| Index: src/arm/cfg-arm.cc
|
| ===================================================================
|
| --- src/arm/cfg-arm.cc (revision 2620)
|
| +++ src/arm/cfg-arm.cc (working copy)
|
| @@ -29,6 +29,7 @@
|
|
|
| #include "cfg.h"
|
| #include "codegen-inl.h"
|
| +#include "codegen-arm.h" // Include after codegen-inl.h.
|
| #include "macro-assembler-arm.h"
|
|
|
| namespace v8 {
|
| @@ -42,6 +43,14 @@
|
| {
|
| Comment cmt(masm, "[ InstructionBlock");
|
| for (int i = 0, len = instructions_.length(); i < len; i++) {
|
| + // If the location of the current instruction is a temp, then the
|
| + // instruction cannot be in tail position in the block. Allocate the
|
| + // temp based on peeking ahead to the next instruction.
|
| + Instruction* instr = instructions_[i];
|
| + Location* loc = instr->location();
|
| + if (loc->is_temporary()) {
|
| + instructions_[i+1]->FastAllocate(TempLocation::cast(loc));
|
| + }
|
| instructions_[i]->Compile(masm);
|
| }
|
| }
|
| @@ -91,34 +100,123 @@
|
| }
|
|
|
|
|
| +void BinaryOpInstr::Compile(MacroAssembler* masm) {
|
| + // The right value should not be on the stack---if it is a
|
| + // compiler-generated temporary it is in the accumulator.
|
| + ASSERT(!val1_->is_on_stack());
|
| +
|
| + // We can overwrite one of the operands if it is a temporary.
|
| + OverwriteMode mode = NO_OVERWRITE;
|
| + if (val0_->is_temporary()) {
|
| + mode = OVERWRITE_LEFT;
|
| + } else if (val1_->is_temporary()) {
|
| + mode = OVERWRITE_RIGHT;
|
| + }
|
| +
|
| + // Move left to r1 and right to r0.
|
| + val0_->Get(masm, r1);
|
| + val1_->Get(masm, r0);
|
| + GenericBinaryOpStub stub(op_, mode);
|
| + __ CallStub(&stub);
|
| + loc_->Set(masm, r0);
|
| +}
|
| +
|
| +
|
| void ReturnInstr::Compile(MacroAssembler* masm) {
|
| + // The location should be 'Effect'. As a side effect, move the value to
|
| + // the accumulator.
|
| Comment cmnt(masm, "[ ReturnInstr");
|
| - value_->ToRegister(masm, r0);
|
| + value_->Get(masm, r0);
|
| }
|
|
|
|
|
| -void Constant::ToRegister(MacroAssembler* masm, Register reg) {
|
| +void Constant::Get(MacroAssembler* masm, Register reg) {
|
| __ mov(reg, Operand(handle_));
|
| }
|
|
|
|
|
| -void SlotLocation::ToRegister(MacroAssembler* masm, Register reg) {
|
| - switch (type_) {
|
| +void Constant::Push(MacroAssembler* masm) {
|
| + __ mov(ip, Operand(handle_));
|
| + __ push(ip);
|
| +}
|
| +
|
| +
|
| +static MemOperand ToMemOperand(SlotLocation* loc) {
|
| + switch (loc->type()) {
|
| case Slot::PARAMETER: {
|
| int count = CfgGlobals::current()->fun()->scope()->num_parameters();
|
| - __ ldr(reg, MemOperand(fp, (1 + count - index_) * kPointerSize));
|
| - break;
|
| + return MemOperand(fp, (1 + count - loc->index()) * kPointerSize);
|
| }
|
| case Slot::LOCAL: {
|
| const int kOffset = JavaScriptFrameConstants::kLocal0Offset;
|
| - __ ldr(reg, MemOperand(fp, kOffset - index_ * kPointerSize));
|
| - break;
|
| + return MemOperand(fp, kOffset - loc->index() * kPointerSize);
|
| }
|
| default:
|
| UNREACHABLE();
|
| + return MemOperand(r0);
|
| }
|
| }
|
|
|
| +
|
| +void SlotLocation::Get(MacroAssembler* masm, Register reg) {
|
| + __ ldr(reg, ToMemOperand(this));
|
| +}
|
| +
|
| +
|
| +void SlotLocation::Set(MacroAssembler* masm, Register reg) {
|
| + __ str(reg, ToMemOperand(this));
|
| +}
|
| +
|
| +
|
| +void SlotLocation::Push(MacroAssembler* masm) {
|
| + __ ldr(ip, ToMemOperand(this));
|
| + __ push(ip); // Push will not destroy ip.
|
| +}
|
| +
|
| +
|
| +void TempLocation::Get(MacroAssembler* masm, Register reg) {
|
| + switch (where_) {
|
| + case ACCUMULATOR:
|
| + if (!reg.is(r0)) __ mov(reg, r0);
|
| + break;
|
| + case STACK:
|
| + __ pop(reg);
|
| + break;
|
| + case NOWHERE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void TempLocation::Set(MacroAssembler* masm, Register reg) {
|
| + switch (where_) {
|
| + case ACCUMULATOR:
|
| + if (!reg.is(r0)) __ mov(r0, reg);
|
| + break;
|
| + case STACK:
|
| + __ push(reg);
|
| + break;
|
| + case NOWHERE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void TempLocation::Push(MacroAssembler* masm) {
|
| + switch (where_) {
|
| + case ACCUMULATOR:
|
| + __ push(r0);
|
| + break;
|
| + case STACK:
|
| + case NOWHERE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
| } } // namespace v8::internal
|
|
|