From 507e9b26a6401a1f851a38abc94ced26337872ac Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Mon, 26 Apr 2010 14:25:29 +0000 Subject: [PATCH] Simplify the use of the stm instruction on ARM. Review URL: http://codereview.chromium.org/1694016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4501 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/codegen-arm.cc | 22 ++++++---------- src/arm/ic-arm.cc | 21 +++++++-------- src/arm/macro-assembler-arm.h | 59 +++++++++++++++++++++++++++++++++++++++++++ src/arm/stub-cache-arm.cc | 28 ++++++++------------ src/arm/virtual-frame-arm.cc | 6 ++--- 5 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 3594aab..312bfd5 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -619,7 +619,7 @@ void CodeGenerator::StoreArgumentsObject(bool initial) { __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); frame_->Adjust(3); - __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit()); + __ Push(r2, r1, r0); frame_->CallStub(&stub, 3); frame_->EmitPush(r0); } @@ -4437,8 +4437,7 @@ class DeferredSearchCache: public DeferredCode { void DeferredSearchCache::Generate() { - __ push(cache_); - __ push(key_); + __ Push(cache_, key_); __ CallRuntime(Runtime::kGetFromCache, 2); if (!dst_.is(r0)) { __ mov(dst_, r0); @@ -5497,8 +5496,7 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) { // Create a new closure through the slower runtime call. __ bind(&gc); - __ push(cp); - __ push(r3); + __ Push(cp, r3); __ TailCallRuntime(Runtime::kNewClosure, 2, 1); } @@ -6328,8 +6326,7 @@ void CompareStub::Generate(MacroAssembler* masm) { __ bind(&slow); - __ push(r1); - __ push(r0); + __ Push(r1, r0); // Figure out which native to call and setup the arguments. Builtins::JavaScript native; if (cc_ == eq) { @@ -6594,8 +6591,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases( __ bind(&slow); // Push arguments to the stack - __ push(r1); - __ push(r0); + __ Push(r1, r0); if (Token::ADD == op_) { // Test for string arguments before calling runtime. @@ -6849,8 +6845,7 @@ void GenericBinaryOpStub::HandleNonSmiBitwiseOp(MacroAssembler* masm, // If all else failed then we go to the runtime system. __ bind(&slow); - __ push(lhs); // restore stack - __ push(rhs); + __ Push(lhs, rhs); // Restore stack. switch (op_) { case Token::BIT_OR: __ InvokeBuiltin(Builtins::BIT_OR, JUMP_JS); @@ -7248,8 +7243,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { Label get_result; - __ push(r1); - __ push(r0); + __ Push(r1, r0); // Internal frame is necessary to handle exceptions properly. __ EnterInternalFrame(); @@ -7723,7 +7717,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { __ mov(r6, Operand(Smi::FromInt(marker))); __ mov(r5, Operand(ExternalReference(Top::k_c_entry_fp_address))); __ ldr(r5, MemOperand(r5)); - __ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | r8.bit()); + __ Push(r8, r7, r6, r5); // Setup frame pointer for the frame to be pushed. __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index 2b7dac6..80504df 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -447,7 +447,7 @@ void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { __ EnterInternalFrame(); // Push the receiver and the name of the function. - __ stm(db_w, sp, r2.bit() | r3.bit()); + __ Push(r3, r2); // Call the entry. __ mov(r0, Operand(2)); @@ -645,7 +645,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { // ----------------------------------- __ ldm(ia, sp, r2.bit() | r3.bit()); - __ stm(db_w, sp, r2.bit() | r3.bit()); + __ Push(r3, r2); ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); __ TailCallExternalReference(ref, 2, 1); @@ -660,7 +660,7 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { // ----------------------------------- __ ldm(ia, sp, r2.bit() | r3.bit()); - __ stm(db_w, sp, r2.bit() | r3.bit()); + __ Push(r3, r2); __ TailCallRuntime(Runtime::kGetProperty, 2, 1); } @@ -778,7 +778,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { __ bind(&index_ok); // Duplicate receiver and key since they are expected on the stack after // the KeyedLoadIC call. - __ stm(db_w, sp, r0.bit() | r1.bit()); + __ Push(r1, r0); __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS); __ bind(&miss); @@ -1094,8 +1094,7 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { __ b(ne, &slow); // Everything is fine, call runtime. - __ push(r1); // receiver - __ push(r0); // key + __ Push(r1, r0); // Receiver, key. // Perform tail call to the entry. __ TailCallExternalReference(ExternalReference( @@ -1115,7 +1114,7 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { // ----------------------------------- __ ldm(ia, sp, r2.bit() | r3.bit()); - __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit()); + __ Push(r3, r2, r0); ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); __ TailCallExternalReference(ref, 3, 1); @@ -1130,7 +1129,7 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { // -- sp[1] : receiver // ----------------------------------- __ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object - __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit()); + __ Push(r3, r1, r0); __ TailCallRuntime(Runtime::kSetProperty, 3, 1); } @@ -1684,8 +1683,7 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) { // -- lr : return address // ----------------------------------- - __ push(r1); - __ stm(db_w, sp, r2.bit() | r0.bit()); + __ Push(r1, r2, r0); // Perform tail call to the entry. ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); @@ -1729,8 +1727,7 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) { __ BranchOnNotSmi(value, &miss); // Prepare tail call to StoreIC_ArrayLength. - __ push(receiver); - __ push(value); + __ Push(receiver, value); ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength)); __ TailCallExternalReference(ref, 2, 1); diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index a2cd270..062c5c6 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -93,6 +93,65 @@ class MacroAssembler: public Assembler { // well as the ip register. void RecordWrite(Register object, Register offset, Register scratch); + // Push two registers. Pushes leftmost register first (to highest address). + void Push(Register src1, Register src2, Condition cond = al) { + ASSERT(!src1.is(src2)); + if (src1.code() > src2.code()) { + stm(db_w, sp, src1.bit() | src2.bit(), cond); + } else { + str(src1, MemOperand(sp, 4, NegPreIndex), cond); + str(src2, MemOperand(sp, 4, NegPreIndex), cond); + } + } + + // Push three registers. Pushes leftmost register first (to highest address). + void Push(Register src1, Register src2, Register src3, Condition cond = al) { + ASSERT(!src1.is(src2)); + ASSERT(!src2.is(src3)); + ASSERT(!src1.is(src3)); + if (src1.code() > src2.code()) { + if (src2.code() > src3.code()) { + stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond); + } else { + stm(db_w, sp, src1.bit() | src2.bit(), cond); + str(src3, MemOperand(sp, 4, NegPreIndex), cond); + } + } else { + str(src1, MemOperand(sp, 4, NegPreIndex), cond); + Push(src2, src3, cond); + } + } + + // Push four registers. Pushes leftmost register first (to highest address). + void Push(Register src1, Register src2, + Register src3, Register src4, Condition cond = al) { + ASSERT(!src1.is(src2)); + ASSERT(!src2.is(src3)); + ASSERT(!src1.is(src3)); + ASSERT(!src1.is(src4)); + ASSERT(!src2.is(src4)); + ASSERT(!src3.is(src4)); + if (src1.code() > src2.code()) { + if (src2.code() > src3.code()) { + if (src3.code() > src4.code()) { + stm(db_w, + sp, + src1.bit() | src2.bit() | src3.bit() | src4.bit(), + cond); + } else { + stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond); + str(src4, MemOperand(sp, 4, NegPreIndex), cond); + } + } else { + stm(db_w, sp, src1.bit() | src2.bit(), cond); + Push(src3, src4, cond); + } + } else { + str(src1, MemOperand(sp, 4, NegPreIndex), cond); + Push(src2, src3, src4, cond); + } + } + // --------------------------------------------------------------------------- // Stack limit support diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 1cb88b4..6fef40b 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -296,7 +296,7 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, // We jump to a runtime call that extends the properties array. __ push(receiver_reg); __ mov(r2, Operand(Handle(transition))); - __ stm(db_w, sp, r2.bit() | r0.bit()); + __ Push(r2, r0); __ TailCallExternalReference( ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1); @@ -464,8 +464,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED { __ EnterInternalFrame(); __ push(receiver); - __ push(holder); - __ push(name_); + __ Push(holder, name_); CompileCallLoadPropertyWithInterceptor(masm, receiver, @@ -510,8 +509,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED { Label cleanup; __ pop(scratch2); - __ push(receiver); - __ push(scratch2); + __ Push(receiver, scratch2); holder = stub_compiler->CheckPrototypes(holder_obj, holder, lookup->holder(), scratch1, @@ -523,8 +521,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED { __ Move(holder, Handle(callback)); __ push(holder); __ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset)); - __ push(scratch1); - __ push(name_); + __ Push(scratch1, name_); ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); @@ -725,13 +722,11 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); // Push the arguments on the JS stack of the caller. - __ push(receiver); // receiver - __ push(reg); // holder + __ push(receiver); // Receiver. + __ push(reg); // Holder. __ mov(ip, Operand(Handle(callback))); // callback data - __ push(ip); __ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset)); - __ push(reg); - __ push(name_reg); // name + __ Push(ip, reg, name_reg); // Do tail-call to the runtime system. ExternalReference load_callback_property = @@ -1105,8 +1100,7 @@ Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, // Call the interceptor. __ EnterInternalFrame(); - __ push(holder_reg); - __ push(name_reg); + __ Push(holder_reg, name_reg); CompileCallLoadPropertyWithInterceptor(masm(), receiver, holder_reg, @@ -1309,7 +1303,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, __ push(r1); // receiver __ mov(ip, Operand(Handle(callback))); // callback info - __ stm(db_w, sp, ip.bit() | r2.bit() | r0.bit()); + __ Push(ip, r2, r0); // Do tail-call to the runtime system. ExternalReference store_callback_property = @@ -1354,9 +1348,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, // checks. ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); - __ push(r1); // receiver. - __ push(r2); // name. - __ push(r0); // value. + __ Push(r1, r2, r0); // Receiver, name, value. // Do tail-call to the runtime system. ExternalReference store_ic_property = diff --git a/src/arm/virtual-frame-arm.cc b/src/arm/virtual-frame-arm.cc index 3183c09..78099a2 100644 --- a/src/arm/virtual-frame-arm.cc +++ b/src/arm/virtual-frame-arm.cc @@ -121,8 +121,7 @@ void VirtualFrame::MergeTo(VirtualFrame* expected) { __ pop(r0); break; case CASE_NUMBER(R0_R1_TOS, NO_TOS_REGISTERS): - __ push(r1); - __ push(r0); + __ Push(r1, r0); break; case CASE_NUMBER(R0_R1_TOS, R0_TOS): __ push(r1); @@ -137,8 +136,7 @@ void VirtualFrame::MergeTo(VirtualFrame* expected) { __ Swap(r0, r1, ip); break; case CASE_NUMBER(R1_R0_TOS, NO_TOS_REGISTERS): - __ push(r0); - __ push(r1); + __ Push(r0, r1); break; case CASE_NUMBER(R1_R0_TOS, R0_TOS): __ push(r0); -- 2.7.4