| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 2099)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -41,7 +41,35 @@
|
|
|
| #define __ ACCESS_MASM(masm_)
|
|
|
| +// -------------------------------------------------------------------------
|
| +// Platform-specific DeferredCode functions.
|
|
|
| +void DeferredCode::SaveRegisters() {
|
| + for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
|
| + int action = registers_[i];
|
| + if (action == kPush) {
|
| + __ push(RegisterAllocator::ToRegister(i));
|
| + } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
|
| + __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void DeferredCode::RestoreRegisters() {
|
| + // Restore registers in reverse order due to the stack.
|
| + for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
|
| + int action = registers_[i];
|
| + if (action == kPush) {
|
| + __ pop(RegisterAllocator::ToRegister(i));
|
| + } else if (action != kIgnore) {
|
| + action &= ~kSyncedFlag;
|
| + __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| // -------------------------------------------------------------------------
|
| // CodeGenState implementation.
|
|
|
| @@ -776,23 +804,14 @@
|
| };
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm)
|
| -
|
| -
|
| void DeferredInlineSmiOperation::Generate() {
|
| - MacroAssembler* masm = cgen()->masm();
|
| - enter()->Bind();
|
| - VirtualFrame::SpilledScope spilled_scope;
|
| -
|
| switch (op_) {
|
| case Token::ADD: {
|
| + // Revert optimistic add.
|
| if (reversed_) {
|
| - // revert optimistic add
|
| __ sub(r0, r0, Operand(Smi::FromInt(value_)));
|
| __ mov(r1, Operand(Smi::FromInt(value_)));
|
| } else {
|
| - // revert optimistic add
|
| __ sub(r1, r0, Operand(Smi::FromInt(value_)));
|
| __ mov(r0, Operand(Smi::FromInt(value_)));
|
| }
|
| @@ -800,8 +819,8 @@
|
| }
|
|
|
| case Token::SUB: {
|
| + // Revert optimistic sub.
|
| if (reversed_) {
|
| - // revert optimistic sub
|
| __ rsb(r0, r0, Operand(Smi::FromInt(value_)));
|
| __ mov(r1, Operand(Smi::FromInt(value_)));
|
| } else {
|
| @@ -830,31 +849,22 @@
|
| __ mov(r1, Operand(r0));
|
| __ mov(r0, Operand(Smi::FromInt(value_)));
|
| } else {
|
| - UNREACHABLE(); // should have been handled in SmiOperation
|
| + UNREACHABLE(); // Should have been handled in SmiOperation.
|
| }
|
| break;
|
| }
|
|
|
| default:
|
| - // other cases should have been handled before this point.
|
| + // Other cases should have been handled before this point.
|
| UNREACHABLE();
|
| break;
|
| }
|
|
|
| - GenericBinaryOpStub igostub(op_, overwrite_mode_);
|
| - Result arg0 = cgen()->allocator()->Allocate(r1);
|
| - ASSERT(arg0.is_valid());
|
| - Result arg1 = cgen()->allocator()->Allocate(r0);
|
| - ASSERT(arg1.is_valid());
|
| - cgen()->frame()->CallStub(&igostub, &arg0, &arg1);
|
| - exit_.Jump();
|
| + GenericBinaryOpStub stub(op_, overwrite_mode_);
|
| + __ CallStub(&stub);
|
| }
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm_)
|
| -
|
| -
|
| void CodeGenerator::SmiOperation(Token::Value op,
|
| Handle<Object> value,
|
| bool reversed,
|
| @@ -877,28 +887,28 @@
|
| switch (op) {
|
| case Token::ADD: {
|
| DeferredCode* deferred =
|
| - new DeferredInlineSmiOperation(op, int_value, reversed, mode);
|
| + new DeferredInlineSmiOperation(op, int_value, reversed, mode);
|
|
|
| __ add(r0, r0, Operand(value), SetCC);
|
| - deferred->enter()->Branch(vs);
|
| + deferred->Branch(vs);
|
| __ tst(r0, Operand(kSmiTagMask));
|
| - deferred->enter()->Branch(ne);
|
| + deferred->Branch(ne);
|
| deferred->BindExit();
|
| break;
|
| }
|
|
|
| case Token::SUB: {
|
| DeferredCode* deferred =
|
| - new DeferredInlineSmiOperation(op, int_value, reversed, mode);
|
| + new DeferredInlineSmiOperation(op, int_value, reversed, mode);
|
|
|
| - if (!reversed) {
|
| - __ sub(r0, r0, Operand(value), SetCC);
|
| - } else {
|
| + if (reversed) {
|
| __ rsb(r0, r0, Operand(value), SetCC);
|
| + } else {
|
| + __ sub(r0, r0, Operand(value), SetCC);
|
| }
|
| - deferred->enter()->Branch(vs);
|
| + deferred->Branch(vs);
|
| __ tst(r0, Operand(kSmiTagMask));
|
| - deferred->enter()->Branch(ne);
|
| + deferred->Branch(ne);
|
| deferred->BindExit();
|
| break;
|
| }
|
| @@ -909,7 +919,7 @@
|
| DeferredCode* deferred =
|
| new DeferredInlineSmiOperation(op, int_value, reversed, mode);
|
| __ tst(r0, Operand(kSmiTagMask));
|
| - deferred->enter()->Branch(ne);
|
| + deferred->Branch(ne);
|
| switch (op) {
|
| case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break;
|
| case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
|
| @@ -934,14 +944,14 @@
|
| DeferredCode* deferred =
|
| new DeferredInlineSmiOperation(op, shift_value, false, mode);
|
| __ tst(r0, Operand(kSmiTagMask));
|
| - deferred->enter()->Branch(ne);
|
| + deferred->Branch(ne);
|
| __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags
|
| switch (op) {
|
| case Token::SHL: {
|
| __ mov(r2, Operand(r2, LSL, shift_value));
|
| // check that the *unsigned* result fits in a smi
|
| __ add(r3, r2, Operand(0x40000000), SetCC);
|
| - deferred->enter()->Branch(mi);
|
| + deferred->Branch(mi);
|
| break;
|
| }
|
| case Token::SHR: {
|
| @@ -956,7 +966,7 @@
|
| // smi tagging these two cases can only happen with shifts
|
| // by 0 or 1 when handed a valid smi
|
| __ and_(r3, r2, Operand(0xc0000000), SetCC);
|
| - deferred->enter()->Branch(ne);
|
| + deferred->Branch(ne);
|
| break;
|
| }
|
| case Token::SAR: {
|
| @@ -2670,40 +2680,25 @@
|
| };
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm)
|
| -
|
| -
|
| void DeferredObjectLiteral::Generate() {
|
| - MacroAssembler* masm = cgen()->masm();
|
| // Argument is passed in r1.
|
| - enter()->Bind();
|
| - VirtualFrame::SpilledScope spilled_scope;
|
|
|
| // If the entry is undefined we call the runtime system to compute
|
| // the literal.
|
| -
|
| - VirtualFrame* frame = cgen()->frame();
|
| // Literal array (0).
|
| - frame->EmitPush(r1);
|
| + __ push(r1);
|
| // Literal index (1).
|
| __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
|
| - frame->EmitPush(r0);
|
| + __ push(r0);
|
| // Constant properties (2).
|
| __ mov(r0, Operand(node_->constant_properties()));
|
| - frame->EmitPush(r0);
|
| - Result boilerplate =
|
| - frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
|
| - __ mov(r2, Operand(boilerplate.reg()));
|
| + __ push(r0);
|
| + __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
|
| + __ mov(r2, Operand(r0));
|
| // Result is returned in r2.
|
| - exit_.Jump();
|
| }
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm_)
|
| -
|
| -
|
| void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
|
| #ifdef DEBUG
|
| int original_height = frame_->height();
|
| @@ -2729,7 +2724,7 @@
|
| // Check whether we need to materialize the object literal boilerplate.
|
| // If so, jump to the deferred code.
|
| __ cmp(r2, Operand(Factory::undefined_value()));
|
| - deferred->enter()->Branch(eq);
|
| + deferred->Branch(eq);
|
| deferred->BindExit();
|
|
|
| // Push the object literal boilerplate.
|
| @@ -2807,40 +2802,25 @@
|
| };
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm)
|
| -
|
| -
|
| void DeferredArrayLiteral::Generate() {
|
| - MacroAssembler* masm = cgen()->masm();
|
| // Argument is passed in r1.
|
| - enter()->Bind();
|
| - VirtualFrame::SpilledScope spilled_scope;
|
|
|
| // If the entry is undefined we call the runtime system to computed
|
| // the literal.
|
| -
|
| - VirtualFrame* frame = cgen()->frame();
|
| // Literal array (0).
|
| - frame->EmitPush(r1);
|
| + __ push(r1);
|
| // Literal index (1).
|
| __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
|
| - frame->EmitPush(r0);
|
| + __ push(r0);
|
| // Constant properties (2).
|
| __ mov(r0, Operand(node_->literals()));
|
| - frame->EmitPush(r0);
|
| - Result boilerplate =
|
| - frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
|
| - __ mov(r2, Operand(boilerplate.reg()));
|
| + __ push(r0);
|
| + __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
|
| + __ mov(r2, Operand(r0));
|
| // Result is returned in r2.
|
| - exit_.Jump();
|
| }
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm_)
|
| -
|
| -
|
| void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
|
| #ifdef DEBUG
|
| int original_height = frame_->height();
|
| @@ -2866,7 +2846,7 @@
|
| // Check whether we need to materialize the object literal boilerplate.
|
| // If so, jump to the deferred code.
|
| __ cmp(r2, Operand(Factory::undefined_value()));
|
| - deferred->enter()->Branch(eq);
|
| + deferred->Branch(eq);
|
| deferred->BindExit();
|
|
|
| // Push the object literal boilerplate.
|
|
|