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

Unified Diff: src/x64/lithium-codegen-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/lithium-codegen-x64.cc
===================================================================
--- src/x64/lithium-codegen-x64.cc (revision 15486)
+++ src/x64/lithium-codegen-x64.cc (working copy)
@@ -65,7 +65,11 @@
#define __ masm()->
+#define __k __
+#define __q __
+#define __n __
+
bool LCodeGen::GenerateCode() {
LPhase phase("Z_Code generation", chunk());
ASSERT(is_unused());
@@ -141,8 +145,13 @@
Label ok;
__ testq(rcx, rcx);
__ j(zero, &ok, Label::kNear);
+#ifndef V8_TARGET_ARCH_X32
// +1 for return address.
int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
+#else
+ int receiver_offset = 1 * kHWRegSize +
+ scope()->num_parameters() * kPointerSize;
+#endif
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
__ movq(Operand(rsp, receiver_offset), kScratchRegister);
__ bind(&ok);
@@ -171,7 +180,7 @@
__ subq(rsp, Immediate(slots * kPointerSize));
__ push(rax);
__ Set(rax, slots);
- __ movq(kScratchRegister, kSlotsZapValue, RelocInfo::NONE64);
+ __n movq(kScratchRegister, kSlotsZapValue, RelocInfo::NONE64);
Label loop;
__ bind(&loop);
__ movq(MemOperand(rsp, rax, times_pointer_size, 0),
@@ -1131,11 +1140,11 @@
int32_t power = WhichPowerOf2(divisor_abs);
if (divisor < 0) {
__ movsxlq(result, dividend);
- __ neg(result);
+ __k neg(result);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(zero, instr->environment());
}
- __ sar(result, Immediate(power));
+ __k sar(result, Immediate(power));
} else {
if (!result.is(dividend)) {
__ movl(result, dividend);
@@ -1164,15 +1173,15 @@
__ movsxlq(reg1, dividend);
if (divisor < 0 &&
instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ neg(reg1);
+ __k neg(reg1);
DeoptimizeIf(zero, instr->environment());
}
- __ movq(reg2, multiplier, RelocInfo::NONE64);
+ __n movq(reg2, multiplier, RelocInfo::NONE64);
// Result just fit in r64, because it's int32 * uint32.
- __ imul(reg2, reg1);
+ __k imul(reg2, reg1);
- __ addq(reg2, Immediate(1 << 30));
- __ sar(reg2, Immediate(shift));
+ __k addq(reg2, Immediate(1 << 30));
+ __k sar(reg2, Immediate(shift));
}
}
@@ -1536,7 +1545,7 @@
} else {
Register tmp = ToRegister(instr->temp());
__ Set(tmp, int_val);
- __ movq(res, tmp);
+ __k movq(res, tmp);
}
}
@@ -1624,7 +1633,7 @@
__ bind(&runtime);
__ PrepareCallCFunction(2);
__ movq(arg_reg_1, object);
- __ movq(arg_reg_2, index, RelocInfo::NONE64);
+ __n movq(arg_reg_2, index, RelocInfo::NONE64);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ bind(&done);
@@ -2449,7 +2458,12 @@
__ push(ToRegister(instr->value()));
__ PushHeapObject(instr->function());
+#ifndef V8_TARGET_ARCH_X32
static const int kAdditionalDelta = 10;
+#else
+ // Actual size for X32.
+ static const int kAdditionalDelta = 16;
+#endif
int delta =
masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
ASSERT(delta >= 0);
@@ -2542,7 +2556,7 @@
// The argument count parameter is a smi
__ SmiToInteger32(reg, reg);
Register return_addr_reg = reg.is(rcx) ? rbx : rcx;
- __ pop(return_addr_reg);
+ __k pop(return_addr_reg);
__ shl(reg, Immediate(kPointerSizeLog2));
__ addq(rsp, reg);
__ jmp(return_addr_reg);
@@ -2865,7 +2879,12 @@
int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
int index = (const_length - const_index) + 1;
+#ifndef V8_TARGET_ARCH_X32
__ movq(result, Operand(arguments, index * kPointerSize));
+#else
+ __ movl(result, Operand(arguments, index * kPointerSize +
+ 2 * kHWRegSize - 2 * kPointerSize));
+#endif
} else {
Register length = ToRegister(instr->length());
// There are two words between the frame pointer and the last argument.
@@ -2875,8 +2894,15 @@
} else {
__ subl(length, ToOperand(instr->index()));
}
+#ifndef V8_TARGET_ARCH_X32
__ movq(result,
Operand(arguments, length, times_pointer_size, kPointerSize));
+#else
+ // PC and FP are with kHWRegSize.
+ __ movl(result,
+ Operand(arguments, length, times_pointer_size,
+ 2 * kHWRegSize - 1 *kPointerSize));
+#endif
}
}
@@ -2896,7 +2922,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
Operand operand(BuildFastArrayOperand(
@@ -2969,7 +2995,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
@@ -3011,7 +3037,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
@@ -3086,7 +3112,7 @@
Register result = ToRegister(instr->result());
if (instr->hydrogen()->from_inlined()) {
- __ lea(result, Operand(rsp, -2 * kPointerSize));
+ __q lea(result, Operand(rsp, -2 * kPointerSize));
} else {
// Check for arguments adapter frame.
Label done, adapted;
@@ -3208,7 +3234,12 @@
__ testl(length, length);
__ j(zero, &invoke, Label::kNear);
__ bind(&loop);
+#ifndef V8_TARGET_ARCH_X32
__ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
+#else
+ __ Push(Operand(elements, length, times_pointer_size,
+ 2 * kHWRegSize - 1 * kPointerSize));
+#endif
__ decl(length);
__ j(not_zero, &loop);
@@ -3311,7 +3342,11 @@
if (function.is_identical_to(info()->closure())) {
__ CallSelf();
} else {
+#ifndef V8_TARGET_ARCH_X32
__ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
+#else
+ __ Call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
+#endif
}
// Set up deoptimization.
@@ -3384,10 +3419,10 @@
__ LoadFromSafepointRegisterSlot(input_reg, input_reg);
__ bind(&allocated);
- __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
- __ shl(tmp2, Immediate(1));
- __ shr(tmp2, Immediate(1));
- __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
+ __k movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __k shl(tmp2, Immediate(1));
+ __k shr(tmp2, Immediate(1));
+ __k movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
__ StoreToSafepointRegisterSlot(input_reg, tmp);
__ bind(&done);
@@ -3453,8 +3488,8 @@
CpuFeatureScope scope(masm(), SSE4_1);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Deoptimize if minus zero.
- __ movq(output_reg, input_reg);
- __ subq(output_reg, Immediate(1));
+ __k movq(output_reg, input_reg);
+ __k subq(output_reg, Immediate(1));
DeoptimizeIf(overflow, instr->environment());
}
__ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
@@ -3474,7 +3509,7 @@
Label positive_sign;
__ j(above, &positive_sign, Label::kNear);
__ movmskpd(output_reg, input_reg);
- __ testq(output_reg, Immediate(1));
+ __k testq(output_reg, Immediate(1));
DeoptimizeIf(not_zero, instr->environment());
__ Set(output_reg, 0);
__ jmp(&done);
@@ -3511,7 +3546,7 @@
static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5
Label done, round_to_zero, below_one_half, do_not_compensate, restore;
- __ movq(kScratchRegister, one_half, RelocInfo::NONE64);
+ __k movq(kScratchRegister, one_half, RelocInfo::NONE64);
__ movq(xmm_scratch, kScratchRegister);
__ ucomisd(xmm_scratch, input_reg);
__ j(above, &below_one_half);
@@ -3526,14 +3561,14 @@
__ jmp(&done);
__ bind(&below_one_half);
- __ movq(kScratchRegister, minus_one_half, RelocInfo::NONE64);
+ __k movq(kScratchRegister, minus_one_half, RelocInfo::NONE64);
__ movq(xmm_scratch, kScratchRegister);
__ ucomisd(xmm_scratch, input_reg);
__ j(below_equal, &round_to_zero);
// CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
// compare and compensate.
- __ movq(kScratchRegister, input_reg); // Back up input_reg.
+ __k movq(kScratchRegister, input_reg); // Back up input_reg.
__ subsd(input_reg, xmm_scratch);
__ cvttsd2si(output_reg, input_reg);
// Catch minint due to overflow, and to prevent overflow when compensating.
@@ -3547,15 +3582,15 @@
__ subl(output_reg, Immediate(1));
// No overflow because we already ruled out minint.
__ bind(&restore);
- __ movq(input_reg, kScratchRegister); // Restore input_reg.
+ __k movq(input_reg, kScratchRegister); // Restore input_reg.
__ jmp(&done);
__ bind(&round_to_zero);
// We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
// we can ignore the difference between a result of -0 and +0.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ movq(output_reg, input_reg);
- __ testq(output_reg, output_reg);
+ __k movq(output_reg, input_reg);
+ __k testq(output_reg, output_reg);
__ RecordComment("Minus zero");
DeoptimizeIf(negative, instr->environment());
}
@@ -3666,7 +3701,9 @@
#endif
static const int kSeedSize = sizeof(uint32_t);
+#ifndef V8_TARGET_ARCH_X32
STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
+#endif
__ movq(global_object,
FieldOperand(global_object, GlobalObject::kNativeContextOffset));
@@ -4084,7 +4121,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
Operand operand(BuildFastArrayOperand(
@@ -4148,7 +4185,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
@@ -4160,7 +4197,7 @@
__ Set(kScratchRegister, BitCast<uint64_t>(
FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
- __ movq(value, kScratchRegister);
+ __k movq(value, kScratchRegister);
__ bind(&have_value);
}
@@ -4191,7 +4228,7 @@
} else if (instr->hydrogen()->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
- __ movsxlq(key_reg, key_reg);
+ __k movsxlq(key_reg, key_reg);
}
}
@@ -4402,7 +4439,7 @@
__ cmpl(char_code, Immediate(String::kMaxOneByteCharCode));
__ j(above, deferred->entry());
- __ movsxlq(char_code, char_code);
+ __k movsxlq(char_code, char_code);
__ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
__ movq(result, FieldOperand(result,
char_code, times_pointer_size,
@@ -4474,14 +4511,79 @@
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
+#ifndef V8_TARGET_ARCH_X32
LOperand* input = instr->value();
ASSERT(input->IsRegister() && input->Equals(instr->result()));
Register reg = ToRegister(input);
__ Integer32ToSmi(reg, reg);
+#else
+ class DeferredNumberTagI: public LDeferredCode {
+ public:
+ DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredNumberTagI(instr_);
+ }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LNumberTagI* instr_;
+ };
+
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister() && input->Equals(instr->result()));
+ Register reg = ToRegister(input);
+
+ DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
+ __ Integer32ToSmi(reg, reg);
+ __ j(overflow, deferred->entry());
+ __ bind(deferred->exit());
+#endif
}
+#ifdef V8_TARGET_ARCH_X32
+void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
+ Label slow;
+ Register reg = ToRegister(instr->value());
+ Register tmp = reg.is(rax) ? kScratchRegister : rax;
+
+ // Preserve the value of all registers.
+ PushSafepointRegistersScope scope(this);
+
+ Label done;
+ // There was overflow, so bits 30 and 31 of the original integer
+ // disagree. Try to allocate a heap number in new space and store
+ // the value in there. If that fails, call the runtime system.
+ __ SmiToInteger32(reg, reg);
+ __ xorl(reg, Immediate(0x80000000));
+ __ cvtlsi2sd(xmm0, reg);
+
+ if (FLAG_inline_new) {
+ __ AllocateHeapNumber(reg, tmp, &slow);
+ __ jmp(&done, Label::kNear);
+ }
+
+ // Slow case: Call the runtime system to do the number allocation.
+ __ bind(&slow);
+
+ // Put a valid pointer value in the stack slot where the result
+ // register is stored, as this register is in the pointer map, but contains an
+ // integer value.
+ __ StoreToSafepointRegisterSlot(reg, Immediate(0));
+ CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
+ // Set the pointer to the new heap number in tmp.
+ if (!reg.is(rax)) __ movl(reg, rax);
+
+ // Heap number allocated. Put the value in xmm0 into the value of the
+ // allocated heap number.
+ __ bind(&done);
+ __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
+ __ StoreToSafepointRegisterSlot(reg, reg);
+}
+#endif
+
+
void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
class DeferredNumberTagU: public LDeferredCode {
public:
@@ -4586,7 +4688,7 @@
__ addq(rsp, Immediate(kDoubleSize));
__ Set(kScratchRegister, BitCast<uint64_t>(
FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
- __ movq(input_reg, kScratchRegister);
+ __k movq(input_reg, kScratchRegister);
}
__ bind(&no_special_nan_handling);
@@ -4687,7 +4789,7 @@
__ ucomisd(xmm_scratch, result_reg);
__ j(not_equal, &done, Label::kNear);
__ movmskpd(kScratchRegister, result_reg);
- __ testq(kScratchRegister, Immediate(1));
+ __k testq(kScratchRegister, Immediate(1));
DeoptimizeIf(not_zero, env);
}
__ jmp(&done, Label::kNear);
@@ -4725,7 +4827,7 @@
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2siq(input_reg, xmm0);
__ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
- __ cmpq(input_reg, kScratchRegister);
+ __k cmpq(input_reg, kScratchRegister);
DeoptimizeIf(equal, instr->environment());
} else {
// Deoptimize if we don't have a heap number.
@@ -4814,10 +4916,10 @@
// Performs a truncating conversion of a floating point number as used by
// the JS bitwise operations.
__ cvttsd2siq(result_reg, input_reg);
- __ movq(kScratchRegister,
+ __k movq(kScratchRegister,
V8_INT64_C(0x8000000000000000),
RelocInfo::NONE64);
- __ cmpq(result_reg, kScratchRegister);
+ __k cmpq(result_reg, kScratchRegister);
DeoptimizeIf(equal, instr->environment());
} else {
__ cvttsd2si(result_reg, input_reg);
@@ -5648,6 +5750,9 @@
}
+#undef __n
+#undef __q
+#undef __k
#undef __
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698