Commit 7dd0cc2d authored by ager@chromium.org's avatar ager@chromium.org

More x64 work.

x64: Implement DoArgumentsElements, DoNumberUntagD, DoArgumentsLength,
DoAccessArgumentsAt, DoStringLength in lithium x64 backend.

Fix a bug in DoConstantD where only 32-bits of a double was loaded to
an xmm register.

Review URL: http://codereview.chromium.org/6474039

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6771 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e0552d77
...@@ -888,21 +888,15 @@ void LCodeGen::DoConstantD(LConstantD* instr) { ...@@ -888,21 +888,15 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
ASSERT(instr->result()->IsDoubleRegister()); ASSERT(instr->result()->IsDoubleRegister());
XMMRegister res = ToDoubleRegister(instr->result()); XMMRegister res = ToDoubleRegister(instr->result());
double v = instr->value(); 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 // Use xor to produce +0.0 in a fast and compact way, but avoid to
// do so if the constant is -0.0. // do so if the constant is -0.0.
if (BitCast<uint64_t, double>(v) == 0) { if (int_val == 0) {
__ xorpd(res, res); __ xorpd(res, res);
} else { } else {
Register tmp = ToRegister(instr->TempAt(0)); Register tmp = ToRegister(instr->TempAt(0));
int32_t v_int32 = static_cast<int32_t>(v); __ Set(tmp, int_val);
if (static_cast<double>(v_int32) == v) { __ movq(res, tmp);
__ 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);
}
} }
} }
...@@ -1820,7 +1814,20 @@ void LCodeGen::DoLoadPixelArrayExternalPointer( ...@@ -1820,7 +1814,20 @@ void LCodeGen::DoLoadPixelArrayExternalPointer(
void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 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));
} }
...@@ -1859,12 +1866,51 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ...@@ -1859,12 +1866,51 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
void LCodeGen::DoArgumentsElements(LArgumentsElements* 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) { 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);
} }
...@@ -2148,6 +2194,13 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { ...@@ -2148,6 +2194,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) { void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
LOperand* input = instr->InputAt(0); LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() || input->IsStackSlot()); ASSERT(input->IsRegister() || input->IsStackSlot());
...@@ -2260,7 +2313,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, ...@@ -2260,7 +2313,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Smi to XMM conversion // Smi to XMM conversion
__ bind(&load_smi); __ bind(&load_smi);
__ SmiToInteger32(kScratchRegister, input_reg); // Untag smi first. __ SmiToInteger32(kScratchRegister, input_reg);
__ cvtlsi2sd(result_reg, kScratchRegister); __ cvtlsi2sd(result_reg, kScratchRegister);
__ bind(&done); __ bind(&done);
} }
...@@ -2337,7 +2390,15 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { ...@@ -2337,7 +2390,15 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
void LCodeGen::DoNumberUntagD(LNumberUntagD* 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());
} }
......
...@@ -1114,14 +1114,12 @@ LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { ...@@ -1114,14 +1114,12 @@ LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
Abort("Unimplemented: %s", "DoArgumentsLength"); return DefineAsRegister(new LArgumentsLength(Use(length->value())));
return NULL;
} }
LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
Abort("Unimplemented: %s", "DoArgumentsElements"); return DefineAsRegister(new LArgumentsElements);
return NULL;
} }
...@@ -1343,7 +1341,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1343,7 +1341,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} }
return result; return result;
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
Abort("Unimplemented: %s", "DoAdd on Doubles"); return DoArithmeticD(Token::ADD, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsTagged());
return DoArithmeticT(Token::ADD, instr); return DoArithmeticT(Token::ADD, instr);
...@@ -1750,8 +1748,8 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { ...@@ -1750,8 +1748,8 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
Abort("Unimplemented: %s", "DoStringLength"); LOperand* string = UseRegisterAtStart(instr->value());
return NULL; return DefineAsRegister(new LStringLength(string));
} }
...@@ -1813,8 +1811,11 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { ...@@ -1813,8 +1811,11 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
Abort("Unimplemented: %s", "DoAccessArgumentsAt"); LOperand* arguments = UseRegister(instr->arguments());
return NULL; LOperand* length = UseTempRegister(instr->length());
LOperand* index = Use(instr->index());
LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
return AssignEnvironment(DefineAsRegister(result));
} }
......
...@@ -146,6 +146,7 @@ class LCodeGen; ...@@ -146,6 +146,7 @@ class LCodeGen;
V(StoreKeyedGeneric) \ V(StoreKeyedGeneric) \
V(StoreNamedField) \ V(StoreNamedField) \
V(StoreNamedGeneric) \ V(StoreNamedGeneric) \
V(StringLength) \
V(SubI) \ V(SubI) \
V(TaggedToI) \ V(TaggedToI) \
V(Throw) \ V(Throw) \
...@@ -1550,6 +1551,19 @@ class LStoreKeyedGeneric: public LStoreKeyed { ...@@ -1550,6 +1551,19 @@ class LStoreKeyedGeneric: public LStoreKeyed {
}; };
class LStringLength: public LTemplateInstruction<1, 1, 0> {
public:
explicit LStringLength(LOperand* string) {
inputs_[0] = string;
}
DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
DECLARE_HYDROGEN_ACCESSOR(StringLength)
LOperand* string() { return inputs_[0]; }
};
class LCheckFunction: public LTemplateInstruction<0, 1, 0> { class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
public: public:
explicit LCheckFunction(LOperand* value) { explicit LCheckFunction(LOperand* value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment