Revision: 5281
Author: [email protected]
Date: Tue Aug 17 01:43:45 2010
Log: Add support for vstr for single precision VFP register. This is a commit of http://codereview.chromium.org/3064045 for Rodolph Perfetta
http://code.google.com/p/v8/source/detail?r=5281

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/arm/assembler-arm.h
 /branches/bleeding_edge/src/arm/ic-arm.cc
 /branches/bleeding_edge/test/cctest/test-assembler-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Mon Aug 16 00:52:49 2010 +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Aug 17 01:43:45 2010
@@ -1820,6 +1820,7 @@
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(offset % 4 == 0);
   ASSERT((offset / 4) < 256);
+  ASSERT(offset >= 0);
   emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 |
        0xB*B8 | ((offset / 4) & 255));
 }
@@ -1836,6 +1837,7 @@
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(offset % 4 == 0);
   ASSERT((offset / 4) < 256);
+  ASSERT(offset >= 0);
   emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 |
        0xA*B8 | ((offset / 4) & 255));
 }
@@ -1852,9 +1854,27 @@
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(offset % 4 == 0);
   ASSERT((offset / 4) < 256);
+  ASSERT(offset >= 0);
   emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 |
        0xB*B8 | ((offset / 4) & 255));
 }
+
+
+void Assembler::vstr(const SwVfpRegister src,
+                     const Register base,
+                     int offset,
+                     const Condition cond) {
+  // MEM(Rbase + offset) = SSrc.
+  // Instruction details available in ARM DDI 0406A, A8-786.
+  // cond(31-28) | 1101(27-24)| 1000(23-20) | Rbase(19-16) |
+  // Vdst(15-12) | 1010(11-8) | (offset/4)
+  ASSERT(CpuFeatures::IsEnabled(VFP3));
+  ASSERT(offset % 4 == 0);
+  ASSERT((offset / 4) < 256);
+  ASSERT(offset >= 0);
+  emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 |
+       0xA*B8 | ((offset / 4) & 255));
+}


 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h     Mon Aug 16 00:52:49 2010
+++ /branches/bleeding_edge/src/arm/assembler-arm.h     Tue Aug 17 01:43:45 2010
@@ -966,6 +966,11 @@
             int offset,  // Offset must be a multiple of 4.
             const Condition cond = al);

+  void vstr(const SwVfpRegister src,
+            const Register base,
+            int offset,  // Offset must be a multiple of 4.
+            const Condition cond = al);
+
   void vmov(const DwVfpRegister dst,
             double imm,
             const Condition cond = al);
=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc   Mon Aug 16 09:06:46 2010
+++ /branches/bleeding_edge/src/arm/ic-arm.cc   Tue Aug 17 01:43:45 2010
@@ -1791,19 +1791,22 @@
 }


-// Convert int passed in register ival to IEE 754 single precision
-// floating point value and store it into register fval.
+// Convert and store int passed in register ival to IEEE 754 single precision
+// floating point value at memory location (dst + 4 * wordoffset)
 // If VFP3 is available use it for conversion.
-static void ConvertIntToFloat(MacroAssembler* masm,
-                              Register ival,
-                              Register fval,
-                              Register scratch1,
-                              Register scratch2) {
+static void StoreIntAsFloat(MacroAssembler* masm,
+                            Register dst,
+                            Register wordoffset,
+                            Register ival,
+                            Register fval,
+                            Register scratch1,
+                            Register scratch2) {
   if (CpuFeatures::IsSupported(VFP3)) {
     CpuFeatures::Scope scope(VFP3);
     __ vmov(s0, ival);
+    __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
     __ vcvt_f32_s32(s0, s0);
-    __ vmov(fval, s0);
+    __ vstr(s0, scratch1, 0);
   } else {
     Label not_special, done;
// Move sign bit from source to destination. This works because the sign
@@ -1853,6 +1856,7 @@
            Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits));

     __ bind(&done);
+    __ str(fval, MemOperand(dst, wordoffset, LSL, 2));
   }
 }

@@ -1947,9 +1951,8 @@
       __ str(r5, MemOperand(r3, r4, LSL, 2));
       break;
     case kExternalFloatArray:
-      // Need to perform int-to-float conversion.
-      ConvertIntToFloat(masm, r5, r6, r7, r9);
-      __ str(r6, MemOperand(r3, r4, LSL, 2));
+      // Perform int-to-float conversion and store to memory.
+      StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
       break;
     default:
       UNREACHABLE();
@@ -1983,9 +1986,9 @@
       // include -kHeapObjectTag into it.
       __ sub(r5, r0, Operand(kHeapObjectTag));
       __ vldr(d0, r5, HeapNumber::kValueOffset);
+      __ add(r5, r3, Operand(r4, LSL, 2));
       __ vcvt_f32_f64(s0, d0);
-      __ vmov(r5, s0);
-      __ str(r5, MemOperand(r3, r4, LSL, 2));
+      __ vstr(s0, r5, 0);
     } else {
       // Need to perform float-to-int conversion.
       // Test for NaN or infinity (both give zero).
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-arm.cc Wed Jul 21 00:42:51 2010 +++ /branches/bleeding_edge/test/cctest/test-assembler-arm.cc Tue Aug 17 01:43:45 2010
@@ -226,11 +226,13 @@
     double a;
     double b;
     double c;
+    float d;
+    float e;
   } T;
   T t;

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

@@ -252,6 +254,15 @@
     __ 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));
+
     __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());

     CodeDesc desc;
@@ -267,8 +278,12 @@
     t.a = 1.5;
     t.b = 2.75;
     t.c = 17.17;
+    t.d = 4.5;
+    t.e = 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.25, t.c);
     CHECK_EQ(4.25, t.b);
     CHECK_EQ(1.5, t.a);

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

Reply via email to