Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Unified Diff: src/x64/code-stubs-x64.cc

Issue 18014003: Add X32 port into V8 (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/x64/code-stubs-x64.cc
===================================================================
--- src/x64/code-stubs-x64.cc (revision 15486)
+++ src/x64/code-stubs-x64.cc (working copy)
@@ -227,6 +227,11 @@
#define __ ACCESS_MASM(masm)
+#define __k __
+#define __a __
+#define __q __
+#define __s __
+#define __n __
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
@@ -267,9 +272,9 @@
__ Ret();
__ bind(&call_builtin);
- __ pop(rcx); // Pop return address.
+ __k pop(rcx); // Pop return address.
__ push(rax);
- __ push(rcx); // Push return address.
+ __k push(rcx); // Push return address.
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
}
@@ -285,7 +290,7 @@
__ IncrementCounter(counters->fast_new_closure_total(), 1);
// Get the function info from the stack.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 1 * kPointerSize));
int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
@@ -393,17 +398,17 @@
__ ret(1 * kPointerSize);
__ bind(&restore);
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 1 * kPointerSize));
__ jmp(&install_unoptimized);
// Create a new closure through the slower runtime call.
__ bind(&gc);
- __ pop(rcx); // Temporarily remove return address.
+ __k pop(rcx); // Temporarily remove return address.
__ pop(rdx);
__ push(rsi);
__ push(rdx);
__ PushRoot(Heap::kFalseValueRootIndex);
- __ push(rcx); // Restore return address.
+ __k push(rcx); // Restore return address.
__ TailCallRuntime(Runtime::kNewClosure, 3, 1);
}
@@ -416,7 +421,7 @@
rax, rbx, rcx, &gc, TAG_OBJECT);
// Get the function from the stack.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
// Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
@@ -462,10 +467,10 @@
rax, rbx, rcx, &gc, TAG_OBJECT);
// Get the function from the stack.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
// Get the serialized scope info from the stack.
- __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+ __a movq(rbx, Operand(rsp, 2 * kPointerSize));
// Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex);
@@ -589,14 +594,14 @@
Register double_value = rdi;
Label done, exponent_63_plus;
// Get double and extract exponent.
- __ movq(double_value, FieldOperand(source, HeapNumber::kValueOffset));
+ __k movq(double_value, FieldOperand(source, HeapNumber::kValueOffset));
// Clear result preemptively, in case we need to return zero.
__ xorl(result, result);
__ movq(xmm0, double_value); // Save copy in xmm0 in case we need it there.
// Double to remove sign bit, shift exponent down to least significant bits.
// and subtract bias to get the unshifted, unbiased exponent.
- __ lea(double_exponent, Operand(double_value, double_value, times_1, 0));
- __ shr(double_exponent, Immediate(64 - HeapNumber::kExponentBits));
+ __k lea(double_exponent, Operand(double_value, double_value, times_1, 0));
+ __k shr(double_exponent, Immediate(64 - HeapNumber::kExponentBits));
__ subl(double_exponent, Immediate(HeapNumber::kExponentBias));
// Check whether the exponent is too big for a 63 bit unsigned integer.
__ cmpl(double_exponent, Immediate(63));
@@ -617,7 +622,7 @@
// the least significant exponent-52 bits.
// Negate low bits of mantissa if value is negative.
- __ addq(double_value, double_value); // Move sign bit to carry.
+ __k addq(double_value, double_value); // Move sign bit to carry.
__ sbbl(result, result); // And convert carry to -1 in result register.
// if scratch2 is negative, do (scratch2-1)^-1, otherwise (scratch2-0)^0.
__ addl(double_value, result);
@@ -662,14 +667,14 @@
void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
- __ pop(rcx); // Save return address.
+ __k pop(rcx); // Save return address.
__ push(rax); // the operand
__ Push(Smi::FromInt(op_));
__ Push(Smi::FromInt(mode_));
__ Push(Smi::FromInt(operand_type_));
- __ push(rcx); // Push return address.
+ __k push(rcx); // Push return address.
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
@@ -780,8 +785,8 @@
// Operand is a float, negate its value by flipping the sign bit.
if (mode_ == UNARY_OVERWRITE) {
__ Set(kScratchRegister, 0x01);
- __ shl(kScratchRegister, Immediate(63));
- __ xor_(FieldOperand(rax, HeapNumber::kValueOffset), kScratchRegister);
+ __k shl(kScratchRegister, Immediate(63));
+ __k xor_(FieldOperand(rax, HeapNumber::kValueOffset), kScratchRegister);
} else {
// Allocate a heap number before calculating the answer,
// so we don't have an untagged double around during GC.
@@ -801,11 +806,11 @@
// rcx: allocated 'empty' number
// Copy the double value to the new heap number, flipping the sign.
- __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
+ __k movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
__ Set(kScratchRegister, 0x01);
- __ shl(kScratchRegister, Immediate(63));
- __ xor_(rdx, kScratchRegister); // Flip sign.
- __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
+ __k shl(kScratchRegister, Immediate(63));
+ __k xor_(rdx, kScratchRegister); // Flip sign.
+ __k movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
__ movq(rax, rcx);
}
__ ret(0);
@@ -819,6 +824,7 @@
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, slow);
+#ifndef V8_TARGET_ARCH_X32
// Convert the heap number in rax to an untagged integer in rcx.
IntegerConvert(masm, rax, rax);
@@ -826,6 +832,47 @@
__ notl(rax);
__ Integer32ToSmi(rax, rax);
__ ret(0);
+#else
+ // Convert the heap number in rax to an untagged integer in rcx.
+ IntegerConvert(masm, rcx, rax);
+
+ // Do the bitwise operation and smi tag the result.
+ Label try_float;
+ __ notl(rcx);
+ __ cmpl(rcx, Immediate(0xc0000000));
+ __ j(sign, &try_float, Label::kNear);
+ __ Integer32ToSmi(rax, rcx);
+ __ ret(0);
+
+ // Try to store the result in a heap number.
+ __ bind(&try_float);
+ if (mode_ == UNARY_NO_OVERWRITE) {
+ Label slow_allocate_heapnumber, heapnumber_allocated;
+ __ movl(rbx, rax);
+ __ AllocateHeapNumber(rax, kScratchRegister, &slow_allocate_heapnumber);
+ __ jmp(&heapnumber_allocated);
+
+ __ bind(&slow_allocate_heapnumber);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ // Push the original HeapNumber on the stack. The integer value can't
+ // be stored since it's untagged and not in the smi range (so we can't
+ // smi-tag it). We'll recalculate the value after the GC instead.
+ __ Push(rbx);
+ __ CallRuntime(Runtime::kNumberAlloc, 0);
+ // New HeapNumber is in eax.
+ __ Pop(rbx);
+ }
+ // Recalcuate bit-not value.
+ IntegerConvert(masm, rcx, rbx);
+ __ notl(rcx);
+
+ __ bind(&heapnumber_allocated);
+ }
+ __ cvtlsi2sd(xmm0, rcx);
+ __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
+ __ ret(0);
+#endif
}
@@ -866,9 +913,9 @@
void UnaryOpStub::GenerateGenericCodeFallback(MacroAssembler* masm) {
// Handle the slow case by jumping to the JavaScript builtin.
- __ pop(rcx); // pop return address
+ __k pop(rcx); // pop return address
__ push(rax);
- __ push(rcx); // push return address
+ __k push(rcx); // push return address
switch (op_) {
case Token::SUB:
__ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
@@ -900,13 +947,13 @@
void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
- __ pop(rcx); // Save return address.
+ __k pop(rcx); // Save return address.
__ push(rdx);
__ push(rax);
// Left and right arguments are now on top.
__ Push(Smi::FromInt(MinorKey()));
- __ push(rcx); // Push return address.
+ __k push(rcx); // Push return address.
// Patch the caller to an appropriate specialized stub and return the
// operation result to the caller of the stub.
@@ -930,10 +977,17 @@
// We only generate heapnumber answers for overflowing calculations
// for the four basic arithmetic operations and logical right shift by 0.
+#ifndef V8_TARGET_ARCH_X32
bool generate_inline_heapnumber_results =
(allow_heapnumber_results == BinaryOpStub::ALLOW_HEAPNUMBER_RESULTS) &&
(op == Token::ADD || op == Token::SUB ||
op == Token::MUL || op == Token::DIV || op == Token::SHR);
+#else
+ bool generate_inline_heapnumber_results =
+ (allow_heapnumber_results == BinaryOpStub::ALLOW_HEAPNUMBER_RESULTS) &&
+ (op == Token::ADD || op == Token::SUB || op == Token::SHL ||
+ op == Token::MUL || op == Token::DIV || op == Token::SHR);
+#endif
// Smi check of both operands. If op is BIT_OR, the check is delayed
// until after the OR operation.
@@ -996,7 +1050,12 @@
break;
case Token::SHL:
+#ifndef V8_TARGET_ARCH_X32
__ SmiShiftLeft(left, left, right);
+#else
+ __ movl(kScratchRegister, left);
+ __ SmiShiftLeft(left, left, right, &use_fp_on_smis);
+#endif
__ movq(rax, left);
break;
@@ -1006,6 +1065,9 @@
break;
case Token::SHR:
+#ifdef V8_TARGET_ARCH_X32
+ __ movl(kScratchRegister, left);
+#endif
__ SmiShiftLogicalRight(left, left, right, &use_fp_on_smis);
__ movq(rax, left);
break;
@@ -1031,10 +1093,22 @@
if (generate_inline_heapnumber_results) {
__ AllocateHeapNumber(rcx, rbx, slow);
Comment perform_float(masm, "-- Perform float operation on smis");
+#ifndef V8_TARGET_ARCH_X32
if (op == Token::SHR) {
__ SmiToInteger32(left, left);
__ cvtqsi2sd(xmm0, left);
} else {
+#else
+ if (op == Token::SHL) {
+ __ cvtlsi2sd(xmm0, left);
+ } else if (op == Token::SHR) {
+ // The value of left is from MacroAssembler::SmiShiftLogicalRight
+ // We allow logical shift value:
+ // 0 : might turn a signed integer into unsigned integer
+ // 1 : the value might be above 2^30 - 1
+ __ cvtqsi2sd(xmm0, left);
+ } else {
+#endif
FloatingPointHelper::LoadSSE2SmiOperands(masm);
switch (op) {
case Token::ADD: __ addsd(xmm0, xmm1); break;
@@ -1048,6 +1122,14 @@
__ movq(rax, rcx);
__ ret(0);
} else {
+#ifdef V8_TARGET_ARCH_X32
+ // Restore the orignial left value from kScratchRegister for stub call
+ // KScratchRegister is not killed by MacroAssembler::SmiShiftLogicalRight
+ // and is not killed by MacroAssembler::SmiShiftLeft either.
+ if (op == Token::SHL || op == Token::SHR) {
+ __ movl(left, kScratchRegister);
+ }
+#endif
__ jmp(&fail);
}
}
@@ -1086,6 +1168,11 @@
Label* allocation_failure,
Label* non_numeric_failure,
Token::Value op,
+#ifdef V8_TARGET_ARCH_X32
+ BinaryOpIC::TypeInfo
+ result_type,
+ Label* non_int32_failure,
+#endif
OverwriteMode mode) {
switch (op) {
case Token::ADD:
@@ -1101,6 +1188,18 @@
case Token::DIV: __ divsd(xmm0, xmm1); break;
default: UNREACHABLE();
}
+#ifdef V8_TARGET_ARCH_X32
+ if (non_int32_failure != NULL) {
+ if (result_type <= BinaryOpIC::INT32) {
+ __ cvttsd2si(kScratchRegister, xmm0);
+ __ cvtlsi2sd(xmm2, kScratchRegister);
+ __ pcmpeqd(xmm2, xmm0);
+ __ movmskpd(rcx, xmm2);
+ __ testl(rcx, Immediate(1));
+ __ j(zero, non_int32_failure);
+ }
+ }
+#endif
BinaryOpStub_GenerateHeapResultAllocation(
masm, allocation_failure, mode);
__ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
@@ -1120,6 +1219,9 @@
case Token::SHR: {
Label non_smi_shr_result;
Register heap_number_map = r9;
+#ifdef V8_TARGET_ARCH_X32
+ __ movl(kScratchRegister, rax);
+#endif
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
FloatingPointHelper::LoadAsIntegers(masm, non_numeric_failure,
heap_number_map);
@@ -1131,19 +1233,33 @@
case Token::SHL: __ shll_cl(rax); break;
case Token::SHR: {
__ shrl_cl(rax);
+#ifndef V8_TARGET_ARCH_X32
// Check if result is negative. This can only happen for a shift
// by zero.
__ testl(rax, rax);
__ j(negative, &non_smi_shr_result);
+#endif
break;
}
default: UNREACHABLE();
}
+#ifndef V8_TARGET_ARCH_X32
STATIC_ASSERT(kSmiValueSize == 32);
+#else
+ STATIC_ASSERT(kSmiValueSize == 31);
+ if (op == Token::SHR) {
+ __ testl(rax, Immediate(0xc0000000));
+ __ j(not_zero, &non_smi_shr_result);
+ } else {
+ __ cmpl(rax, Immediate(0xc0000000));
+ __ j(negative, &non_smi_shr_result, Label::kNear);
+ }
+#endif
// Tag smi result and return.
__ Integer32ToSmi(rax, rax);
__ Ret();
+#ifndef V8_TARGET_ARCH_X32
// Logical shift right can produce an unsigned int32 that is not
// an int32, and so is not in the smi range. Allocate a heap number
// in that case.
@@ -1173,6 +1289,37 @@
__ Integer32ToSmi(rdx, rbx);
__ jmp(allocation_failure);
}
+#else
+ __ bind(&non_smi_shr_result);
+ Label allocation_failed;
+ __ movl(rbx, rax); // rbx holds result value (uint32 value as int64).
+ // Allocate heap number in new space.
+ // Not using AllocateHeapNumber macro in order to reuse
+ // already loaded heap_number_map.
+ __ Allocate(HeapNumber::kSize, rax, r8, no_reg, &allocation_failed,
+ TAG_OBJECT);
+ // Set the map.
+ __ AssertRootValue(heap_number_map,
+ Heap::kHeapNumberMapRootIndex,
+ "HeapNumberMap register clobbered.");
+ __ movl(FieldOperand(rax, HeapObject::kMapOffset),
+ heap_number_map);
+ if (op == Token::SHR) {
+ __ cvtqsi2sd(xmm0, rbx);
+ } else {
+ // All other operations returns a signed int32, so we
+ // use lsi2sd here to retain the sign bit.
+ __ cvtlsi2sd(xmm0, rbx);
+ }
+ __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
+ __ Ret();
+
+ __ bind(&allocation_failed);
+ // Restore the right operand from kScratchRegister.
+ // Left operand is in rdx, not changed in this function.
+ __ movl(rax, kScratchRegister);
+ __ jmp(allocation_failure);
+#endif
break;
}
default: UNREACHABLE(); break;
@@ -1189,10 +1336,10 @@
MacroAssembler* masm) {
// Push arguments, but ensure they are under the return address
// for a tail call.
- __ pop(rcx);
+ __k pop(rcx);
__ push(rdx);
__ push(rax);
- __ push(rcx);
+ __k push(rcx);
}
@@ -1268,9 +1415,29 @@
void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
+#ifndef V8_TARGET_ARCH_X32
// The int32 case is identical to the Smi case. We avoid creating this
// ic state on x64.
UNREACHABLE();
+#else
+ ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32);
+
+ Label gc_required, not_number, not_int32;
+ BinaryOpStub_GenerateFloatingPointCode(masm, &gc_required, &not_number,
+ op_, result_type_, &not_int32, mode_);
+
+ __ bind(&not_number);
+ __ bind(&not_int32);
+ GenerateTypeTransition(masm);
+
+ __ bind(&gc_required);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ GenerateRegisterArgsPush(masm);
+ GenerateCallRuntime(masm);
+ }
+ __ Ret();
+#endif
}
@@ -1356,7 +1523,7 @@
__ cvtlsi2sd(xmm1, scratch2);
__ movq(scratch1, xmm0);
__ movq(scratch2, xmm1);
- __ cmpq(scratch1, scratch2);
+ __k cmpq(scratch1, scratch2);
__ j(not_equal, fail);
__ bind(&ok);
}
@@ -1375,8 +1542,13 @@
BinaryOpStub_CheckSmiInput(masm, rax, &not_number);
}
+#ifndef V8_TARGET_ARCH_X32
BinaryOpStub_GenerateFloatingPointCode(
masm, &gc_required, &not_number, op_, mode_);
+#else
+ BinaryOpStub_GenerateFloatingPointCode(
+ masm, &gc_required, &not_number, op_, result_type_, NULL, mode_);
+#endif
__ bind(&not_number);
GenerateTypeTransition(masm);
@@ -1397,8 +1569,14 @@
BinaryOpStub_GenerateSmiCode(
masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS, op_);
+#ifndef V8_TARGET_ARCH_X32
BinaryOpStub_GenerateFloatingPointCode(
masm, &call_runtime, &call_string_add_or_runtime, op_, mode_);
+#else
+ BinaryOpStub_GenerateFloatingPointCode(
+ masm, &call_runtime, &call_string_add_or_runtime, op_,
+ result_type_, NULL, mode_);
+#endif
__ bind(&call_string_add_or_runtime);
if (op_ == Token::ADD) {
@@ -1481,7 +1659,7 @@
if (tagged) {
Label input_not_smi, loaded;
// Test that rax is a number.
- __ movq(rax, Operand(rsp, kPointerSize));
+ __a movq(rax, Operand(rsp, 1 * kPointerSize));
__ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
// Input is a smi. Untag and load it onto the FPU stack.
// Then load the bits of the double into rbx.
@@ -1503,8 +1681,8 @@
// Input is a HeapNumber. Push it on the FPU stack and load its
// bits into rbx.
__ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
- __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
- __ movq(rdx, rbx);
+ __k movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
+ __k movq(rdx, rbx);
__ bind(&loaded);
} else { // UNTAGGED.
@@ -1521,7 +1699,7 @@
// h ^= h >> 8;
// h = h & (cacheSize - 1);
// or h = (h0 ^ (h0 >> 8) ^ (h0 >> 16) ^ (h0 >> 24)) & (cacheSize - 1)
- __ sar(rdx, Immediate(32));
+ __k sar(rdx, Immediate(32));
__ xorl(rdx, rbx);
__ movl(rcx, rdx);
__ movl(rax, rdx);
@@ -1565,12 +1743,18 @@
CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start));
}
#endif
+#ifndef V8_TARGET_ARCH_X32
// Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16].
__ addl(rcx, rcx);
__ lea(rcx, Operand(rax, rcx, times_8, 0));
+#else
+ // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*12].
+ __ leal(rcx, Operand(rcx, rcx, times_2, 0));
+ __ leal(rcx, Operand(rax, rcx, times_4, 0));
+#endif
// Check if cache matches: Double value is stored in uint32_t[2] array.
Label cache_miss;
- __ cmpq(rbx, Operand(rcx, 0));
+ __k cmpq(rbx, Operand(rcx, 0));
__ j(not_equal, &cache_miss, Label::kNear);
// Cache hit!
Counters* counters = masm->isolate()->counters();
@@ -1595,7 +1779,7 @@
__ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
}
GenerateOperation(masm, type_);
- __ movq(Operand(rcx, 0), rbx);
+ __k movq(Operand(rcx, 0), rbx);
__ movq(Operand(rcx, 2 * kIntSize), rax);
__ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
if (tagged) {
@@ -1678,9 +1862,9 @@
Label in_range;
// If argument is outside the range -2^63..2^63, fsin/cos doesn't
// work. We must reduce it to the appropriate range.
- __ movq(rdi, rbx);
+ __k movq(rdi, rbx);
// Move exponent and sign bits to low bits.
- __ shr(rdi, Immediate(HeapNumber::kMantissaBits));
+ __k shr(rdi, Immediate(HeapNumber::kMantissaBits));
// Remove sign bit.
__ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1));
int supported_exponent_limit = (63 + HeapNumber::kExponentBias);
@@ -1693,17 +1877,17 @@
// Input is +/-Infinity or NaN. Result is NaN.
__ fstp(0);
// NaN is represented by 0x7ff8000000000000.
- __ subq(rsp, Immediate(kPointerSize));
+ __ subq(rsp, Immediate(kDoubleSize));
__ movl(Operand(rsp, 4), Immediate(0x7ff80000));
__ movl(Operand(rsp, 0), Immediate(0x00000000));
__ fld_d(Operand(rsp, 0));
- __ addq(rsp, Immediate(kPointerSize));
+ __ addq(rsp, Immediate(kDoubleSize));
__ jmp(&done);
__ bind(&non_nan_result);
// Use fpmod to restrict argument to the range +/-2*PI.
- __ movq(rdi, rax); // Save rax before using fnstsw_ax.
+ __k movq(rdi, rax); // Save rax before using fnstsw_ax.
__ fldpi();
__ fadd(0);
__ fld(1);
@@ -1936,8 +2120,12 @@
// comparing to the original double's bits.
__ cvtlsi2sd(xmm1, smi_result);
__ movq(kScratchRegister, xmm1);
- __ cmpq(scratch2, kScratchRegister);
+ __k cmpq(scratch2, kScratchRegister);
__ j(not_equal, on_not_smis);
+#ifdef V8_TARGET_ARCH_X32
+ __ cmpl(smi_result, Immediate(0xc0000000));
+ __ j(negative, on_not_smis);
+#endif
__ Integer32ToSmi(first, smi_result);
__ bind(&first_done);
@@ -1955,8 +2143,12 @@
__ cvttsd2siq(smi_result, xmm0);
__ cvtlsi2sd(xmm1, smi_result);
__ movq(kScratchRegister, xmm1);
- __ cmpq(scratch2, kScratchRegister);
+ __k cmpq(scratch2, kScratchRegister);
__ j(not_equal, on_not_smis);
+#ifdef V8_TARGET_ARCH_X32
+ __ cmpl(smi_result, Immediate(0xc0000000));
+ __ j(negative, on_not_smis);
+#endif
__ Integer32ToSmi(second, smi_result);
if (on_success != NULL) {
__ jmp(on_success);
@@ -2003,8 +2195,8 @@
// The exponent and base are supplied as arguments on the stack.
// This can only happen if the stub is called from non-optimized code.
// Load input parameters from stack.
- __ movq(base, Operand(rsp, 2 * kPointerSize));
- __ movq(exponent, Operand(rsp, 1 * kPointerSize));
+ __a movq(base, Operand(rsp, 2 * kPointerSize));
+ __a movq(exponent, Operand(rsp, 1 * kPointerSize));
__ JumpIfSmi(base, &base_is_smi, Label::kNear);
__ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
@@ -2347,10 +2539,10 @@
__ JumpIfNotSmi(value, &miss);
// Prepare tail call to StoreIC_ArrayLength.
- __ pop(scratch);
+ __k pop(scratch);
__ push(receiver);
__ push(value);
- __ push(scratch); // return address
+ __k push(scratch); // return address
ExternalReference ref =
ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), masm->isolate());
@@ -2368,7 +2560,11 @@
// The displacement is used for skipping the frame pointer on the
// stack. It is the offset of the last parameter (if any) relative
// to the frame pointer.
+#ifndef V8_TARGET_ARCH_X32
static const int kDisplacement = 1 * kPointerSize;
+#else
+ static const int kDisplacement = 2 * kHWRegSize - 1 * kPointerSize;
+#endif
// Check that the key is a smi.
Label slow;
@@ -2415,9 +2611,9 @@
// Slow-case: Handle non-smi or out-of-bounds access to arguments
// by calling the runtime system.
__ bind(&slow);
- __ pop(rbx); // Return address.
+ __k pop(rbx); // Return address.
__ push(rdx);
- __ push(rbx);
+ __k push(rbx);
__ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
}
@@ -2434,7 +2630,7 @@
Factory* factory = masm->isolate()->factory();
- __ SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize));
+ __a SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize));
// rbx = parameter count (untagged)
// Check if the calling frame is an arguments adaptor frame.
@@ -2456,7 +2652,7 @@
ArgumentsAdaptorFrameConstants::kLengthOffset));
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __a movq(Operand(rsp, 2 * kPointerSize), rdx);
// rbx = parameter count (untagged)
// rcx = argument count (untagged)
@@ -2517,7 +2713,7 @@
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
- __ movq(rdx, Operand(rsp, 3 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 3 * kPointerSize));
__ movq(FieldOperand(rax, JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize),
rdx);
@@ -2568,7 +2764,7 @@
// Load tagged parameter count into r9.
__ Integer32ToSmi(r9, rbx);
__ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
- __ addq(r8, Operand(rsp, 1 * kPointerSize));
+ __a addq(r8, Operand(rsp, 1 * kPointerSize));
__ subq(r8, r9);
__ Move(r11, factory->the_hole_value());
__ movq(rdx, rdi);
@@ -2607,7 +2803,7 @@
Label arguments_loop, arguments_test;
__ movq(r8, rbx);
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 2 * kPointerSize));
// Untag rcx for the loop below.
__ SmiToInteger64(rcx, rcx);
__ lea(kScratchRegister, Operand(r8, times_pointer_size, 0));
@@ -2634,7 +2830,7 @@
// rcx = argument count (untagged)
__ bind(&runtime);
__ Integer32ToSmi(rcx, rcx);
- __ movq(Operand(rsp, 1 * kPointerSize), rcx); // Patch argument count.
+ __a movq(Operand(rsp, 1 * kPointerSize), rcx); // Patch argument count.
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
}
@@ -2654,11 +2850,11 @@
// Patch the arguments.length and the parameters pointer.
__ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+ __a movq(Operand(rsp, 1 * kPointerSize), rcx);
__ SmiToInteger64(rcx, rcx);
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __a movq(Operand(rsp, 2 * kPointerSize), rdx);
__ bind(&runtime);
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
@@ -2679,18 +2875,18 @@
__ j(equal, &adaptor_frame);
// Get the length from the frame.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
__ SmiToInteger64(rcx, rcx);
__ jmp(&try_allocate);
// Patch the arguments.length and the parameters pointer.
__ bind(&adaptor_frame);
__ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+ __a movq(Operand(rsp, 1 * kPointerSize), rcx);
__ SmiToInteger64(rcx, rcx);
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __a movq(Operand(rsp, 2 * kPointerSize), rdx);
// Try the new space allocation. Start out with computing the size of
// the arguments object and the elements array.
@@ -2720,7 +2916,7 @@
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
__ movq(FieldOperand(rax, JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize),
rcx);
@@ -2731,7 +2927,7 @@
__ j(zero, &done);
// Get the parameters pointer from the stack.
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 2 * kPointerSize));
// Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
@@ -2780,10 +2976,17 @@
// rsp[24] : subject string
// rsp[32] : JSRegExp object
+#ifndef V8_TARGET_ARCH_X32
static const int kLastMatchInfoOffset = 1 * kPointerSize;
static const int kPreviousIndexOffset = 2 * kPointerSize;
static const int kSubjectOffset = 3 * kPointerSize;
static const int kJSRegExpOffset = 4 * kPointerSize;
+#else
+ static const int kLastMatchInfoOffset = 1 * kHWRegSize;
+ static const int kPreviousIndexOffset = 1 * kHWRegSize + 1 * kPointerSize;
+ static const int kSubjectOffset = 1 * kHWRegSize + 2 * kPointerSize;
+ static const int kJSRegExpOffset = 1 * kHWRegSize + 3 * kPointerSize;
+#endif
Label runtime;
// Ensure that a RegExp stack is allocated.
@@ -2955,11 +3158,11 @@
// Argument 9: Pass current isolate address.
__ LoadAddress(kScratchRegister,
ExternalReference::isolate_address(masm->isolate()));
- __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
+ __s movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
kScratchRegister);
// Argument 8: Indicate that this is a direct call from JavaScript.
- __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
+ __s movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
Immediate(1));
// Argument 7: Start (high end) of backtracking stack memory area.
@@ -2967,13 +3170,13 @@
__ movq(r9, Operand(kScratchRegister, 0));
__ movq(kScratchRegister, address_of_regexp_stack_memory_size);
__ addq(r9, Operand(kScratchRegister, 0));
- __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
+ __s movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
// Argument 6: Set the number of capture registers to zero to force global
// regexps to behave as non-global. This does not affect non-global regexps.
// Argument 6 is passed in r9 on Linux and on the stack on Windows.
#ifdef _WIN64
- __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize),
+ __s movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize),
Immediate(0));
#else
__ Set(r9, 0);
@@ -2984,7 +3187,7 @@
ExternalReference::address_of_static_offsets_vector(isolate));
// Argument 5 passed in r8 on Linux and on the stack on Windows.
#ifdef _WIN64
- __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kPointerSize), r8);
+ __s movq(Operand(rsp, (argument_slots_on_stack - 5) * kPointerSize), r8);
#endif
// rdi: subject string
@@ -3214,7 +3417,7 @@
const int kMaxInlineLength = 100;
Label slowcase;
Label done;
- __ movq(r8, Operand(rsp, kPointerSize * 3));
+ __a movq(r8, Operand(rsp, 3 * kPointerSize));
__ JumpIfNotSmi(r8, &slowcase);
__ SmiToInteger32(rbx, r8);
__ cmpl(rbx, Immediate(kMaxInlineLength));
@@ -3252,11 +3455,11 @@
__ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
// Set input, index and length fields from arguments.
- __ movq(r8, Operand(rsp, kPointerSize * 1));
+ __a movq(r8, Operand(rsp, 1 * kPointerSize));
__ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8);
- __ movq(r8, Operand(rsp, kPointerSize * 2));
+ __a movq(r8, Operand(rsp, 2 * kPointerSize));
__ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8);
- __ movq(r8, Operand(rsp, kPointerSize * 3));
+ __a movq(r8, Operand(rsp, 3 * kPointerSize));
__ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
// Fill out the elements FixedArray.
@@ -3391,7 +3594,7 @@
void NumberToStringStub::Generate(MacroAssembler* masm) {
Label runtime;
- __ movq(rbx, Operand(rsp, kPointerSize));
+ __a movq(rbx, Operand(rsp, 1 * kPointerSize));
// Generate code to lookup number in the number string cache.
GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
@@ -3682,7 +3885,7 @@
}
// Push arguments below the return address to prepare jump to builtin.
- __ pop(rcx);
+ __k pop(rcx);
__ push(rdx);
__ push(rax);
@@ -3696,7 +3899,7 @@
}
// Restore return address on the stack.
- __ push(rcx);
+ __k push(rcx);
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
// tagged as a small integer.
@@ -3806,14 +4009,14 @@
Label call;
// Get the receiver from the stack.
// +1 ~ return address
- __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
+ __a movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
// Call as function is indicated with the hole.
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &call, Label::kNear);
// Patch the receiver on the stack with the global receiver object.
__ movq(rcx, GlobalObjectOperand());
__ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
+ __a movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
__ bind(&call);
}
@@ -3859,9 +4062,9 @@
// Check for function proxy.
__ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
__ j(not_equal, &non_function);
- __ pop(rcx);
+ __k pop(rcx);
__ push(rdi); // put proxy as additional argument under return address
- __ push(rcx);
+ __k push(rcx);
__ Set(rax, argc_ + 1);
__ Set(rbx, 0);
__ SetCallKind(rcx, CALL_AS_METHOD);
@@ -3875,7 +4078,7 @@
// CALL_NON_FUNCTION expects the non-function callee as receiver (instead
// of the original receiver from the call site).
__ bind(&non_function);
- __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
+ __a movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
__ Set(rax, argc_);
__ Set(rbx, 0);
__ SetCallKind(rcx, CALL_AS_METHOD);
@@ -4067,8 +4270,8 @@
// Read result values stored on stack. Result is stored
// above the four argument mirror slots and the two
// Arguments object slots.
- __ movq(rax, Operand(rsp, 6 * kPointerSize));
- __ movq(rdx, Operand(rsp, 7 * kPointerSize));
+ __s movq(rax, Operand(rsp, 6 * kPointerSize));
+ __s movq(rdx, Operand(rsp, 7 * kPointerSize));
}
#endif
__ lea(rcx, Operand(rax, 1));
@@ -4177,7 +4380,7 @@
// Do full GC and retry runtime call one final time.
Failure* failure = Failure::InternalError();
- __ movq(rax, failure, RelocInfo::NONE64);
+ __n movq(rax, failure, RelocInfo::NONE64);
GenerateCore(masm,
&throw_normal_exception,
&throw_termination_exception,
@@ -4198,7 +4401,7 @@
isolate);
Label already_have_failure;
JumpIfOOM(masm, rax, kScratchRegister, &already_have_failure);
- __ movq(rax, Failure::OutOfMemoryException(0x1), RelocInfo::NONE64);
+ __n movq(rax, Failure::OutOfMemoryException(0x1), RelocInfo::NONE64);
__ bind(&already_have_failure);
__ Store(pending_exception, rax);
// Fall through to the next label.
@@ -4228,21 +4431,27 @@
// Scratch register is neither callee-save, nor an argument register on any
// platform. It's free to use at this point.
// Cannot use smi-register for loading yet.
+#ifndef V8_TARGET_ARCH_X32
__ movq(kScratchRegister,
reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
RelocInfo::NONE64);
+#else
+ __ movl(kScratchRegister,
+ reinterpret_cast<uint32_t>(Smi::FromInt(marker)),
+ RelocInfo::NONE32);
+#endif
__ push(kScratchRegister); // context slot
__ push(kScratchRegister); // function slot
// Save callee-saved registers (X64/Win64 calling conventions).
- __ push(r12);
- __ push(r13);
- __ push(r14);
- __ push(r15);
+ __k push(r12);
+ __k push(r13);
+ __k push(r14);
+ __k push(r15);
#ifdef _WIN64
- __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
- __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
+ __k push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
+ __k push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
#endif
- __ push(rbx);
+ __k push(rbx);
#ifdef _WIN64
// On Win64 XMM6-XMM15 are callee-save
@@ -4298,7 +4507,7 @@
ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
isolate);
__ Store(pending_exception, rax);
- __ movq(rax, Failure::Exception(), RelocInfo::NONE64);
+ __n movq(rax, Failure::Exception(), RelocInfo::NONE64);
__ jmp(&exit);
// Invoke: Link this frame into the handler chain. There's only one
@@ -4362,16 +4571,16 @@
__ addq(rsp, Immediate(EntryFrameConstants::kXMMRegistersBlockSize));
#endif
- __ pop(rbx);
+ __k pop(rbx);
#ifdef _WIN64
// Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI.
- __ pop(rsi);
- __ pop(rdi);
+ __k pop(rsi);
+ __k pop(rdi);
#endif
- __ pop(r15);
- __ pop(r14);
- __ pop(r13);
- __ pop(r12);
+ __k pop(r15);
+ __k pop(r14);
+ __k pop(r13);
+ __k pop(r12);
__ addq(rsp, Immediate(2 * kPointerSize)); // remove markers
// Restore frame pointer and return.
@@ -4396,6 +4605,7 @@
// indicate that the value is not an instance.
static const int kOffsetToMapCheckValue = 2;
+#ifndef V8_TARGET_ARCH_X32
static const int kOffsetToResultValue = 18;
// The last 4 bytes of the instruction sequence
// movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
@@ -4407,6 +4617,19 @@
// __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
// before the offset of the hole value in the root array.
static const unsigned int kWordBeforeResultValue = 0x458B4909;
+#else
+ static const int kOffsetToResultValue = 14;
+ // The last 4 bytes of the instruction sequence
+ // movl(rdi, FieldOperand(rax, HeapObject::kMapOffset))
+ // Move(kScratchRegister, Factory::the_hole_value())
+ // in front of the hole value address.
+ static const unsigned int kWordBeforeMapCheckValue = 0xBA41FF78;
+ // The last 4 bytes of the instruction sequence
+ // __ j(not_equal, &cache_miss);
+ // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
+ // before the offset of the hole value in the root array.
+ static const unsigned int kWordBeforeResultValue = 0x458B4109;
+#endif
// Only the inline check flag is supported on X64.
ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0;
@@ -4414,7 +4637,12 @@
// Get the object - go slow case if it's a smi.
Label slow;
+#ifndef V8_TARGET_ARCH_X32
__ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
+#else
+ __ movl(rax, Operand(rsp, 1 * kHWRegSize + 1 * kPointerSize +
+ extra_stack_space));
+#endif
__ JumpIfSmi(rax, &slow);
// Check that the left hand is a JS object. Leave its map in rax.
@@ -4424,7 +4652,7 @@
__ j(above, &slow);
// Get the prototype of the function.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
+ __a movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
// rdx is function, rax is map.
// If there is a call site cache don't look in the global cache, but do the
@@ -4459,8 +4687,8 @@
__ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
} else {
// Get return address and delta to inlined map check.
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __q movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
+ __a subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
if (FLAG_debug_code) {
__ movl(rdi, Immediate(kWordBeforeMapCheckValue));
__ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
@@ -4500,8 +4728,8 @@
// Assert it is a 1-byte signed value.
ASSERT(true_offset >= 0 && true_offset < 0x100);
__ movl(rax, Immediate(true_offset));
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __q movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
+ __a subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
__ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
if (FLAG_debug_code) {
__ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4523,8 +4751,8 @@
// Assert it is a 1-byte signed value.
ASSERT(false_offset >= 0 && false_offset < 0x100);
__ movl(rax, Immediate(false_offset));
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __q movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
+ __a subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
__ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
if (FLAG_debug_code) {
__ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4538,9 +4766,9 @@
__ bind(&slow);
if (HasCallSiteInlineCheck()) {
// Remove extra value from the stack.
- __ pop(rcx);
+ __k pop(rcx);
__ pop(rax);
- __ push(rcx);
+ __k push(rcx);
}
__ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
}
@@ -4690,8 +4918,10 @@
Builtins::JavaScript builtin_id = Builtins::ADD;
// Load the two arguments.
- __ movq(rax, Operand(rsp, 2 * kPointerSize)); // First argument (left).
- __ movq(rdx, Operand(rsp, 1 * kPointerSize)); // Second argument (right).
+ // First argument (left).
+ __a movq(rax, Operand(rsp, 2 * kPointerSize));
+ // Second argument (right).
+ __a movq(rdx, Operand(rsp, 1 * kPointerSize));
// Make sure that both arguments are strings if not known in advance.
if ((flags_ & NO_STRING_ADD_FLAGS) != 0) {
@@ -4708,13 +4938,23 @@
// We convert the one that is not known to be a string.
if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
+#ifndef V8_TARGET_ARCH_X32
GenerateConvertArgument(masm, 2 * kPointerSize, rax, rbx, rcx, rdi,
&call_builtin);
+#else
+ GenerateConvertArgument(masm, 1 * kHWRegSize + 1 * kPointerSize, rax,
+ rbx, rcx, rdi, &call_builtin);
+#endif
builtin_id = Builtins::STRING_ADD_RIGHT;
} else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
+#ifndef V8_TARGET_ARCH_X32
GenerateConvertArgument(masm, 1 * kPointerSize, rdx, rbx, rcx, rdi,
&call_builtin);
+#else
+ GenerateConvertArgument(masm, 1 * kHWRegSize, rdx, rbx, rcx, rdi,
+ &call_builtin);
+#endif
builtin_id = Builtins::STRING_ADD_LEFT;
}
}
@@ -4761,8 +5001,12 @@
__ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
// Look at the length of the result of adding the two strings.
+#ifndef V8_TARGET_ARCH_X32
STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
__ SmiAdd(rbx, rbx, rcx);
+#else
+ __ SmiAdd(rbx, rbx, rcx, &call_runtime);
+#endif
// Use the string table when adding two one character strings, as it
// helps later optimizations to return an internalized string here.
__ SmiCompare(rbx, Smi::FromInt(2));
@@ -5011,10 +5255,10 @@
void StringAddStub::GenerateRegisterArgsPop(MacroAssembler* masm,
Register temp) {
- __ pop(temp);
+ __k pop(temp);
__ pop(rdx);
__ pop(rax);
- __ push(temp);
+ __k push(temp);
}
@@ -5117,7 +5361,8 @@
// Copy from edi to esi using rep movs instruction.
__ movl(kScratchRegister, count);
- __ shr(count, Immediate(kPointerSizeLog2)); // Number of doublewords to copy.
+ // Number of doublewords to copy.
+ __ shr(count, Immediate(kPointerSizeLog2));
__ repmovsq();
// Find number of bytes left.
@@ -5337,7 +5582,11 @@
// rsp[16] : from
// rsp[24] : string
+#ifndef V8_TARGET_ARCH_X32
const int kToOffset = 1 * kPointerSize;
+#else
+ const int kToOffset = 1 * kHWRegSize;
+#endif
const int kFromOffset = kToOffset + kPointerSize;
const int kStringOffset = kFromOffset + kPointerSize;
const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
@@ -5676,7 +5925,7 @@
FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize));
__ lea(right,
FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize));
- __ neg(length);
+ __k neg(length);
Register index = length; // index = -length;
// Compare loop.
@@ -5685,7 +5934,7 @@
__ movb(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0));
__ j(not_equal, chars_not_equal, near_jump);
- __ incq(index);
+ __k incq(index);
__ j(not_zero, &loop);
}
@@ -5698,8 +5947,8 @@
// rsp[8] : right string
// rsp[16] : left string
- __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left
- __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right
+ __a movq(rdx, Operand(rsp, 2 * kPointerSize)); // left
+ __a movq(rax, Operand(rsp, 1 * kPointerSize)); // right
// Check for identity.
Label not_same;
@@ -5718,9 +5967,9 @@
// Inline comparison of ASCII strings.
__ IncrementCounter(counters->string_compare_native(), 1);
// Drop arguments from the stack
- __ pop(rcx);
+ __k pop(rcx);
__ addq(rsp, Immediate(2 * kPointerSize));
- __ push(rcx);
+ __k push(rcx);
GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8);
// Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
@@ -5994,10 +6243,10 @@
// Handle more complex cases in runtime.
__ bind(&runtime);
- __ pop(tmp1); // Return address.
+ __k pop(tmp1); // Return address.
__ push(left);
__ push(right);
- __ push(tmp1);
+ __k push(tmp1);
if (equality) {
__ TailCallRuntime(Runtime::kStringEquals, 2, 1);
} else {
@@ -6219,7 +6468,7 @@
// (their names are the null value).
for (int i = kInlinedProbes; i < kTotalProbes; i++) {
// Compute the masked index: (hash + i + i * i) & mask.
- __ movq(scratch, Operand(rsp, 2 * kPointerSize));
+ __a movq(scratch, Operand(rsp, 2 * kPointerSize));
if (i > 0) {
__ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
}
@@ -6239,7 +6488,7 @@
__ j(equal, &not_in_dictionary);
// Stop if found the property.
- __ cmpq(scratch, Operand(rsp, 3 * kPointerSize));
+ __a cmpq(scratch, Operand(rsp, 3 * kPointerSize));
__ j(equal, &in_dictionary);
if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
@@ -6591,8 +6840,8 @@
Label fast_elements;
// Get array literal index, array literal and its map.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
- __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+ __a movq(rdx, Operand(rsp, 1 * kPointerSize));
+ __a movq(rbx, Operand(rsp, 2 * kPointerSize));
__ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
__ CheckFastElements(rdi, &double_elements);
@@ -6605,7 +6854,7 @@
// the runtime.
__ bind(&slow_elements);
- __ pop(rdi); // Pop return address and remember to put back later for tail
+ __k pop(rdi); // Pop return address and remember to put back later for tail
// call.
__ push(rbx);
__ push(rcx);
@@ -6613,7 +6862,7 @@
__ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
__ push(rdx);
- __ push(rdi); // Return return address so that tail call returns to right
+ __k push(rdi); // Return return address so that tail call returns to right
// place.
__ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
@@ -6661,7 +6910,7 @@
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ movq(rbx, MemOperand(rbp, parameter_count_offset));
masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
- __ pop(rcx);
+ __k pop(rcx);
int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE
? kPointerSize
: 0;
@@ -6686,14 +6935,14 @@
// This stub can be called from essentially anywhere, so it needs to save
// all volatile and callee-save registers.
const size_t kNumSavedRegisters = 2;
- __ push(arg_reg_1);
- __ push(arg_reg_2);
+ __k push(arg_reg_1);
+ __k push(arg_reg_2);
// Calculate the original stack pointer and store it in the second arg.
- __ lea(arg_reg_2, Operand(rsp, (kNumSavedRegisters + 1) * kPointerSize));
+ __q lea(arg_reg_2, Operand(rsp, (kNumSavedRegisters + 1) * kPointerSize));
// Calculate the function address to the first arg.
- __ movq(arg_reg_1, Operand(rsp, kNumSavedRegisters * kPointerSize));
+ __s movq(arg_reg_1, Operand(rsp, kNumSavedRegisters * kPointerSize));
__ subq(arg_reg_1, Immediate(Assembler::kShortCallInstructionLength));
// Save the remainder of the volatile registers.
@@ -6701,7 +6950,11 @@
// Call the entry hook function.
__ movq(rax, FUNCTION_ADDR(masm->isolate()->function_entry_hook()),
+#ifndef V8_TARGET_ARCH_X32
RelocInfo::NONE64);
+#else
+ RelocInfo::NONE32);
+#endif
AllowExternalCallThatCantCauseGC scope(masm);
@@ -6711,9 +6964,8 @@
// Restore volatile regs.
masm->PopCallerSaved(kSaveFPRegs, arg_reg_1, arg_reg_2);
- __ pop(arg_reg_2);
- __ pop(arg_reg_1);
-
+ __k pop(arg_reg_2);
+ __k pop(arg_reg_1);
__ Ret();
}
@@ -6761,7 +7013,7 @@
__ j(not_zero, &normal_sequence);
// look at the first argument
- __ movq(rcx, Operand(rsp, kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
__ testq(rcx, rcx);
__ j(zero, &normal_sequence);
@@ -6928,7 +7180,7 @@
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
- __ movq(rcx, Operand(rsp, kPointerSize));
+ __a movq(rcx, Operand(rsp, 1 * kPointerSize));
__ testq(rcx, rcx);
__ j(zero, &normal_sequence);
@@ -6999,7 +7251,11 @@
GenerateCase(masm, FAST_ELEMENTS);
}
-
+#undef __n
+#undef __s
+#undef __q
+#undef __a
+#undef __k
#undef __
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698