| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index e40021dfeab574f4e883c6b7b1eae41c2e0ec79c..5a8249efc3bcd27a23b3b8d80265b48897cca3fc 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -3037,22 +3037,44 @@ void LCodeGen::DoLoadExternalArrayPointer(
|
| void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
| Register arguments = ToRegister(instr->arguments());
|
| Register result = ToRegister(instr->result());
|
| - if (instr->length()->IsConstantOperand() &&
|
| - instr->index()->IsConstantOperand()) {
|
| - int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
|
| + // There are two words between the frame pointer and the last argument.
|
| + // Subtracting from length accounts for one of them add one more.
|
| + if (instr->length()->IsConstantOperand()) {
|
| int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
|
| - int index = (const_length - const_index) + 1;
|
| - __ lw(result, MemOperand(arguments, index * kPointerSize));
|
| + if (instr->index()->IsConstantOperand()) {
|
| + int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
|
| + int index = (const_length - const_index) + 1;
|
| + __ lw(result, MemOperand(arguments, index * kPointerSize));
|
| + } else {
|
| + Register index = ToRegister(instr->index());
|
| + __ li(at, Operand(const_length + 1));
|
| + __ Subu(result, at, index);
|
| + __ sll(at, result, kPointerSizeLog2);
|
| + __ Addu(at, arguments, at);
|
| + __ lw(result, MemOperand(at));
|
| + }
|
| + } else if (instr->index()->IsConstantOperand()) {
|
| + Register length = ToRegister(instr->length());
|
| + int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
|
| + int loc = const_index - 1;
|
| + if (loc != 0) {
|
| + __ Subu(result, length, Operand(loc));
|
| + __ sll(at, result, kPointerSizeLog2);
|
| + __ Addu(at, arguments, at);
|
| + __ lw(result, MemOperand(at));
|
| + } else {
|
| + __ sll(at, length, kPointerSizeLog2);
|
| + __ Addu(at, arguments, at);
|
| + __ lw(result, MemOperand(at));
|
| + }
|
| } else {
|
| Register length = ToRegister(instr->length());
|
| Register index = ToRegister(instr->index());
|
| - // There are two words between the frame pointer and the last argument.
|
| - // Subtracting from length accounts for one of them, add one more.
|
| - __ subu(length, length, index);
|
| - __ Addu(length, length, Operand(1));
|
| - __ sll(length, length, kPointerSizeLog2);
|
| - __ Addu(at, arguments, Operand(length));
|
| - __ lw(result, MemOperand(at, 0));
|
| + __ Subu(result, length, index);
|
| + __ Addu(result, result, 1);
|
| + __ sll(at, result, kPointerSizeLog2);
|
| + __ Addu(at, arguments, at);
|
| + __ lw(result, MemOperand(at));
|
| }
|
| }
|
|
|
|
|