Commit c26bd162 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: support arguments access in lithium-codegen-arm.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6188 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0ba16239
...@@ -1588,7 +1588,18 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { ...@@ -1588,7 +1588,18 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
Abort("DoAccessArgumentsAt unimplemented."); Register arguments = ToRegister(instr->arguments());
Register length = ToRegister(instr->length());
Operand index = ToOperand(instr->index());
Register result = ToRegister(instr->result());
__ sub(length, length, index);
DeoptimizeIf(hi, 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.
__ add(length, length, Operand(1));
__ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
} }
...@@ -1607,12 +1618,41 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ...@@ -1607,12 +1618,41 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
Abort("DoArgumentsElements unimplemented."); Register scratch = scratch0();
Register result = ToRegister(instr->result());
// Check if the calling frame is an arguments adaptor frame.
Label done, adapted;
__ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset));
__ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
// Result is the frame pointer for the frame if not adapted and for the real
// frame below the adaptor frame if adapted.
__ mov(result, fp, LeaveCC, ne);
__ mov(result, scratch, LeaveCC, eq);
} }
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Abort("DoArgumentsLength unimplemented."); Operand elem = ToOperand(instr->input());
Register result = ToRegister(instr->result());
Label done;
// If no arguments adaptor frame the number of arguments is fixed.
__ cmp(fp, elem);
__ mov(result, Operand(scope()->num_parameters()));
__ b(eq, &done);
// Arguments adaptor frame present. Get argument length from there.
__ ldr(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ ldr(result,
MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(result);
// Argument length is in result register.
__ bind(&done);
} }
......
...@@ -2000,6 +2000,8 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { ...@@ -2000,6 +2000,8 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
__ sub(length, index); __ sub(length, index);
DeoptimizeIf(below_equal, instr->environment()); 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.
__ mov(result, Operand(arguments, length, times_4, kPointerSize)); __ mov(result, Operand(arguments, length, times_4, kPointerSize));
} }
...@@ -2049,7 +2051,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { ...@@ -2049,7 +2051,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
// Check for arguments adapter frame. // Check for arguments adapter frame.
Label done, adapted; NearLabel done, adapted;
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
__ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); __ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
__ cmp(Operand(result), __ cmp(Operand(result),
...@@ -2064,7 +2066,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { ...@@ -2064,7 +2066,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
__ bind(&adapted); __ bind(&adapted);
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
// Done. Pointer to topmost argument is in result. // Result is the frame pointer for the frame if not adapted and for the real
// frame below the adaptor frame if adapted.
__ bind(&done); __ bind(&done);
} }
...@@ -2073,9 +2076,9 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { ...@@ -2073,9 +2076,9 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Operand elem = ToOperand(instr->input()); Operand elem = ToOperand(instr->input());
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
Label done; NearLabel done;
// No arguments adaptor frame. Number of arguments is fixed. // If no arguments adaptor frame the number of arguments is fixed.
__ cmp(ebp, elem); __ cmp(ebp, elem);
__ mov(result, Immediate(scope()->num_parameters())); __ mov(result, Immediate(scope()->num_parameters()));
__ j(equal, &done); __ j(equal, &done);
...@@ -2086,7 +2089,7 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { ...@@ -2086,7 +2089,7 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
ArgumentsAdaptorFrameConstants::kLengthOffset)); ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(result); __ SmiUntag(result);
// Done. Argument length is in result register. // Argument length is in result register.
__ bind(&done); __ bind(&done);
} }
......
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