Revision: 5352
Author: [email protected]
Date: Thu Aug 26 01:53:00 2010
Log: Fix incorrect encoding of single and double precision registers for some VFP instructions. Also fix incorrect disassembling of vldr/vstr. This is a commit of http://codereview.chromium.org/3107027 for Rodolph Perfetta.
http://code.google.com/p/v8/source/detail?r=5352

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/arm/assembler-arm.h
 /branches/bleeding_edge/src/arm/constants-arm.h
 /branches/bleeding_edge/src/arm/disasm-arm.cc
 /branches/bleeding_edge/src/arm/simulator-arm.cc
 /branches/bleeding_edge/test/cctest/test-assembler-arm.cc
 /branches/bleeding_edge/test/cctest/test-disasm-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Aug 17 01:43:45 2010 +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Thu Aug 26 01:53:00 2010
@@ -1809,6 +1809,7 @@


 // Support for VFP.
+
 void Assembler::vldr(const DwVfpRegister dst,
                      const Register base,
                      int offset,
@@ -1838,7 +1839,9 @@
   ASSERT(offset % 4 == 0);
   ASSERT((offset / 4) < 256);
   ASSERT(offset >= 0);
-  emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 |
+  int sd, d;
+  dst.split_code(&sd, &d);
+  emit(cond | d*B22 | 0xD9*B20 | base.code()*B16 | sd*B12 |
        0xA*B8 | ((offset / 4) & 255));
 }

@@ -1872,7 +1875,9 @@
   ASSERT(offset % 4 == 0);
   ASSERT((offset / 4) < 256);
   ASSERT(offset >= 0);
-  emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 |
+  int sd, d;
+  src.split_code(&sd, &d);
+  emit(cond | d*B22 | 0xD8*B20 | base.code()*B16 | sd*B12 |
        0xA*B8 | ((offset / 4) & 255));
 }

@@ -1979,8 +1984,10 @@
   // Sd = Sm
   // Instruction details available in ARM DDI 0406B, A8-642.
   ASSERT(CpuFeatures::IsEnabled(VFP3));
-  emit(cond | 0xE*B24 | 0xB*B20 |
-       dst.code()*B12 | 0x5*B9 | B6 | src.code());
+  int sd, d, sm, m;
+  dst.split_code(&sd, &d);
+  src.split_code(&sm, &m);
+ emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
 }


@@ -2034,8 +2041,9 @@
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(!src.is(pc));
-  emit(cond | 0xE*B24 | (dst.code() >> 1)*B16 |
-       src.code()*B12 | 0xA*B8 | (0x1 & dst.code())*B7 | B4);
+  int sn, n;
+  dst.split_code(&sn, &n);
+  emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
 }


@@ -2048,8 +2056,9 @@
   // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(!dst.is(pc));
-  emit(cond | 0xE*B24 | B20 | (src.code() >> 1)*B16 |
-       dst.code()*B12 | 0xA*B8 | (0x1 & src.code())*B7 | B4);
+  int sn, n;
+  src.split_code(&sn, &n);
+ emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
 }


@@ -2099,16 +2108,21 @@
 }


-// Depending on split_last_bit split binary representation of reg_code into Vm:M
-// or M:Vm form (where M is single bit).
-static void SplitRegCode(bool split_last_bit,
+// Split five bit reg_code based on size of reg_type.
+//  32-bit register codes are Vm:M
+//  64-bit register codes are M:Vm
+// where Vm is four bits, and M is a single bit.
+static void SplitRegCode(VFPType reg_type,
                          int reg_code,
                          int* vm,
                          int* m) {
-  if (split_last_bit) {
+  ASSERT((reg_code >= 0) && (reg_code <= 31));
+  if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
+    // 32 bit type.
     *m  = reg_code & 0x1;
     *vm = reg_code >> 1;
   } else {
+    // 64 bit type.
     *m  = (reg_code & 0x10) >> 4;
     *vm = reg_code & 0x0F;
   }
@@ -2121,6 +2135,11 @@
                         const VFPType src_type,
                         const int src_code,
                         const Condition cond) {
+  ASSERT(src_type != dst_type);
+  int D, Vd, M, Vm;
+  SplitRegCode(src_type, src_code, &Vm, &M);
+  SplitRegCode(dst_type, dst_code, &Vd, &D);
+
   if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
     // Conversion between IEEE floating point and 32-bit integer.
     // Instruction details available in ARM DDI 0406B, A8.6.295.
@@ -2128,22 +2147,17 @@
     // Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
     ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));

