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