Index: test/cctest/test-code-stubs-arm.cc |
diff --git a/test/cctest/test-code-stubs-x64.cc b/test/cctest/test-code-stubs-arm.cc |
similarity index 58% |
copy from test/cctest/test-code-stubs-x64.cc |
copy to test/cctest/test-code-stubs-arm.cc |
index 4af5b45d7c62135119a37b7825003f538647fd4a..cc51e839c5dd6600fa9692d6e2022dd1b62fae4a 100644 |
--- a/test/cctest/test-code-stubs-x64.cc |
+++ b/test/cctest/test-code-stubs-arm.cc |
@@ -35,83 +35,97 @@ |
#include "factory.h" |
#include "macro-assembler.h" |
#include "platform.h" |
+#include "simulator.h" |
using namespace v8::internal; |
- |
-#define __ assm. |
+#define __ masm. |
ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, |
Register source_reg, |
- Register destination_reg) { |
+ Register destination_reg, |
+ bool inline_fastpath) { |
// Allocate an executable page of memory. |
size_t actual_size; |
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, |
- &actual_size, |
- true)); |
+ &actual_size, |
+ true)); |
CHECK(buffer); |
HandleScope handles(isolate); |
- MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); |
- assm.set_allow_stub_calls(false); |
- int offset = |
- source_reg.is(rsp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); |
- DoubleToIStub stub(source_reg, destination_reg, offset, true); |
- byte* start = stub.GetCode(isolate)->instruction_start(); |
+ MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); |
+ masm.set_allow_stub_calls(false); |
+ DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath); |
- __ push(rbx); |
- __ push(rcx); |
- __ push(rdx); |
- __ push(rsi); |
- __ push(rdi); |
- |
- if (!source_reg.is(rsp)) { |
- __ lea(source_reg, MemOperand(rsp, -8 * kPointerSize - offset)); |
+ byte* start = stub.GetCode(isolate)->instruction_start(); |
+ Label done; |
+ |
+ // Save callee save registers. |
+ __ Push(r7, r6, r5, r4); |
+ __ Push(lr); |
+ |
+ // Push the double argument. |
+ __ vmov(d0, r0, r1); |
+ __ sub(sp, sp, Operand(kDoubleSize)); |
+ __ vstr(d0, sp, 0); |
+ if (!source_reg.is(sp)) { |
+ __ mov(source_reg, sp); |
} |
- int param_offset = 7 * kPointerSize; |
// Save registers make sure they don't get clobbered. |
+ int source_reg_offset = kDoubleSize; |
int reg_num = 0; |
for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { |
Register reg = Register::from_code(reg_num); |
- if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { |
+ if (!reg.is(destination_reg)) { |
__ push(reg); |
- param_offset += kPointerSize; |
+ source_reg_offset += kPointerSize; |
} |
} |
- // Re-push the double argument |
- __ subq(rsp, Immediate(kDoubleSize)); |
- __ movsd(MemOperand(rsp, 0), xmm0); |
+ // Re-push the double argument. |
+ __ sub(sp, sp, Operand(kDoubleSize)); |
+ __ vstr(d0, sp, 0); |
// Call through to the actual stub |
+ if (inline_fastpath) { |
+ __ vldr(d0, MemOperand(source_reg)); |
+ __ TryInlineTruncateDoubleToI(destination_reg, d0, &done); |
+ if (destination_reg.is(source_reg) && !source_reg.is(sp)) { |
+ // Restore clobbered source_reg. |
+ __ add(source_reg, sp, Operand(source_reg_offset)); |
+ } |
+ } |
__ Call(start, RelocInfo::EXTERNAL_REFERENCE); |
+ __ bind(&done); |
- __ addq(rsp, Immediate(kDoubleSize)); |
+ __ add(sp, sp, Operand(kDoubleSize)); |
// Make sure no registers have been unexpectedly clobbered |
for (--reg_num; reg_num >= 0; --reg_num) { |
Register reg = Register::from_code(reg_num); |
- if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { |
- __ cmpq(reg, MemOperand(rsp, 0)); |
- __ Assert(equal, kRegisterWasClobbered); |
- __ addq(rsp, Immediate(kPointerSize)); |
+ if (!reg.is(destination_reg)) { |
+ __ ldr(ip, MemOperand(sp, 0)); |
+ __ cmp(reg, ip); |
+ __ Assert(eq, kRegisterWasClobbered); |
+ __ add(sp, sp, Operand(kPointerSize)); |
} |
} |
- __ movq(rax, destination_reg); |
+ __ add(sp, sp, Operand(kDoubleSize)); |
+ |
+ if (!destination_reg.is(r0)) |
+ __ mov(r0, destination_reg); |
- __ pop(rdi); |
- __ pop(rsi); |
- __ pop(rdx); |
- __ pop(rcx); |
- __ pop(rbx); |
+ // Restore callee save registers. |
+ __ Pop(lr); |
+ __ Pop(r7, r6, r5, r4); |
- __ ret(0); |
+ __ Ret(0); |
CodeDesc desc; |
- assm.GetCode(&desc); |
- return reinterpret_cast<ConvertDToIFunc>( |
- reinterpret_cast<intptr_t>(buffer)); |
+ masm.GetCode(&desc); |
+ return (reinterpret_cast<ConvertDToIFunc>( |
+ reinterpret_cast<intptr_t>(buffer))); |
} |
#undef __ |
@@ -122,6 +136,16 @@ static Isolate* GetIsolateFrom(LocalContext* context) { |
} |
+int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, |
+ double from) { |
+#ifdef USE_SIMULATOR |
+ return reinterpret_cast<int32_t>(CALL_GENERATED_CODE(func, from, 0, 0, 0, 0)); |
+#else |
+ return (*func)(from); |
+#endif |
+} |
+ |
+ |
TEST(ConvertDToI) { |
CcTest::InitializeVM(); |
LocalContext context; |
@@ -135,15 +159,23 @@ TEST(ConvertDToI) { |
RunAllTruncationTests(&ConvertDToICVersion); |
#endif |
- Register source_registers[] = {rsp, rax, rbx, rcx, rdx, rsi, rdi, r8, r9}; |
- Register dest_registers[] = {rax, rbx, rcx, rdx, rsi, rdi, r8, r9}; |
+ Register source_registers[] = {sp, r0, r1, r2, r3, r4, r5, r6, r7}; |
+ Register dest_registers[] = {r0, r1, r2, r3, r4, r5, r6, r7}; |
for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) { |
for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) { |
RunAllTruncationTests( |
+ RunGeneratedCodeCallWrapper, |
+ MakeConvertDToIFuncTrampoline(isolate, |
+ source_registers[s], |
+ dest_registers[d], |
+ false)); |
+ RunAllTruncationTests( |
+ RunGeneratedCodeCallWrapper, |
MakeConvertDToIFuncTrampoline(isolate, |
source_registers[s], |
- dest_registers[d])); |
+ dest_registers[d], |
+ true)); |
} |
} |
} |