Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 36c9aac2f4bb66e5736e906a8286fb33fd077187..364fbde5571ef5ca687f89b7eeb2c7c6763c9343 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -888,21 +888,15 @@ void LCodeGen::DoConstantD(LConstantD* instr) { |
ASSERT(instr->result()->IsDoubleRegister()); |
XMMRegister res = ToDoubleRegister(instr->result()); |
double v = instr->value(); |
+ uint64_t int_val = BitCast<uint64_t, double>(v); |
// Use xor to produce +0.0 in a fast and compact way, but avoid to |
// do so if the constant is -0.0. |
- if (BitCast<uint64_t, double>(v) == 0) { |
+ if (int_val == 0) { |
__ xorpd(res, res); |
} else { |
Register tmp = ToRegister(instr->TempAt(0)); |
- int32_t v_int32 = static_cast<int32_t>(v); |
- if (static_cast<double>(v_int32) == v) { |
- __ movl(tmp, Immediate(v_int32)); |
- __ cvtlsi2sd(res, tmp); |
- } else { |
- uint64_t int_val = BitCast<uint64_t, double>(v); |
- __ Set(tmp, int_val); |
- __ movd(res, tmp); |
- } |
+ __ Set(tmp, int_val); |
+ __ movq(res, tmp); |
} |
} |
@@ -1797,7 +1791,20 @@ void LCodeGen::DoLoadPixelArrayExternalPointer( |
void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
- Abort("Unimplemented: %s", "DoAccessArgumentsAt"); |
+ Register arguments = ToRegister(instr->arguments()); |
+ Register length = ToRegister(instr->length()); |
+ Register result = ToRegister(instr->result()); |
+ |
+ if (instr->index()->IsRegister()) { |
+ __ subl(length, ToRegister(instr->index())); |
+ } else { |
+ __ subl(length, ToOperand(instr->index())); |
+ } |
+ DeoptimizeIf(below_equal, instr->environment()); |
+ |
+ // There are two words between the frame pointer and the last argument. |
+ // Subtracting from length accounts for one of them add one more. |
+ __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
} |
@@ -1836,12 +1843,51 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
- Abort("Unimplemented: %s", "DoArgumentsElements"); |
+ Register result = ToRegister(instr->result()); |
+ |
+ // Check for arguments adapter frame. |
+ NearLabel done, adapted; |
+ __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
+ __ SmiCompare(Operand(result, StandardFrameConstants::kContextOffset), |
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
+ __ j(equal, &adapted); |
+ |
+ // No arguments adaptor frame. |
+ __ movq(result, rbp); |
+ __ jmp(&done); |
+ |
+ // Arguments adaptor frame present. |
+ __ bind(&adapted); |
+ __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
+ |
+ // Result is the frame pointer for the frame if not adapted and for the real |
+ // frame below the adaptor frame if adapted. |
+ __ bind(&done); |
} |
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |
- Abort("Unimplemented: %s", "DoArgumentsLength"); |
+ Register result = ToRegister(instr->result()); |
+ |
+ NearLabel done; |
+ |
+ // If no arguments adaptor frame the number of arguments is fixed. |
+ if (instr->InputAt(0)->IsRegister()) { |
+ __ cmpq(rbp, ToRegister(instr->InputAt(0))); |
+ } else { |
+ __ cmpq(rbp, ToOperand(instr->InputAt(0))); |
+ } |
+ __ movq(result, Immediate(scope()->num_parameters())); |
+ __ j(equal, &done); |
+ |
+ // Arguments adaptor frame present. Get argument length from there. |
+ __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
+ __ movq(result, Operand(result, |
+ ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ SmiToInteger32(result, result); |
+ |
+ // Argument length is in result register. |
+ __ bind(&done); |
} |
@@ -2125,6 +2171,13 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
} |
+void LCodeGen::DoStringLength(LStringLength* instr) { |
+ Register string = ToRegister(instr->string()); |
+ Register result = ToRegister(instr->result()); |
+ __ movq(result, FieldOperand(string, String::kLengthOffset)); |
+} |
+ |
+ |
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
LOperand* input = instr->InputAt(0); |
ASSERT(input->IsRegister() || input->IsStackSlot()); |
@@ -2233,7 +2286,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, |
// Smi to XMM conversion |
__ bind(&load_smi); |
- __ SmiToInteger32(kScratchRegister, input_reg); // Untag smi first. |
+ __ SmiToInteger32(kScratchRegister, input_reg); |
__ cvtlsi2sd(result_reg, kScratchRegister); |
__ bind(&done); |
} |
@@ -2310,7 +2363,15 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
- Abort("Unimplemented: %s", "DoNumberUntagD"); |
+ LOperand* input = instr->InputAt(0); |
+ ASSERT(input->IsRegister()); |
+ LOperand* result = instr->result(); |
+ ASSERT(result->IsDoubleRegister()); |
+ |
+ Register input_reg = ToRegister(input); |
+ XMMRegister result_reg = ToDoubleRegister(result); |
+ |
+ EmitNumberUntagD(input_reg, result_reg, instr->environment()); |
} |