-    int sz, opc2, D, Vd, M, Vm, op;
+    int sz, opc2, op;

     if (IsIntegerVFPType(dst_type)) {
       opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
       sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
       op = 1;  // round towards zero
-      SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M);
-      SplitRegCode(true, dst_code, &Vd, &D);
     } else {
       ASSERT(IsIntegerVFPType(src_type));
-
       opc2 = 0x0;
       sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
       op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
-      SplitRegCode(true, src_code, &Vm, &M);
-      SplitRegCode(!IsDoubleVFPType(dst_type), dst_code, &Vd, &D);
     }

     return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 |
@@ -2153,13 +2167,7 @@
     // Instruction details available in ARM DDI 0406B, A8.6.298.
     // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) |
     // Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
-    int sz, D, Vd, M, Vm;
-
-    ASSERT(IsDoubleVFPType(dst_type) != IsDoubleVFPType(src_type));
-    sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
-    SplitRegCode(IsDoubleVFPType(src_type), dst_code, &Vd, &D);
-    SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M);
-
+    int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
     return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
             Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
   }
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h     Tue Aug 17 01:43:45 2010
+++ /branches/bleeding_edge/src/arm/assembler-arm.h     Thu Aug 26 01:53:00 2010
@@ -120,6 +120,11 @@
     ASSERT(is_valid());
     return 1 << code_;
   }
+  void split_code(int* vm, int* m) const  {
+    ASSERT(is_valid());
+    *m = code_ & 0x1;
+    *vm = code_ >> 1;
+  }

   int code_;
 };
@@ -152,6 +157,11 @@
     ASSERT(is_valid());
     return 1 << code_;
   }
+  void split_code(int* vm, int* m) const  {
+    ASSERT(is_valid());
+    *m = (code_ & 0x10) >> 4;
+    *vm = code_ & 0x0F;
+  }

   int code_;
 };
=======================================
--- /branches/bleeding_edge/src/arm/constants-arm.h     Thu Jul  8 05:38:02 2010
+++ /branches/bleeding_edge/src/arm/constants-arm.h     Thu Aug 26 01:53:00 2010
@@ -194,6 +194,13 @@
 };


+// Type of VFP register. Determines register encoding.
+enum VFPRegPrecision {
+  kSinglePrecision = 0,
+  kDoublePrecision = 1
+};
+
+
 typedef int32_t instr_t;


@@ -269,6 +276,15 @@
   inline int VCField() const { return Bit(8); }
   inline int VAField() const { return Bits(23, 21); }
   inline int VBField() const { return Bits(6, 5); }
+  inline int VFPNRegCode(VFPRegPrecision pre) {
+    return VFPGlueRegCode(pre, 16, 7);
+  }
+  inline int VFPMRegCode(VFPRegPrecision pre) {
+    return VFPGlueRegCode(pre, 0, 5);
+  }
+  inline int VFPDRegCode(VFPRegPrecision pre) {
+    return VFPGlueRegCode(pre, 12, 22);
+  }

   // Fields used in Data processing instructions
   inline Opcode OpcodeField() const {
@@ -343,6 +359,17 @@
   static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); }

  private:
+  // Join split register codes, depending on single or double precision.
+  // four_bit is the position of the least-significant bit of the four
+  // bit specifier. one_bit is the position of the additional single bit
+  // specifier.
+ inline int VFPGlueRegCode(VFPRegPrecision pre, int four_bit, int one_bit) {
+    if (pre == kSinglePrecision) {
+      return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit);
+    }
+    return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit);
+  }
+
   // We need to prevent the creation of instances of class Instr.
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
 };
=======================================
--- /branches/bleeding_edge/src/arm/disasm-arm.cc       Mon Aug 16 00:52:49 2010
+++ /branches/bleeding_edge/src/arm/disasm-arm.cc       Thu Aug 26 01:53:00 2010
@@ -463,7 +463,7 @@
       ASSERT((width + lsb) <= 32);

       out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                           "#%d",
