From 2c631933d54b4e866daf42678d159c59e93f3210 Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Fri, 11 Oct 2013 07:12:06 +0000 Subject: [PATCH] Load/Store cannot handle double representation. Assert that the representation for Load/Store in the X64 MacroAssembler is never Double. Also add missing test case for the Load/Store macros. TEST=cctest/test-macro-assembler-x64 R=mvstanton@chromium.org Committed: https://code.google.com/p/v8/source/detail?r=17135 Review URL: https://codereview.chromium.org/25990002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17151 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/macro-assembler-x64.cc | 2 + test/cctest/test-macro-assembler-x64.cc | 110 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 27900c1eef..b301f29e31 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -948,6 +948,7 @@ void MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { void MacroAssembler::Load(Register dst, const Operand& src, Representation r) { + ASSERT(!r.IsDouble()); if (r.IsByte()) { movzxbl(dst, src); } else if (r.IsInteger32()) { @@ -959,6 +960,7 @@ void MacroAssembler::Load(Register dst, const Operand& src, Representation r) { void MacroAssembler::Store(const Operand& dst, Register src, Representation r) { + ASSERT(!r.IsDouble()); if (r.IsByte()) { movb(dst, src); } else if (r.IsInteger32()) { diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc index d9b6e3f081..61914b58c3 100644 --- a/test/cctest/test-macro-assembler-x64.cc +++ b/test/cctest/test-macro-assembler-x64.cc @@ -47,6 +47,7 @@ using v8::internal::MacroAssembler; using v8::internal::OS; using v8::internal::Operand; using v8::internal::RelocInfo; +using v8::internal::Representation; using v8::internal::Smi; using v8::internal::SmiIndex; using v8::internal::byte; @@ -2634,5 +2635,114 @@ TEST(OperandOffset) { } +TEST(LoadAndStoreWithRepresentation) { + v8::internal::V8::Initialize(NULL); + + // Allocate an executable page of memory. + size_t actual_size; + byte* buffer = static_cast(OS::Allocate(Assembler::kMinimalBufferSize, + &actual_size, + true)); + CHECK(buffer); + Isolate* isolate = CcTest::i_isolate(); + HandleScope handles(isolate); + MacroAssembler assembler(isolate, buffer, static_cast(actual_size)); + MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. + masm->set_allow_stub_calls(false); + EntryCode(masm); + __ subq(rsp, Immediate(1 * kPointerSize)); + Label exit; + + // Test 1. + __ movq(rax, Immediate(1)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Byte()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(255)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Byte()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 2. + __ movq(rax, Immediate(2)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Smi()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Smi()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 3. + __ movq(rax, Immediate(3)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movq(rcx, Immediate(-1)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer32()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(-1)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer32()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 4. + __ movq(rax, Immediate(4)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ movl(rcx, Immediate(0x44332211)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::HeapObject()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ movl(rdx, Immediate(0x44332211)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::HeapObject()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 5. + __ movq(rax, Immediate(5)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0x12345678, deadbeaf)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Tagged()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0x12345678, deadbeaf)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Tagged()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + // Test 6. + __ movq(rax, Immediate(6)); // Test number. + __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0)); + __ Set(rcx, V8_2PART_UINT64_C(0x11223344, 55667788)); + __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::External()); + __ movq(rcx, Operand(rsp, 0 * kPointerSize)); + __ Set(rdx, V8_2PART_UINT64_C(0x11223344, 55667788)); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::External()); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + + __ xor_(rax, rax); // Success. + __ bind(&exit); + __ addq(rsp, Immediate(1 * kPointerSize)); + ExitCode(masm); + __ ret(0); + + CodeDesc desc; + masm->GetCode(&desc); + // Call the function from C++. + int result = FUNCTION_CAST(buffer)(); + CHECK_EQ(0, result); +} + #undef __