13ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Copyright 2009 the V8 project authors. All rights reserved. 23ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Redistribution and use in source and binary forms, with or without 33ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// modification, are permitted provided that the following conditions are 43ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// met: 53ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// 63ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// * Redistributions of source code must retain the above copyright 73ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// notice, this list of conditions and the following disclaimer. 83ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// * Redistributions in binary form must reproduce the above 93ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// copyright notice, this list of conditions and the following 103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// disclaimer in the documentation and/or other materials provided 113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// with the distribution. 123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// * Neither the name of Google Inc. nor the names of its 133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// contributors may be used to endorse or promote products derived 143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// from this software without specific prior written permission. 153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// 163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include <stdlib.h> 293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "v8.h" 313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "macro-assembler.h" 333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "factory.h" 343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "platform.h" 353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "serialize.h" 363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#include "cctest.h" 373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::Assembler; 398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::CodeDesc; 403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::Condition; 418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::FUNCTION_CAST; 423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::HandleScope; 433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::Immediate; 448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::Isolate; 453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::Label; 468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::MacroAssembler; 478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::OS; 488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::Operand; 493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::RelocInfo; 508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::Smi; 518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::SmiIndex; 528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::byte; 538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::carry; 548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::greater; 558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::greater_equal; 568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::kIntSize; 578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::kPointerSize; 588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::kSmiTagMask; 598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::kSmiValueSize; 608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::less_equal; 618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::negative; 628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::not_carry; 638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::not_equal; 648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::not_zero; 658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::positive; 668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r11; 678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r13; 688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r14; 698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r15; 708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r8; 718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::r9; 723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::rax; 738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::rbp; 743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::rbx; 753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::rcx; 768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::rdi; 773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::rdx; 788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochusing v8::internal::rsi; 793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockusing v8::internal::rsp; 80f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeusing v8::internal::times_pointer_size; 813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Test the x64 assembler by compiling some simple functions into 833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// a buffer and executing them. These tests do not initialize the 843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// V8 library, create a context, or use any V8 objects. 853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The AMD64 calling convention is used, with the first five arguments 863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in 873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// the XMM registers. The return value is in RAX. 883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// This calling convention is used on Linux, with GCC, and on Mac OS, 893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// with GCC. A different convention is used on 64-bit windows. 903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blocktypedef int (*F0)(); 923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#define __ masm-> 943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 958defd9ff6930b4e24729971a61cf7469daf119beSteve Block 968defd9ff6930b4e24729971a61cf7469daf119beSteve Blockstatic void EntryCode(MacroAssembler* masm) { 978defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Smi constant register is callee save. 988defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ push(v8::internal::kSmiConstantRegister); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ push(v8::internal::kRootRegister); 1008defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ InitializeSmiConstantRegister(); 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ InitializeRootRegister(); 1028defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 1038defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1048defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1058defd9ff6930b4e24729971a61cf7469daf119beSteve Blockstatic void ExitCode(MacroAssembler* masm) { 1068defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Return -1 if kSmiConstantRegister was clobbered during the test. 1078defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ Move(rdx, Smi::FromInt(1)); 1088defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ cmpq(rdx, v8::internal::kSmiConstantRegister); 1098defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ movq(rdx, Immediate(-1)); 1108defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ cmovq(not_equal, rax, rdx); 11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ pop(v8::internal::kRootRegister); 1128defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ pop(v8::internal::kSmiConstantRegister); 1138defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 1148defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1158defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(Smi) { 1173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Check that C++ Smi operations work as expected. 118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int64_t test_numbers[] = { 1193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 0, 1, -1, 127, 128, -128, -129, 255, 256, -256, -257, 120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Smi::kMaxValue, static_cast<int64_t>(Smi::kMaxValue) + 1, 121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Smi::kMinValue, static_cast<int64_t>(Smi::kMinValue) - 1 1223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block }; 1233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int test_number_count = 15; 1243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < test_number_count; i++) { 125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int64_t number = test_numbers[i]; 1263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool is_valid = Smi::IsValid(number); 1273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool is_in_range = number >= Smi::kMinValue && number <= Smi::kMaxValue; 1283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(is_in_range, is_valid); 1293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (is_valid) { 1303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Smi* smi_from_intptr = Smi::FromIntptr(number); 1313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (static_cast<int>(number) == number) { // Is a 32-bit int. 1323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Smi* smi_from_int = Smi::FromInt(static_cast<int32_t>(number)); 1333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(smi_from_int, smi_from_intptr); 1343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int64_t smi_value = smi_from_intptr->value(); 136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(number, smi_value); 1373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) { 1433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 1443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(0)); 1453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0))); 1463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ cmpq(rcx, rdx); 1473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 1483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Test that we can move a Smi value literally into a register. 1523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiMove) { 15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 1553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 1563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 1573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 1583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 1593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 1603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 1618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 1628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 1638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 1643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. 1653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 1668defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 1673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 1683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 1, Smi::FromInt(0)); 1703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 2, Smi::FromInt(127)); 1713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 3, Smi::FromInt(128)); 1723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 4, Smi::FromInt(255)); 1733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 5, Smi::FromInt(256)); 1743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 6, Smi::FromInt(Smi::kMaxValue)); 1753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 7, Smi::FromInt(-1)); 1763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 8, Smi::FromInt(-128)); 1773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 9, Smi::FromInt(-129)); 1783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 10, Smi::FromInt(-256)); 1793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 11, Smi::FromInt(-257)); 1803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestMoveSmi(masm, &exit, 12, Smi::FromInt(Smi::kMinValue)); 1813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 1833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 1848defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 1853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 1863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 1883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 1893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 1903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 1913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 1923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) { 1963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 1973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r8, rcx); 1983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 1993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r9, rdx); 2003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiCompare(rcx, rdx); 2013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (x < y) { 2023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 1)); 2033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(greater_equal, exit); 2043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (x > y) { 2053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 2)); 2063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(less_equal, exit); 2073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT_EQ(x, y); 2093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 3)); 2103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 2113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 4)); 2133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ cmpq(rcx, r8); 2143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 2153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 2163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ cmpq(rdx, r9); 2173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 2183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (x != y) { 2203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiCompare(rdx, rcx); 2213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (y < x) { 2223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 9)); 2233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(greater_equal, exit); 2243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(y > x); 2263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 10)); 2273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(less_equal, exit); 2283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rcx); 2313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 11)); 2323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 2333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 2343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ cmpq(rcx, r8); 2353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 2363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 2383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Test that we can compare smis for equality (and more). 2413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiCompare) { 24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 2433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 2443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 2453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 2473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 2483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 2493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 2503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 2518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 2528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 2538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 2543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 2563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 2578defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 2583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 2593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x10, 0, 0); 2613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x20, 0, 1); 2623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x30, 1, 0); 2633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x40, 1, 1); 2643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x50, 0, -1); 2653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x60, -1, 0); 2663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x70, -1, -1); 2673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x80, 0, Smi::kMinValue); 2683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x90, Smi::kMinValue, 0); 2693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xA0, 0, Smi::kMaxValue); 2703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xB0, Smi::kMaxValue, 0); 2713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xC0, -1, Smi::kMinValue); 2723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xD0, Smi::kMinValue, -1); 2733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xE0, -1, Smi::kMaxValue); 2743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0xF0, Smi::kMaxValue, -1); 2753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x100, Smi::kMinValue, Smi::kMinValue); 2763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x110, Smi::kMinValue, Smi::kMaxValue); 2773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x120, Smi::kMaxValue, Smi::kMinValue); 2783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiCompare(masm, &exit, 0x130, Smi::kMaxValue, Smi::kMaxValue); 2793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 2813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 2828defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 2833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 2843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 2863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 2873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 2883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 2893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 2903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 2913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(Integer32ToSmi) { 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 2963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 2973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 2983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 2993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 3003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 3013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 3023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 3038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 3048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 3058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 3063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 3083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 3098defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 3103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 3113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(1)); // Test number. 3133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(0)); 3143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 3153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0))); 31644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rdx); 3173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(2)); // Test number. 3203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(1024)); 3213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 3223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024))); 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rdx); 3243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(3)); // Test number. 3273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(-1)); 3283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 3293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1))); 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rdx); 3313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(4)); // Test number. 3343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMaxValue)); 3353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 3363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue))); 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rdx); 3383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(5)); // Test number. 3413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMinValue)); 3423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 3433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue))); 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, rdx); 3453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Different target register. 3483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(6)); // Test number. 3503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(0)); 3513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, rcx); 3523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(0))); 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rdx); 3543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(7)); // Test number. 3573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(1024)); 3583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, rcx); 3593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024))); 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rdx); 3613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(8)); // Test number. 3643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(-1)); 3653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, rcx); 3663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1))); 36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rdx); 3683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(9)); // Test number. 3713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMaxValue)); 3723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, rcx); 3733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue))); 37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rdx); 3753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rax, Immediate(10)); // Test number. 3783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMinValue)); 3793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, rcx); 3803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue))); 38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rdx); 3823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, &exit); 3833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 3863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 3878defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 3883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 3893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 3913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 3923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 3933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 3943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 3953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestI64PlusConstantToSmi(MacroAssembler* masm, 3993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 4003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 4013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int64_t x, 4023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int y) { 4033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int64_t result = x + y; 4043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(Smi::IsValid(result)); 4053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 406d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block __ Move(r8, Smi::FromInt(static_cast<int>(result))); 4073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, x, RelocInfo::NONE); 4083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 4093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer64PlusConstantToSmi(rdx, rcx, y); 41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rdx, r8); 4113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 4123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 4153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 4163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 4183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer64PlusConstantToSmi(rcx, rcx, y); 41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 4203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 4213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 4223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(Integer64PlusConstantToSmi) { 42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 4263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 4273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 4283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 4293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 4303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 4313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 4323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 4338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 4348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 4358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 4363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 4383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 4398defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 4403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 4413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int64_t twice_max = static_cast<int64_t>(Smi::kMaxValue) * 2; 4433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x10, 0, 0); 4453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x20, 0, 1); 4463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x30, 1, 0); 4473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x40, Smi::kMaxValue - 5, 5); 4483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x50, Smi::kMinValue + 5, 5); 4493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x60, twice_max, -Smi::kMaxValue); 4503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x70, -twice_max, Smi::kMaxValue); 4513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x80, 0, Smi::kMinValue); 4523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0x90, 0, Smi::kMaxValue); 4533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0xA0, Smi::kMinValue, 0); 4543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0xB0, Smi::kMaxValue, 0); 4553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestI64PlusConstantToSmi(masm, &exit, 0xC0, twice_max, Smi::kMinValue); 4563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 4583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 4598defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 4603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 4613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 4633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 4643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 4653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 4663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 4673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 4683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiCheck) { 47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 4723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 4733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 4743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 4753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 4763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 4773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 4783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 4798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 4808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 4818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 4823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 4843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 4858defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 4863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 4873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Condition cond; 4883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(1)); // Test number. 4903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // CheckSmi 4923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(0)); 4943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 4953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 4963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 4973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 4993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 5003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(-1)); 5053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 5113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMaxValue)); 5163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 5223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(Smi::kMinValue)); 5273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 5333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckSmi(rcx); 5343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // CheckPositiveSmi 5373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(0)); 5403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 541f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); 5423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 546f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // "zero" non-smi. 5473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(-1)); 5513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 552f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // Negative smis are not positive. 5533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMinValue)); 5573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 558f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // Most negative smi is not positive. 5593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 563f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // "Negative" non-smi. 5643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMaxValue)); 5683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 569f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // Most positive smi is positive. 5703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 574f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch cond = masm->CheckNonNegativeSmi(rcx); // "Positive" non-smi. 5753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // CheckIsMinSmi 5783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMaxValue)); 5813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckIsMinSmi(rcx); 5833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(0)); 5873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckIsMinSmi(rcx); 5893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 5903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMinValue)); 5933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 5943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckIsMinSmi(rcx); 5953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 5963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 5983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMinValue + 1)); 5993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 6003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckIsMinSmi(rcx); 6013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 6023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // CheckBothSmi 6043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMaxValue)); 6073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 6083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rdx, Immediate(Smi::kMinValue)); 6093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rdx, rdx); 6103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rcx, rdx); 6113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 6153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rcx, rdx); 6163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 6173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rdx, Immediate(kSmiTagMask)); 6203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rcx, rdx); 6213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 6223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 6253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rcx, rdx); 6263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 6273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rcx, rcx); 6303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckBothSmi(rdx, rdx); 6343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(cond, &exit); 6353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // CheckInteger32ValidSmiValue 6373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(0)); 6393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckInteger32ValidSmiValue(rax); 6403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(-1)); 6443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckInteger32ValidSmiValue(rax); 6453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMaxValue)); 6493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckInteger32ValidSmiValue(rax); 6503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, Immediate(Smi::kMinValue)); 6543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block cond = masm->CheckInteger32ValidSmiValue(rax); 6553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(NegateCondition(cond), &exit); 6563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Success 6583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); 6593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 6618defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 6623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 6633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 6653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 6663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 6673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 6683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 6693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 6703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) { 6743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 6753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 6763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (x == Smi::kMinValue || x == 0) { 6773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Negation fails. 6783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 8)); 6793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNeg(r9, rcx, exit); 6803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 6833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 6843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 6863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNeg(rcx, rcx, exit); 6873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 6903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 6913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 6923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label smi_ok, smi_ok2; 6933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = -x; 6943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 6953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 6963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNeg(r9, rcx, &smi_ok); 6983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 6993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&smi_ok); 7003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 7023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 7063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 7093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNeg(rcx, rcx, &smi_ok2); 7103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 7113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&smi_ok2); 7123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 7143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 7163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 7173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiNeg) { 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 7213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 7223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 7233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 7243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 7253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 7263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 7273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 7283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 7308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 7318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 7323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 7343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 7358defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 7363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 7373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x10, 0); 7393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x20, 1); 7403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x30, -1); 7413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x40, 127); 7423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x50, 65535); 7433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x60, Smi::kMinValue); 7443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x70, Smi::kMaxValue); 7453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNeg(masm, &exit, 0x80, -Smi::kMaxValue); 7463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 7483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 7498defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 7503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 7513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 7533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 7543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 7553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 7563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 7573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 7583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic void SmiAddTest(MacroAssembler* masm, 7633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 7643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 7653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int first, 7663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int second) { 7673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(first)); 7683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 7693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rdx, Immediate(second)); 7703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rdx, rdx); 7713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(r8, Immediate(first + second)); 7723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(r8, r8); 7733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); // Test number. 7753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAdd(r9, rcx, rdx, exit); 77644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 7773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 7803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAdd(rcx, rcx, rdx, exit); \ 78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 7823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(first)); 7853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 7863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 7883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAddConstant(r9, rcx, Smi::FromInt(second)); 78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 7903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAddConstant(rcx, rcx, Smi::FromInt(second)); 79344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 7943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 7953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rcx, Immediate(first)); 7973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Integer32ToSmi(rcx, rcx); 7983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 7993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 8003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAddConstant(r9, rcx, Smi::FromInt(second), exit); 80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 8023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 8053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), exit); 80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 8073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 8093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiAdd) { 81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 8123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 8133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 8143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 8153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 8163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 8173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 8183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 8198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 8208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 8218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 8223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 8243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 8258defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 8263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 8273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // No-overflow tests. 8293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x10, 1, 2); 8303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x20, 1, -2); 8313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x30, -1, 2); 8323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x40, -1, -2); 8333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x50, 0x1000, 0x2000); 8343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x60, Smi::kMinValue, 5); 8353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x70, Smi::kMaxValue, -5); 8363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiAddTest(masm, &exit, 0x80, Smi::kMaxValue, Smi::kMinValue); 8373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 8393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 8408defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 8413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 8423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 8443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 8453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 8463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 8473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 8483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 8493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic void SmiSubTest(MacroAssembler* masm, 8523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 8533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 8543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int first, 8553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int second) { 8563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(first)); 8573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(second)); 8583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(first - second)); 8593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); // Test 0. 8613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(r9, rcx, rdx, exit); 86244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 8633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); // Test 1. 8663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(rcx, rcx, rdx, exit); 86744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 8683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(first)); 8713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); // Test 2. 8733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(r9, rcx, Smi::FromInt(second)); 87444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 8753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); // Test 3. 8783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(rcx, rcx, Smi::FromInt(second)); 87944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 8803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(first)); 8833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); // Test 4. 8853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(r9, rcx, Smi::FromInt(second), exit); 88644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 8873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); // Test 5. 8903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), exit); 89144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 8923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 8933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 8943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 8953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockstatic void SmiSubOverflowTest(MacroAssembler* masm, 8963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 8973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 8983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int x) { 8993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Subtracts a Smi from x so that the subtraction overflows. 9003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(x != -1); // Can't overflow by subtracting a Smi. 9013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int y_max = (x < 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue + 0); 9023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int y_min = (x < 0) ? (Smi::kMaxValue + x + 2) : (Smi::kMinValue + x); 9033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 9053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 9063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); // Store original Smi value of x in r11. 9073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y_min)); 9083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(r9, rcx, rdx, &overflow_ok); 9113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 91444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(rcx, rcx, rdx, &overflow_ok); 9223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 9303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(r9, rcx, Smi::FromInt(y_min), &overflow_ok); 9343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 93744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_min), &overflow_ok); 9453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 94844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y_max)); 9533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(r9, rcx, rdx, &overflow_ok); 9583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSub(rcx, rcx, rdx, &overflow_ok); 9693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 97244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 9773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(r9, rcx, Smi::FromInt(y_max), &overflow_ok); 9813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 98444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 9883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block { 9893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok; 9903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 9913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), &overflow_ok); 9923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 9933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 9943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 99544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 9963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 9973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 9983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 9993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiSub) { 100244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 10033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 10043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 10053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 10063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 10073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 10083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 10093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 10103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 10118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 10128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 10138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 10143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 10163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 10178defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 10183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 10193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x10, 1, 2); 10213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x20, 1, -2); 10223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x30, -1, 2); 10233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x40, -1, -2); 10243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x50, 0x1000, 0x2000); 10253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x60, Smi::kMinValue, -5); 10263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x70, Smi::kMaxValue, 5); 10273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x80, -Smi::kMaxValue, Smi::kMinValue); 10283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubTest(masm, &exit, 0x90, 0, Smi::kMaxValue); 10293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xA0, 1); 10313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xB0, 1024); 10323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xC0, Smi::kMaxValue); 10333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xD0, -2); 10343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xE0, -42000); 10353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0xF0, Smi::kMinValue); 10363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiSubOverflowTest(masm, &exit, 0x100, 0); 10373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 10393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 10408defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 10413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 10423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 10443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 10453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 10463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 10473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 10483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 10493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) { 10533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int64_t result = static_cast<int64_t>(x) * static_cast<int64_t>(y); 10543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool negative_zero = (result == 0) && (x < 0 || y < 0); 10553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 10563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 10573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 10583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (Smi::IsValid(result) && !negative_zero) { 10593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 10603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromIntptr(result)); 10613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiMul(r9, rcx, rdx, exit); 10623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 106344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 10643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 10653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 106644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 10673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 10683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 10703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiMul(rcx, rcx, rdx, exit); 107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 10723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 10733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 10743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id + 8)); 10753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label overflow_ok, overflow_ok2; 10763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiMul(r9, rcx, rdx, &overflow_ok); 10773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 10783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok); 10793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 108044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 10813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 10823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 10833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiMul(rcx, rcx, rdx, &overflow_ok2); 10843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 10853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&overflow_ok2); 10863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 31-bit version doesn't preserve rcx on failure. 10873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // __ incq(rax); 108844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // __ cmpq(r11, rcx); 10893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // __ j(not_equal, exit); 10903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 10913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 10923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 10943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiMul) { 109544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 10963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 10973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 10983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 10993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 11003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 11013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 11023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 11038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 11048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 11058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 11063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 11083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 11098defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 11103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 11113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x10, 0, 0); 11133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x20, -1, 0); 11143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x30, 0, -1); 11153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x40, -1, -1); 11163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x50, 0x10000, 0x10000); 11173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x60, 0x10000, 0xffff); 11183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x70, 0x10000, 0xffff); 11193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x80, Smi::kMaxValue, -1); 11203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0x90, Smi::kMaxValue, -2); 11213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0xa0, Smi::kMaxValue, 2); 11223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0xb0, (Smi::kMaxValue / 2), 2); 11233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0xc0, (Smi::kMaxValue / 2) + 1, 2); 11243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0xd0, (Smi::kMinValue / 2), 2); 11253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMul(masm, &exit, 0xe0, (Smi::kMinValue / 2) - 1, 2); 11263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 11283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 11298defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 11303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 11313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 11333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 11343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 11353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 11363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 11373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 11383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) { 11413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool division_by_zero = (y == 0); 11423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool negative_zero = (x == 0 && y < 0); 11433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef V8_TARGET_ARCH_X64 11443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool overflow = (x == Smi::kMinValue && y < 0); // Safe approx. used. 11453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#else 11463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool overflow = (x == Smi::kMinValue && y == -1); 11473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif 11483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool fraction = !division_by_zero && !overflow && (x % y != 0); 11493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r11, Smi::FromInt(x)); 11508defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ Move(r14, Smi::FromInt(y)); 11513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!fraction && !overflow && !negative_zero && !division_by_zero) { 11523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Division succeeds 11533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 115444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(r15, Immediate(id)); 11553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x / y; 11563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 11578defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiDiv(r9, rcx, r14, exit); 11588defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Might have destroyed rcx and r14. 115944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 116044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 11613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 11623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 116344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 11643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 11658defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ Move(r14, Smi::FromInt(y)); 116644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 11673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 11683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 116944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 11708defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiDiv(rcx, rcx, r14, exit); 11713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 11743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 11753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 11763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Division fails. 117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(r15, Immediate(id + 8)); 11783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 11793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label fail_ok, fail_ok2; 11803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 11818defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiDiv(r9, rcx, r14, &fail_ok); 11823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 11833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok); 11843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 118544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 118644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 11873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 11883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 11908defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiDiv(rcx, rcx, r14, &fail_ok2); 11913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 11923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok2); 11933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 11963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 11973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 11983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 11993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiDiv) { 120244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 12033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 12043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 12053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 12063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 12073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 12083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 12093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 12103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 12118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 12128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 12138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 12143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 12163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 12178defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 12183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 12193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12208defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ push(r14); 122144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ push(r15); 12223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x10, 1, 1); 12233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x20, 1, 0); 12243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x30, -1, 0); 12253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x40, 0, 1); 12263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x50, 0, -1); 12273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x60, 4, 2); 12283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x70, -4, 2); 12293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x80, 4, -2); 12303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x90, -4, -2); 12313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xa0, 3, 2); 12323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xb0, 3, 4); 12333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xc0, 1, Smi::kMaxValue); 12343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xd0, -1, Smi::kMaxValue); 12353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xe0, Smi::kMaxValue, 1); 12363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0xf0, Smi::kMaxValue, Smi::kMaxValue); 12373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x100, Smi::kMaxValue, -Smi::kMaxValue); 12383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x110, Smi::kMaxValue, -1); 12393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x120, Smi::kMinValue, 1); 12403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x130, Smi::kMinValue, Smi::kMinValue); 12413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiDiv(masm, &exit, 0x140, Smi::kMinValue, -1); 12423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ xor_(r15, r15); // Success. 12443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(rax, r15); 124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ pop(r15); 12478defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ pop(r14); 12488defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 12493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 12503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 12523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 12533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 12543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 12553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 12563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 12573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiMod(MacroAssembler* masm, Label* exit, int id, int x, int y) { 12603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool division_by_zero = (y == 0); 12613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool division_overflow = (x == Smi::kMinValue) && (y == -1); 12623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool fraction = !division_by_zero && !division_overflow && ((x % y) != 0); 12633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bool negative_zero = (!fraction && x < 0); 12643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 12653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 12668defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ Move(r14, Smi::FromInt(y)); 12673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!division_overflow && !negative_zero && !division_by_zero) { 12683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Modulo succeeds 126944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(r15, Immediate(id)); 12703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x % y; 12713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 12728defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiMod(r9, rcx, r14, exit); 12733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 127444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 127544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 12763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 12773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 127844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 127944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 12803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 12813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 128244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 12838defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiMod(rcx, rcx, r14, exit); 12843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 128544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 128644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 12873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 12883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 12893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Modulo fails. 129044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(r15, Immediate(id + 8)); 12913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 12923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label fail_ok, fail_ok2; 12938defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiMod(r9, rcx, r14, &fail_ok); 12943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 12953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok); 12963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 129744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 129844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 12993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 13003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 130144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 13028defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ SmiMod(rcx, rcx, r14, &fail_ok2); 13033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 13043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok2); 13053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 130644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ incq(r15); 130744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 13083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 13093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 13103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 13113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiMod) { 131444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 13153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 13163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 13173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 13183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 13193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 13203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 13213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 13223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 13238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 13248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 13258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 13263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 13283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 13298defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 13303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 13313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13328defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ push(r14); 133344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ push(r15); 13343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x10, 1, 1); 13353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x20, 1, 0); 13363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x30, -1, 0); 13373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x40, 0, 1); 13383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x50, 0, -1); 13393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x60, 4, 2); 13403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x70, -4, 2); 13413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x80, 4, -2); 13423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x90, -4, -2); 13433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xa0, 3, 2); 13443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xb0, 3, 4); 13453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xc0, 1, Smi::kMaxValue); 13463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xd0, -1, Smi::kMaxValue); 13473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xe0, Smi::kMaxValue, 1); 13483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0xf0, Smi::kMaxValue, Smi::kMaxValue); 13493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x100, Smi::kMaxValue, -Smi::kMaxValue); 13503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x110, Smi::kMaxValue, -1); 13513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x120, Smi::kMinValue, 1); 13523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x130, Smi::kMinValue, Smi::kMinValue); 13533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiMod(masm, &exit, 0x140, Smi::kMinValue, -1); 13543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 135544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ xor_(r15, r15); // Success. 13563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 135744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ movq(rax, r15); 135844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ pop(r15); 13598defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ pop(r14); 13608defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 13613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 13623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 13643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 13653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 13663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 13673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 13683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { 13723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 13733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < 8; i++) { 13753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 13763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiIndex index = masm->SmiToIndex(rdx, rcx, i); 13773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(index.reg.is(rcx) || index.reg.is(rdx)); 13783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ shl(index.reg, Immediate(index.scale)); 13793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(r8, static_cast<intptr_t>(x) << i); 138044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(index.reg, r8); 13813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 13823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 13833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 13843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block index = masm->SmiToIndex(rcx, rcx, i); 13853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(index.reg.is(rcx)); 13863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ shl(rcx, Immediate(index.scale)); 13873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(r8, static_cast<intptr_t>(x) << i); 138844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 13893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 13903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 13913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 13923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 13933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block index = masm->SmiToNegativeIndex(rdx, rcx, i); 13943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(index.reg.is(rcx) || index.reg.is(rdx)); 13953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ shl(index.reg, Immediate(index.scale)); 13963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(r8, static_cast<intptr_t>(-x) << i); 139744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(index.reg, r8); 13983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 13993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 14003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 14013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block index = masm->SmiToNegativeIndex(rcx, rcx, i); 14023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(index.reg.is(rcx)); 14033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ shl(rcx, Immediate(index.scale)); 14043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(r8, static_cast<intptr_t>(-x) << i); 140544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 14063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 14073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 14083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 14093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 14103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiIndex) { 141244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 14133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 14143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 14153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 14168defd9ff6930b4e24729971a61cf7469daf119beSteve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, 14173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 14183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 14193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 14203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 14218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 14228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 14238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 14243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 14263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 14278defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 14283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 14293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiIndex(masm, &exit, 0x10, 0); 14313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiIndex(masm, &exit, 0x20, 1); 14323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiIndex(masm, &exit, 0x30, 100); 14333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiIndex(masm, &exit, 0x40, 1000); 14343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiIndex(masm, &exit, 0x50, Smi::kMaxValue); 14353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 14373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 14388defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 14393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 14403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 14423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 14433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 14443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 14453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 14463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 14473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) { 14503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 14513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 14523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 14533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rdx, Immediate(kSmiTagMask)); 14543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SelectNonSmi(r9, rcx, rdx, exit); 14553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 145744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, rdx); 14583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 14593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 14613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 14623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 14633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 14643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SelectNonSmi(r9, rcx, rdx, exit); 14653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 146744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, rcx); 14683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 14693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 14713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label fail_ok; 14723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 14733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 14743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rcx, Immediate(kSmiTagMask)); 14753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rdx, Immediate(kSmiTagMask)); 14763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SelectNonSmi(r9, rcx, rdx, &fail_ok); 14773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 14783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok); 14793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 14803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiSelectNonSmi) { 148344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 14843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 14853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 14863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 14873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 14883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 14893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 14903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 14913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 14928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 14938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 14948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 14953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 14963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 14973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); // Avoid inline checks. 14988defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 14993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 15003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x10, 0, 0); 15023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x20, 0, 1); 15033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x30, 1, 0); 15043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x40, 0, -1); 15053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x50, -1, 0); 15063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x60, -1, -1); 15073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x70, 1, 1); 15083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x80, Smi::kMinValue, Smi::kMaxValue); 15093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSelectNonSmi(masm, &exit, 0x90, Smi::kMinValue, Smi::kMinValue); 15103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 15123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 15138defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 15143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 15153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 15173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 15183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 15193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 15203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 15213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 15223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiAnd(MacroAssembler* masm, Label* exit, int id, int x, int y) { 15253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x & y; 15263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 15283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 15303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 15313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 15323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 15333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAnd(r9, rcx, rdx); 153444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 15353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 153844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 15393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 15423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAnd(rcx, rcx, rdx); 154344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 15443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 15473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 15483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAndConstant(r9, rcx, Smi::FromInt(y)); 154944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 15503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 155344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 15543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 15573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiAndConstant(rcx, rcx, Smi::FromInt(y)); 155844f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 15593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 15603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 15613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiAnd) { 156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 15653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 15663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 15673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 15683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 15693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 15703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 15713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 15723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 15738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 15748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 15758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 15763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 15783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 15798defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 15803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 15813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x10, 0, 0); 15833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x20, 0, 1); 15843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x30, 1, 0); 15853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x40, 0, -1); 15863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x50, -1, 0); 15873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x60, -1, -1); 15883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x70, 1, 1); 15893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x80, Smi::kMinValue, Smi::kMaxValue); 15903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0x90, Smi::kMinValue, Smi::kMinValue); 15913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0xA0, Smi::kMinValue, -1); 15923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiAnd(masm, &exit, 0xB0, Smi::kMinValue, -1); 15933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 15953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 15968defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 15973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 15983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 15993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 16003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 16013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 16023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 16033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 16043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 16053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiOr(MacroAssembler* masm, Label* exit, int id, int x, int y) { 16083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x | y; 16093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 16113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 16133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 16143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 16153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 16163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiOr(r9, rcx, rdx); 161744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 16183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 162144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 16223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 16253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiOr(rcx, rcx, rdx); 162644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 16273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 16303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 16313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiOrConstant(r9, rcx, Smi::FromInt(y)); 163244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 16333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 163644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 16373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 16403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiOrConstant(rcx, rcx, Smi::FromInt(y)); 164144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 16423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 16433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 16443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiOr) { 164744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 16483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 16493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 16503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 16513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 16523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 16533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 16543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 16553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 16568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 16578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 16588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 16593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 16613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 16628defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 16633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 16643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x10, 0, 0); 16663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x20, 0, 1); 16673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x30, 1, 0); 16683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x40, 0, -1); 16693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x50, -1, 0); 16703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x60, -1, -1); 16713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x70, 1, 1); 16723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x80, Smi::kMinValue, Smi::kMaxValue); 16733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0x90, Smi::kMinValue, Smi::kMinValue); 16743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0xA0, Smi::kMinValue, -1); 16753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0xB0, 0x05555555, 0x01234567); 16763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0xC0, 0x05555555, 0x0fedcba9); 16773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiOr(masm, &exit, 0xD0, Smi::kMinValue, -1); 16783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 16803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 16818defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 16823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 16833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 16853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 16863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 16873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 16883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 16893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 16903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiXor(MacroAssembler* masm, Label* exit, int id, int x, int y) { 16933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x ^ y; 16943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 16963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 16973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 16983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 16993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(y)); 17003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 17013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiXor(r9, rcx, rdx); 170244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 17033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 170644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 17073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 17103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiXor(rcx, rcx, rdx); 171144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 17123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(rcx, r11); 17153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 17163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiXorConstant(r9, rcx, Smi::FromInt(y)); 171744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, r9); 17183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 172144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 17223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 17253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiXorConstant(rcx, rcx, Smi::FromInt(y)); 172644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r8, rcx); 17273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 17293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiXor) { 173244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 17333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 17343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 17353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 17363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 17373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 17383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 17393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 17403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 17418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 17428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 17438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 17443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 17463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 17478defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 17483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 17493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x10, 0, 0); 17513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x20, 0, 1); 17523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x30, 1, 0); 17533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x40, 0, -1); 17543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x50, -1, 0); 17553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x60, -1, -1); 17563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x70, 1, 1); 17573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x80, Smi::kMinValue, Smi::kMaxValue); 17583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0x90, Smi::kMinValue, Smi::kMinValue); 17593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0xA0, Smi::kMinValue, -1); 17603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0xB0, 0x5555555, 0x01234567); 17613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0xC0, 0x5555555, 0x0fedcba9); 17623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiXor(masm, &exit, 0xD0, Smi::kMinValue, -1); 17633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 17653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 17668defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 17673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 17683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 17703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 17713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 17723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 17733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 17743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 17753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiNot(MacroAssembler* masm, Label* exit, int id, int x) { 17783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = ~x; 17793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 17803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 17823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 17833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 17843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNot(r9, rcx); 178644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 17873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 179044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); 17913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 17943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiNot(rcx, rcx); 179544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 17963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 17973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 17983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 17993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiNot) { 180144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 18023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 18033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 18043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 18053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 18063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 18073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 18083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 18093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 18108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 18118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 18128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 18133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 18153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 18168defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 18173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 18183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x10, 0); 18203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x20, 1); 18213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x30, -1); 18223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x40, 127); 18233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x50, 65535); 18243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x60, Smi::kMinValue); 18253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x70, Smi::kMaxValue); 18263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiNot(masm, &exit, 0x80, 0x05555555); 18273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 18293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 18308defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 18313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 18323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 18343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 18353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 18363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 18373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 18383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 18393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) { 18423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int shifts[] = { 0, 1, 7, 24, kSmiValueSize - 1}; 18433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int kNumShifts = 5; 18443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 18453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < kNumShifts; i++) { 18463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // rax == id + i * 10. 18473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift = shifts[i]; 18483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = x << shift; 184925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen CHECK(Smi::IsValid(result)); 185025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(r8, Smi::FromInt(result)); 185125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rcx, Smi::FromInt(x)); 185225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ SmiShiftLeftConstant(r9, rcx, shift); 185325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 185425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 185544f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 185625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ j(not_equal, exit); 185725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 185825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 185925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rcx, Smi::FromInt(x)); 186025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ SmiShiftLeftConstant(rcx, rcx, shift); 186125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 186225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 186344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 186425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ j(not_equal, exit); 186525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 186625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 186725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rdx, Smi::FromInt(x)); 186825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rcx, Smi::FromInt(shift)); 186925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ SmiShiftLeft(r9, rdx, rcx); 187025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 187125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 187244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 187325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ j(not_equal, exit); 187425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 187525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 187625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rdx, Smi::FromInt(x)); 187725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(r11, Smi::FromInt(shift)); 187825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ SmiShiftLeft(r9, rdx, r11); 187925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 188025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 188144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 188225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ j(not_equal, exit); 188325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 188425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 188525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(rdx, Smi::FromInt(x)); 188625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ Move(r11, Smi::FromInt(shift)); 188725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ SmiShiftLeft(rdx, rdx, r11); 188825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 188925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 189044f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rdx, r8); 189125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ j(not_equal, exit); 189225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 189325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen __ incq(rax); 18943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 18953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 18963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 18983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiShiftLeft) { 189944f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 19003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 19013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 19023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 19038defd9ff6930b4e24729971a61cf7469daf119beSteve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4, 19043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 19053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 19063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 19073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 19088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 19098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 19108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 19113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 19133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 19148defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 19153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 19163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x10, 0); 19183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x50, 1); 19193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x90, 127); 19203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0xD0, 65535); 19213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x110, Smi::kMaxValue); 19223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x150, Smi::kMinValue); 19233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLeft(masm, &exit, 0x190, -1); 19243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 19263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 19278defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 19283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 19293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 19313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 19323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 19333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 19343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 19353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 19363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiShiftLogicalRight(MacroAssembler* masm, 19393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 19403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 19413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int x) { 19423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int shifts[] = { 0, 1, 7, 24, kSmiValueSize - 1}; 19433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int kNumShifts = 5; 19443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 19453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < kNumShifts; i++) { 19463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift = shifts[i]; 19473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block intptr_t result = static_cast<unsigned int>(x) >> shift; 19483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (Smi::IsValid(result)) { 1949d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block __ Move(r8, Smi::FromInt(static_cast<int>(result))); 19503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 19513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftLogicalRightConstant(r9, rcx, shift, exit); 19523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 195444f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 19553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 19563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 19583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(x)); 19593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(shift)); 19603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftLogicalRight(r9, rdx, rcx, exit); 19613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 196344f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 19643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 19653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 19673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(x)); 19683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r11, Smi::FromInt(shift)); 19693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftLogicalRight(r9, rdx, r11, exit); 19703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 197244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r9, r8); 19733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 19743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 19763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 19773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Cannot happen with long smis. 19783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label fail_ok; 19793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 19803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 19813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftLogicalRightConstant(r9, rcx, shift, &fail_ok); 19823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 19833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok); 19843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 198644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 19873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 19883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 19903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(shift)); 19913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label fail_ok3; 19923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftLogicalRight(r9, rcx, r8, &fail_ok3); 19933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ jmp(exit); 19943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&fail_ok3); 19953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 19963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 199744f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r11); 19983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 19993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ addq(rax, Immediate(3)); 20013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 20023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 20033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 20043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiShiftLogicalRight) { 200744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 20083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 20093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 20103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 20118defd9ff6930b4e24729971a61cf7469daf119beSteve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 3, 20123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 20133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 20143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 20153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 20168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 20178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 20188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 20193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 20213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 20228defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 20233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 20243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0x10, 0); 20263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0x30, 1); 20273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0x50, 127); 20283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0x70, 65535); 20293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0x90, Smi::kMaxValue); 20303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0xB0, Smi::kMinValue); 20313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftLogicalRight(masm, &exit, 0xD0, -1); 20323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 20343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 20358defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 20363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 20373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 20393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 20403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 20413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 20423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 20433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 20443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestSmiShiftArithmeticRight(MacroAssembler* masm, 20473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label* exit, 20483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int id, 20493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int x) { 20503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int shifts[] = { 0, 1, 7, 24, kSmiValueSize - 1}; 20513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const int kNumShifts = 5; 20523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 20533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < kNumShifts; i++) { 20543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift = shifts[i]; 20553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Guaranteed arithmetic shift. 20563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = (x < 0) ? ~((~x) >> shift) : (x >> shift); 20573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r8, Smi::FromInt(result)); 20583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 20593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftArithmeticRightConstant(rcx, rcx, shift); 20603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 206144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rcx, r8); 20623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 20633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 20653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rdx, Smi::FromInt(x)); 20663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(r11, Smi::FromInt(shift)); 20673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ SmiShiftArithmeticRight(rdx, rdx, r11); 20683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 206944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rdx, r8); 20703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 20713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 20733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 20743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 20753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(SmiShiftArithmeticRight) { 207844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 20793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 20803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 20813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 20823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 20833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 20843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 20853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 20863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 20878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 20888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 20898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 20903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 20923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 20938defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 20943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 20953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 20963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x10, 0); 20973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x20, 1); 20983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x30, 127); 20993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x40, 65535); 21003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x50, Smi::kMaxValue); 21013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x60, Smi::kMinValue); 21023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestSmiShiftArithmeticRight(masm, &exit, 0x70, -1); 21033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 21053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 21068defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 21073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 21083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 21103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 21113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 21123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 21133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 21143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 21153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) { 21183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(x >= 0); 21193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int powers[] = { 0, 1, 2, 3, 8, 16, 24, 31 }; 21203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int power_count = 8; 21213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movl(rax, Immediate(id)); 21223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block for (int i = 0; i < power_count; i++) { 21233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int power = powers[i]; 21243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block intptr_t result = static_cast<intptr_t>(x) << power; 21253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Set(r8, result); 21263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ Move(rcx, Smi::FromInt(x)); 21273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ movq(r11, rcx); 21283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rcx, power); 212944f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rdx, r8); 21303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 21313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 213244f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(r11, rcx); // rcx unchanged. 21333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 21343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 21353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ PositiveSmiTimesPowerOfTwoToInteger64(rcx, rcx, power); 213644f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ cmpq(rdx, r8); 21373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ j(not_equal, exit); 21383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ incq(rax); 21393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 21403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 21413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockTEST(PositiveSmiTimesPowerOfTwoToInteger64) { 214444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 21453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate an executable page of memory. 21463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block size_t actual_size; 21473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block byte* buffer = 214844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 4, 21493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block &actual_size, 21503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block true)); 21513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK(buffer); 21523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block HandleScope handles; 21538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 21548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 21558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 21563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block MacroAssembler* masm = &assembler; 21583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->set_allow_stub_calls(false); 21598defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 21603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Label exit; 21613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x20, 0); 21633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x40, 1); 21643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x60, 127); 21653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x80, 128); 21663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0xA0, 255); 21673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0xC0, 256); 21683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x100, 65535); 21693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x120, 65536); 21703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block TestPositiveSmiPowerUp(masm, &exit, 0x140, Smi::kMaxValue); 21713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ xor_(rax, rax); // Success. 21733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ bind(&exit); 21748defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 21753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block __ ret(0); 21763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CodeDesc desc; 21783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block masm->GetCode(&desc); 21793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Call the function from C++. 21803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int result = FUNCTION_CAST<F0>(buffer)(); 21813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(0, result); 21823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 21833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 21843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2185f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeTEST(OperandOffset) { 218644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 2187f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int data[256]; 2188f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke for (int i = 0; i < 256; i++) { data[i] = i * 0x01010101; } 2189f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2190f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Allocate an executable page of memory. 2191f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke size_t actual_size; 2192f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke byte* buffer = 2193f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, 2194f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke &actual_size, 2195f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke true)); 2196f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK(buffer); 2197f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HandleScope handles; 21988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler assembler(Isolate::Current(), 21998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch buffer, 22008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static_cast<int>(actual_size)); 2201f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2202f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke MacroAssembler* masm = &assembler; 2203f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke masm->set_allow_stub_calls(false); 2204f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Label exit; 2205f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 22068defd9ff6930b4e24729971a61cf7469daf119beSteve Block EntryCode(masm); 2207f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(r13); 22088defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ push(r14); 2209f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(rbx); 2210f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(rbp); 2211f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x100)); // <-- rbp 2212f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movq(rbp, rsp); 2213f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x101)); 2214f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x102)); 2215f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x103)); 2216f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x104)); 2217f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x105)); // <-- rbx 2218f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x106)); 2219f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x107)); 2220f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x108)); 2221f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ push(Immediate(0x109)); // <-- rsp 2222f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // rbp = rsp[9] 222344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // r15 = rsp[3] 2224f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // rbx = rsp[5] 2225f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // r13 = rsp[7] 22268defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ lea(r14, Operand(rsp, 3 * kPointerSize)); 2227f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ lea(r13, Operand(rbp, -3 * kPointerSize)); 2228f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ lea(rbx, Operand(rbp, -5 * kPointerSize)); 2229f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rcx, Immediate(2)); 2230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movq(r8, reinterpret_cast<uintptr_t>(&data[128]), RelocInfo::NONE); 2231f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rax, Immediate(1)); 2232f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2233f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand sp0 = Operand(rsp, 0); 2234f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2235f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 1. 2236f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, sp0); // Sanity check. 2237f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x109)); 2238f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2239f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2240f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2241f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 2. 2242f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Zero to non-zero displacement. 2243f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(sp0, 2 * kPointerSize)); 2244f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x107)); 2245f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2246f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2247f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2248f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand sp2 = Operand(rsp, 2 * kPointerSize); 2249f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2250f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 3. 2251f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, sp2); // Sanity check. 2252f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x107)); 2253f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2254f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2255f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2256f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(sp2, 2 * kPointerSize)); 2257f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x105)); 2258f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2259f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2260f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2261f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Non-zero to zero displacement. 2262f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(sp2, -2 * kPointerSize)); 2263f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x109)); 2264f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2265f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2266f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2267f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand sp2c2 = Operand(rsp, rcx, times_pointer_size, 2 * kPointerSize); 2268f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2269f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 6. 2270f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, sp2c2); // Sanity check. 2271f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x105)); 2272f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2273f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2274f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2275f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(sp2c2, 2 * kPointerSize)); 2276f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x103)); 2277f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2278f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2279f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2280f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Non-zero to zero displacement. 2281f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(sp2c2, -2 * kPointerSize)); 2282f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x107)); 2283f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2284f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2285f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2286f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2287f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bp0 = Operand(rbp, 0); 2288f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2289f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 9. 2290f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bp0); // Sanity check. 2291f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x100)); 2292f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2293f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2294f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2295f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Zero to non-zero displacement. 2296f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bp0, -2 * kPointerSize)); 2297f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x102)); 2298f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2299f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2300f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2301f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bp2 = Operand(rbp, -2 * kPointerSize); 2302f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2303f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 11. 2304f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bp2); // Sanity check. 2305f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x102)); 2306f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2307f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2308f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2309f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Non-zero to zero displacement. 2310f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bp2, 2 * kPointerSize)); 2311f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x100)); 2312f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2313f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2314f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2315f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bp2, -2 * kPointerSize)); 2316f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x104)); 2317f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2318f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2319f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2320f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bp2c4 = Operand(rbp, rcx, times_pointer_size, -4 * kPointerSize); 2321f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2322f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 14: 2323f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bp2c4); // Sanity check. 2324f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x102)); 2325f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2326f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2327f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2328f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bp2c4, 2 * kPointerSize)); 2329f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x100)); 2330f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2331f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2332f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2333f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bp2c4, -2 * kPointerSize)); 2334f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x104)); 2335f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2336f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2337f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2338f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bx0 = Operand(rbx, 0); 2339f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2340f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 17. 2341f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bx0); // Sanity check. 2342f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x105)); 2343f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2344f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2345f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2346f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx0, 5 * kPointerSize)); 2347f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x100)); 2348f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2349f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2350f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2351f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx0, -4 * kPointerSize)); 2352f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x109)); 2353f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2354f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2355f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2356f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bx2 = Operand(rbx, 2 * kPointerSize); 2357f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2358f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 20. 2359f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bx2); // Sanity check. 2360f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x103)); 2361f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2362f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2363f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2364f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx2, 2 * kPointerSize)); 2365f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x101)); 2366f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2367f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2368f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2369f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Non-zero to zero displacement. 2370f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx2, -2 * kPointerSize)); 2371f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x105)); 2372f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2373f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2374f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2375f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand bx2c2 = Operand(rbx, rcx, times_pointer_size, -2 * kPointerSize); 2376f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2377f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 23. 2378f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, bx2c2); // Sanity check. 2379f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x105)); 2380f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx2c2, 2 * kPointerSize)); 2384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x103)); 2385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(bx2c2, -2 * kPointerSize)); 2389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x107)); 2390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand r80 = Operand(r8, 0); 2394f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2395f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 26. 2396f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, r80); // Sanity check. 2397f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x80808080)); 2398f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2399f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2400f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2401f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, -8 * kIntSize)); 2402f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x78787878)); 2403f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2404f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2405f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2406f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, 8 * kIntSize)); 2407f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x88888888)); 2408f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2409f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2410f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2411f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, -64 * kIntSize)); 2412f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x40404040)); 2413f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2414f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2415f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2416f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, 64 * kIntSize)); 2417f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xC0C0C0C0)); 2418f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2419f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2420f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2421f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand r88 = Operand(r8, 8 * kIntSize); 2422f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2423f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 31. 2424f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, r88); // Sanity check. 2425f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x88888888)); 2426f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2427f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2428f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2429f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r88, -8 * kIntSize)); 2430f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x80808080)); 2431f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2432f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2433f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2434f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r88, 8 * kIntSize)); 2435f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x90909090)); 2436f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2437f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2438f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2439f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r88, -64 * kIntSize)); 2440f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x48484848)); 2441f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2442f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2443f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2444f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r88, 64 * kIntSize)); 2445f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xC8C8C8C8)); 2446f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2447f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2448f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2449f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2450f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Operand r864 = Operand(r8, 64 * kIntSize); 2451f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2452f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 36. 2453f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, r864); // Sanity check. 2454f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xC0C0C0C0)); 2455f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2456f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2457f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2458f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, -8 * kIntSize)); 2459f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xB8B8B8B8)); 2460f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2461f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2462f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2463f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, 8 * kIntSize)); 2464f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xC8C8C8C8)); 2465f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2466f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2467f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2468f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, -64 * kIntSize)); 2469f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x80808080)); 2470f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2471f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2472f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2473f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, 32 * kIntSize)); 2474f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xE0E0E0E0)); 2475f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2476f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2477f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2478f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 32-bit offset to 8-bit offset. 2479f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, -60 * kIntSize)); 2480f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x84848484)); 2481f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2482f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2483f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2484f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r864, 60 * kIntSize)); 2485f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xFCFCFCFC)); 2486f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2487f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2488f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2489f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test unaligned offsets. 2490f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2491f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Test 43. 2492f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, 2)); 2493f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x81818080)); 2494f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2495f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2496f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2497f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, -2)); 2498f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x80807F7F)); 2499f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2500f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2501f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2502f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, 126)); 2503f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xA0A09F9F)); 2504f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2505f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2506f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2507f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, -126)); 2508f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x61616060)); 2509f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2510f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2511f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2512f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, 254)); 2513f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0xC0C0BFBF)); 2514f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2515f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2516f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2517f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rdx, Operand(r80, -254)); 2518f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ cmpl(rdx, Immediate(0x41414040)); 2519f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ j(not_equal, &exit); 2520f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ incq(rax); 2521f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2522f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Success. 2523f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2524f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ movl(rax, Immediate(0)); 2525f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ bind(&exit); 2526f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ lea(rsp, Operand(rbp, kPointerSize)); 2527f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ pop(rbp); 2528f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ pop(rbx); 25298defd9ff6930b4e24729971a61cf7469daf119beSteve Block __ pop(r14); 2530f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ pop(r13); 25318defd9ff6930b4e24729971a61cf7469daf119beSteve Block ExitCode(masm); 2532f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke __ ret(0); 2533f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2534f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2535f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CodeDesc desc; 2536f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke masm->GetCode(&desc); 2537f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Call the function from C++. 2538f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int result = FUNCTION_CAST<F0>(buffer)(); 2539f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK_EQ(0, result); 2540f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 2541f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2542f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 2543f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 25443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#undef __ 2545