Index: test/cctest/test-assembler-arm.cc |
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc |
index 26f3ef98b5c827a27f8fc6aca7bed0458e5befb9..74f78eb30e91be5cf25f4d4bf9006e8b84b7dbc5 100644 |
--- a/test/cctest/test-assembler-arm.cc |
+++ b/test/cctest/test-assembler-arm.cc |
@@ -40,6 +40,7 @@ using namespace v8::internal; |
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
+typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); |
Karl Klose
2011/04/06 06:52:56
Please unify naming in F4 and F3.
Søren Thygesen Gjesse
2011/04/06 08:00:09
Done.
|
static v8::Persistent<v8::Context> env; |
@@ -608,4 +609,114 @@ TEST(7) { |
TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true); |
} |
+TEST(8) { |
+ // Test VFP multi load/store. |
+ InitializeVM(); |
+ v8::HandleScope scope; |
+ |
+ typedef struct { |
+ double a; |
+ double b; |
+ double c; |
+ double d; |
+ double e; |
+ double f; |
+ double g; |
+ double h; |
+ } D; |
+ D d; |
+ |
+ typedef struct { |
+ float a; |
+ float b; |
+ float c; |
+ float d; |
+ float e; |
+ float f; |
+ float g; |
+ float h; |
+ } F; |
+ F f; |
+ |
+ // Create a function that uses vldm/vstm to move some double and |
+ // single presision values around in memory. |
Karl Klose
2011/04/06 06:52:56
presision -> precision
Søren Thygesen Gjesse
2011/04/06 08:00:09
Done.
|
+ Assembler assm(Isolate::Current(), NULL, 0); |
+ |
+ if (CpuFeatures::IsSupported(VFP3)) { |
+ CpuFeatures::Scope scope(VFP3); |
+ |
+ __ mov(ip, Operand(sp)); |
+ __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
+ __ sub(fp, ip, Operand(4)); |
+ |
+ __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
+ __ vldm(ia_w, r4, d0, d3); |
+ __ vldm(ia_w, r4, d4, d7); |
+ |
+ __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
+ __ vstm(ia_w, r4, d6, d7); |
+ __ vstm(ia_w, r4, d0, d5); |
+ |
+ __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
+ __ vldm(ia_w, r4, s0, s3); |
+ __ vldm(ia_w, r4, s4, s7); |
+ |
+ __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
+ __ vstm(ia_w, r4, s6, s7); |
+ __ vstm(ia_w, r4, s0, s5); |
+ |
+ __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Object* code = HEAP->CreateCode( |
+ desc, |
+ Code::ComputeFlags(Code::STUB), |
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); |
+ CHECK(code->IsCode()); |
+#ifdef DEBUG |
+ Code::cast(code)->Print(); |
+#endif |
+ F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry()); |
+ d.a = 1.1; |
+ d.b = 2.2; |
+ d.c = 3.3; |
+ d.d = 4.4; |
+ d.e = 5.5; |
+ d.f = 6.6; |
+ d.g = 7.7; |
+ d.h = 8.8; |
+ |
+ f.a = 1.0; |
+ f.b = 2.0; |
+ f.c = 3.0; |
+ f.d = 4.0; |
+ f.e = 5.0; |
+ f.f = 6.0; |
+ f.g = 7.0; |
+ f.h = 8.0; |
+ |
+ Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); |
+ USE(dummy); |
+ |
+ CHECK_EQ(7.7, d.a); |
+ CHECK_EQ(8.8, d.b); |
+ CHECK_EQ(1.1, d.c); |
+ CHECK_EQ(2.2, d.d); |
+ CHECK_EQ(3.3, d.e); |
+ CHECK_EQ(4.4, d.f); |
+ CHECK_EQ(5.5, d.g); |
+ CHECK_EQ(6.6, d.h); |
+ |
+ CHECK_EQ(7.0, f.a); |
+ CHECK_EQ(8.0, f.b); |
+ CHECK_EQ(1.0, f.c); |
+ CHECK_EQ(2.0, f.d); |
+ CHECK_EQ(3.0, f.e); |
+ CHECK_EQ(4.0, f.f); |
+ CHECK_EQ(5.0, f.g); |
+ CHECK_EQ(6.0, f.h); |
+ } |
+} |
+ |
#undef __ |