+                                           "%d",
instr->Bits(width + lsb - 1, lsb));
       return 8;
     }
@@ -931,7 +931,7 @@
       if (instr->HasW()) {
         ASSERT(instr->Bits(5, 4) == 0x1);
         if (instr->Bit(22) == 0x1) {
-          Format(instr, "usat 'rd, 'im...@16, 'rm'shift_sat");
+          Format(instr, "usat 'rd, #'im...@16, 'rm'shift_sat");
         } else {
           UNREACHABLE();  // SSAT.
         }
@@ -1269,17 +1269,19 @@
   if (instr->CoprocessorField() == 0xA) {
     switch (instr->OpcodeField()) {
       case 0x8:
+      case 0xA:
         if (instr->HasL()) {
-          Format(instr, "vldr'cond 'Sd, ['rn - 4*'off8]");
+          Format(instr, "vldr'cond 'Sd, ['rn - 4*'im...@00]");
         } else {
-          Format(instr, "vstr'cond 'Sd, ['rn - 4*'off8]");
+          Format(instr, "vstr'cond 'Sd, ['rn - 4*'im...@00]");
         }
         break;
       case 0xC:
+      case 0xE:
         if (instr->HasL()) {
-          Format(instr, "vldr'cond 'Sd, ['rn + 4*'off8]");
+          Format(instr, "vldr'cond 'Sd, ['rn + 4*'im...@00]");
         } else {
-          Format(instr, "vstr'cond 'Sd, ['rn + 4*'off8]");
+          Format(instr, "vstr'cond 'Sd, ['rn + 4*'im...@00]");
         }
         break;
       default:
@@ -1300,16 +1302,16 @@
         break;
       case 0x8:
         if (instr->HasL()) {
-          Format(instr, "vldr'cond 'Dd, ['rn - 4*'off8]");
+          Format(instr, "vldr'cond 'Dd, ['rn - 4*'im...@00]");
         } else {
-          Format(instr, "vstr'cond 'Dd, ['rn - 4*'off8]");
+          Format(instr, "vstr'cond 'Dd, ['rn - 4*'im...@00]");
         }
         break;
       case 0xC:
         if (instr->HasL()) {
-          Format(instr, "vldr'cond 'Dd, ['rn + 4*'off8]");
+          Format(instr, "vldr'cond 'Dd, ['rn + 4*'im...@00]");
         } else {
-          Format(instr, "vstr'cond 'Dd, ['rn + 4*'off8]");
+          Format(instr, "vstr'cond 'Dd, ['rn + 4*'im...@00]");
         }
         break;
       default:
=======================================
--- /branches/bleeding_edge/src/arm/simulator-arm.cc Fri Aug 20 02:37:22 2010 +++ /branches/bleeding_edge/src/arm/simulator-arm.cc Thu Aug 26 01:53:00 2010
@@ -2279,13 +2279,6 @@
     dbg.Stop(instr);
   }
 }
-
-
-// Depending on value of last_bit flag glue register code from vm and m values
-// (where m is expected to be a single bit).
-static int GlueRegCode(bool last_bit, int vm, int m) {
-  return last_bit ? ((vm << 1) | m) : ((m << 4) | vm);
-}


 // void Simulator::DecodeTypeVFP(Instr* instr)
@@ -2305,9 +2298,10 @@
   ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
   ASSERT(instr->Bits(11, 9) == 0x5);

-  int vm = instr->VmField();
-  int vd = instr->VdField();
-  int vn = instr->VnField();
+  // Obtain double precision register codes.
+  int vm = instr->VFPMRegCode(kDoublePrecision);
+  int vd = instr->VFPDRegCode(kDoublePrecision);
+  int vn = instr->VFPNRegCode(kDoublePrecision);

   if (instr->Bit(4) == 0) {
     if (instr->Opc1Field() == 0x7) {
@@ -2315,9 +2309,13 @@
       if ((instr->Opc2Field() == 0x0) && (instr->Opc3Field() == 0x1)) {
         // vmov register to register.
         if (instr->SzField() == 0x1) {
-          set_d_register_from_double(vd, get_double_from_d_register(vm));
+          int m = instr->VFPMRegCode(kDoublePrecision);
+          int d = instr->VFPDRegCode(kDoublePrecision);
+          set_d_register_from_double(d, get_double_from_d_register(m));
         } else {
-          set_s_register_from_float(vd, get_float_from_s_register(vm));
+          int m = instr->VFPMRegCode(kSinglePrecision);
+          int d = instr->VFPDRegCode(kSinglePrecision);
+          set_s_register_from_float(d, get_float_from_s_register(m));
         }
} else if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
         DecodeVCVTBetweenDoubleAndSingle(instr);
@@ -2410,7 +2408,7 @@
          (instr->VAField() == 0x0));

   int t = instr->RtField();
-  int n  = GlueRegCode(true, instr->VnField(), instr->NField());
+  int n = instr->VFPNRegCode(kSinglePrecision);
   bool to_arm_register = (instr->VLField() == 0x1);

   if (to_arm_register) {
@@ -2427,22 +2425,25 @@
   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
   ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
          (instr->Opc3Field() & 0x1));
-
   // Comparison.
-  bool dp_operation = (instr->SzField() == 1);
+
+  VFPRegPrecision precision = kSinglePrecision;
+  if (instr->SzField() == 1) {
+    precision = kDoublePrecision;
+  }

   if (instr->Bit(7) != 0) {
     // Raising exceptions for quiet NaNs are not supported.
     UNIMPLEMENTED();  // Not used by V8.
   }

-  int d = GlueRegCode(!dp_operation, instr->VdField(), instr->DField());
+  int d = instr->VFPDRegCode(precision);
   int m = 0;
   if (instr->Opc2Field() == 0x4) {
-    m = GlueRegCode(!dp_operation, instr->VmField(), instr->MField());
+    m = instr->VFPMRegCode(precision);
   }

-  if (dp_operation) {
+  if (precision == kDoublePrecision) {
     double dd_value = get_double_from_d_register(d);
     double dm_value = 0.0;
     if (instr->Opc2Field() == 0x4) {
@@ -2460,11 +2461,17 @@
   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
   ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));

-  bool double_to_single = (instr->SzField() == 1);
- int dst = GlueRegCode(double_to_single, instr->VdField(), instr->DField()); - int src = GlueRegCode(!double_to_single, instr->VmField(), instr->MField());
-
-  if (double_to_single) {
+  VFPRegPrecision dst_precision = kDoublePrecision;
+  VFPRegPrecision src_precision = kSinglePrecision;
+  if (instr->SzField() == 1) {
+    dst_precision = kSinglePrecision;
+    src_precision = kDoublePrecision;
+  }
+
+  int dst = instr->VFPDRegCode(dst_precision);
+  int src = instr->VFPMRegCode(src_precision);
+
+  if (dst_precision == kSinglePrecision) {
     double val = get_double_from_d_register(src);
     set_s_register_from_float(dst, static_cast<float>(val));
   } else {
@@ -2480,13 +2487,13 @@
(((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));

   // Conversion between floating-point and integer.
-  int vd = instr->VdField();
-  int d = instr->DField();
-  int vm = instr->VmField();
-  int m = instr->MField();
-
   bool to_integer = (instr->Bit(18) == 1);
-  bool dp_operation = (instr->SzField() == 1);
+
+  VFPRegPrecision src_precision = kSinglePrecision;
+  if (instr->SzField() == 1) {
+    src_precision = kDoublePrecision;
+  }
+
   if (to_integer) {
     bool unsigned_integer = (instr->Bit(16) == 0);
     if (instr->Bit(7) != 1) {
@@ -2494,10 +2501,10 @@
       UNIMPLEMENTED();  // Not used by V8.
     }

-    int dst = GlueRegCode(true, vd, d);
-    int src = GlueRegCode(!dp_operation, vm, m);
-
-    if (dp_operation) {
+    int dst = instr->VFPDRegCode(kSinglePrecision);
+    int src = instr->VFPMRegCode(src_precision);
+
+    if (src_precision == kDoublePrecision) {
       double val = get_double_from_d_register(src);

       int sint = unsigned_integer ? static_cast<uint32_t>(val) :
@@ -2515,12 +2522,12 @@
   } else {
     bool unsigned_integer = (instr->Bit(7) == 0);

-    int dst = GlueRegCode(!dp_operation, vd, d);
-    int src = GlueRegCode(true, vm, m);
+    int dst = instr->VFPDRegCode(src_precision);
+    int src = instr->VFPMRegCode(kSinglePrecision);

     int val = get_sinteger_from_s_register(src);

-    if (dp_operation) {
+    if (src_precision == kDoublePrecision) {
       if (unsigned_integer) {
         set_d_register_from_double(dst,
                                    static_cast<double>((uint32_t)val));
@@ -2551,9 +2558,11 @@
   if (instr->CoprocessorField() == 0xA) {
     switch (instr->OpcodeField()) {
       case 0x8:
-      case 0xC: {  // Load and store float to memory.
+      case 0xA:
+      case 0xC:
+      case 0xE: {  // Load and store single precision float to memory.
         int rn = instr->RnField();
-        int vd = instr->VdField();
+        int vd = instr->VFPDRegCode(kSinglePrecision);
         int offset = instr->Immed8Field();
         if (!instr->HasU()) {
           offset = -offset;
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-arm.cc Tue Aug 17 01:43:45 2010 +++ /branches/bleeding_edge/test/cctest/test-assembler-arm.cc Thu Aug 26 01:53:00 2010
@@ -226,13 +226,17 @@
     double a;
     double b;
     double c;
-    float d;
-    float e;
+    double d;
+    double e;
+    double f;
+    int i;
+    float x;
+    float y;
   } T;
   T t;

   // Create a function that accepts &t, and loads, manipulates, and stores
-  // the doubles t.a, t.b, and t.c, and floats t.d, t.e.
+  // the doubles and floats.
   Assembler assm(NULL, 0);
   Label L, C;

@@ -254,15 +258,34 @@
     __ vmov(d4, r2, r3);
     __ vstr(d4, r4, OFFSET_OF(T, b));

-    // Load t.d and t.e, switch values, and store back to the struct.
-    __ vldr(s0, r4, OFFSET_OF(T, d));
-    __ vldr(s1, r4, OFFSET_OF(T, e));
-    __ vmov(s2, s0);
-    __ vmov(s0, s1);
-    __ vmov(s1, s2);
-    __ vstr(s0, r4, OFFSET_OF(T, d));
-    __ vstr(s1, r4, OFFSET_OF(T, e));
-
+    // Load t.x and t.y, switch values, and store back to the struct.
+    __ vldr(s0, r4, OFFSET_OF(T, x));
+    __ vldr(s31, r4, OFFSET_OF(T, y));
+    __ vmov(s16, s0);
+    __ vmov(s0, s31);
+    __ vmov(s31, s16);
+    __ vstr(s0, r4, OFFSET_OF(T, x));
+    __ vstr(s31, r4, OFFSET_OF(T, y));
+
+ // Move a literal into a register that can be encoded in the instruction.
+    __ vmov(d4, 1.0);
+    __ vstr(d4, r4, OFFSET_OF(T, e));
+
+    // Move a literal into a register that requires 64 bits to encode.
+    // 0x3ff0000010000000 = 1.000000059604644775390625
+    __ vmov(d4, 1.000000059604644775390625);
+    __ vstr(d4, r4, OFFSET_OF(T, d));
+
+    // Convert from floating point to integer.
+    __ vmov(d4, 2.0);
+    __ vcvt_s32_f64(s31, d4);
+    __ vstr(s31, r4, OFFSET_OF(T, i));
+
+    // Convert from integer to floating point.
+    __ mov(lr, Operand(42));
+    __ vmov(s31, lr);
+    __ vcvt_f64_s32(d4, s31);
+    __ vstr(d4, r4, OFFSET_OF(T, f));
     __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());

     CodeDesc desc;
@@ -278,12 +301,20 @@
     t.a = 1.5;
     t.b = 2.75;
     t.c = 17.17;
-    t.d = 4.5;
-    t.e = 9.0;
+    t.d = 0.0;
+    t.e = 0.0;
+    t.f = 0.0;
+    t.i = 0;
+    t.x = 4.5;
+    t.y = 9.0;
     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
     USE(dummy);
-    CHECK_EQ(4.5, t.e);
-    CHECK_EQ(9.0, t.d);
+    CHECK_EQ(4.5, t.y);
+    CHECK_EQ(9.0, t.x);
+    CHECK_EQ(2, t.i);
+    CHECK_EQ(42.0, t.f);
+    CHECK_EQ(1.0, t.e);
+    CHECK_EQ(1.000000059604644775390625, t.d);
     CHECK_EQ(4.25, t.c);
     CHECK_EQ(4.25, t.b);
     CHECK_EQ(1.5, t.a);
=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-arm.cc Wed Jul 21 00:42:51 2010 +++ /branches/bleeding_edge/test/cctest/test-disasm-arm.cc Thu Aug 26 01:53:00 2010
@@ -422,6 +422,19 @@
     COMPARE(vmov(d3, d3, eq),
             "0eb03b43       vmov.f64eq d3, d3");

+    COMPARE(vmov(s0, s31),
+            "eeb00a6f       vmov.f32 s0, s31");
+    COMPARE(vmov(s31, s0),
+            "eef0fa40       vmov.f32 s31, s0");
+    COMPARE(vmov(r0, s0),
+            "ee100a10       vmov r0, s0");
+    COMPARE(vmov(r10, s31),
+            "ee1faa90       vmov r10, s31");
+    COMPARE(vmov(s0, r0),
+            "ee000a10       vmov s0, r0");
+    COMPARE(vmov(s31, r10),
+            "ee0faa90       vmov s31, r10");
+
     COMPARE(vadd(d0, d1, d2),
             "ee310b02       vadd.f64 d0, d1, d2");
     COMPARE(vadd(d3, d4, d5, mi),
@@ -451,6 +464,41 @@
             "eeb70b00       vmov.f64 d0, #1");
     COMPARE(vmov(d2, -13.0),
             "eeba2b0a       vmov.f64 d2, #-13");
+
+    COMPARE(vldr(s0, r0, 0),
+            "ed900a00       vldr s0, [r0 + 4*0]");
+    COMPARE(vldr(s1, r1, 4),
+            "edd10a01       vldr s1, [r1 + 4*1]");
+    COMPARE(vldr(s15, r4, 16),
+            "edd47a04       vldr s15, [r4 + 4*4]");
+    COMPARE(vldr(s16, r5, 20),
+            "ed958a05       vldr s16, [r5 + 4*5]");
+    COMPARE(vldr(s31, r10, 1020),
+            "eddafaff       vldr s31, [r10 + 4*255]");
+
+    COMPARE(vstr(s0, r0, 0),
+            "ed800a00       vstr s0, [r0 + 4*0]");
+    COMPARE(vstr(s1, r1, 4),
+            "edc10a01       vstr s1, [r1 + 4*1]");
+    COMPARE(vstr(s15, r8, 8),
+            "edc87a02       vstr s15, [r8 + 4*2]");
+    COMPARE(vstr(s16, r9, 12),
+            "ed898a03       vstr s16, [r9 + 4*3]");
+    COMPARE(vstr(s31, r10, 1020),
+            "edcafaff       vstr s31, [r10 + 4*255]");
+
+    COMPARE(vldr(d0, r0, 0),
+            "ed900b00       vldr d0, [r0 + 4*0]");
+    COMPARE(vldr(d1, r1, 4),
+            "ed911b01       vldr d1, [r1 + 4*1]");
+    COMPARE(vldr(d15, r10, 1020),
+            "ed9afbff       vldr d15, [r10 + 4*255]");
+    COMPARE(vstr(d0, r0, 0),
+            "ed800b00       vstr d0, [r0 + 4*0]");
+    COMPARE(vstr(d1, r1, 4),
+            "ed811b01       vstr d1, [r1 + 4*1]");
+    COMPARE(vstr(d15, r10, 1020),
+            "ed8afbff       vstr d15, [r10 + 4*255]");
   }

   VERIFY_RUN();

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to