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
This commit is contained in:
erik.corry@gmail.com 2010-04-26 14:25:29 +00:00
parent 53f93b11d2
commit 507e9b26a6
5 changed files with 88 additions and 48 deletions

View File

@ -619,7 +619,7 @@ void CodeGenerator::StoreArgumentsObject(bool initial) {
__ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
__ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
frame_->Adjust(3); frame_->Adjust(3);
__ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit()); __ Push(r2, r1, r0);
frame_->CallStub(&stub, 3); frame_->CallStub(&stub, 3);
frame_->EmitPush(r0); frame_->EmitPush(r0);
} }
@ -4437,8 +4437,7 @@ class DeferredSearchCache: public DeferredCode {
void DeferredSearchCache::Generate() { void DeferredSearchCache::Generate() {
__ push(cache_); __ Push(cache_, key_);
__ push(key_);
__ CallRuntime(Runtime::kGetFromCache, 2); __ CallRuntime(Runtime::kGetFromCache, 2);
if (!dst_.is(r0)) { if (!dst_.is(r0)) {
__ mov(dst_, r0); __ mov(dst_, r0);
@ -5497,8 +5496,7 @@ void FastNewClosureStub::Generate(MacroAssembler* masm) {
// Create a new closure through the slower runtime call. // Create a new closure through the slower runtime call.
__ bind(&gc); __ bind(&gc);
__ push(cp); __ Push(cp, r3);
__ push(r3);
__ TailCallRuntime(Runtime::kNewClosure, 2, 1); __ TailCallRuntime(Runtime::kNewClosure, 2, 1);
} }
@ -6328,8 +6326,7 @@ void CompareStub::Generate(MacroAssembler* masm) {
__ bind(&slow); __ bind(&slow);
__ push(r1); __ Push(r1, r0);
__ push(r0);
// Figure out which native to call and setup the arguments. // Figure out which native to call and setup the arguments.
Builtins::JavaScript native; Builtins::JavaScript native;
if (cc_ == eq) { if (cc_ == eq) {
@ -6594,8 +6591,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ bind(&slow); __ bind(&slow);
// Push arguments to the stack // Push arguments to the stack
__ push(r1); __ Push(r1, r0);
__ push(r0);
if (Token::ADD == op_) { if (Token::ADD == op_) {
// Test for string arguments before calling runtime. // 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. // If all else failed then we go to the runtime system.
__ bind(&slow); __ bind(&slow);
__ push(lhs); // restore stack __ Push(lhs, rhs); // Restore stack.
__ push(rhs);
switch (op_) { switch (op_) {
case Token::BIT_OR: case Token::BIT_OR:
__ InvokeBuiltin(Builtins::BIT_OR, JUMP_JS); __ InvokeBuiltin(Builtins::BIT_OR, JUMP_JS);
@ -7248,8 +7243,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
Label get_result; Label get_result;
__ push(r1); __ Push(r1, r0);
__ push(r0);
// Internal frame is necessary to handle exceptions properly. // Internal frame is necessary to handle exceptions properly.
__ EnterInternalFrame(); __ EnterInternalFrame();
@ -7723,7 +7717,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ mov(r6, Operand(Smi::FromInt(marker))); __ mov(r6, Operand(Smi::FromInt(marker)));
__ mov(r5, Operand(ExternalReference(Top::k_c_entry_fp_address))); __ mov(r5, Operand(ExternalReference(Top::k_c_entry_fp_address)));
__ ldr(r5, MemOperand(r5)); __ 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. // Setup frame pointer for the frame to be pushed.
__ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));

View File

@ -447,7 +447,7 @@ void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
__ EnterInternalFrame(); __ EnterInternalFrame();
// Push the receiver and the name of the function. // Push the receiver and the name of the function.
__ stm(db_w, sp, r2.bit() | r3.bit()); __ Push(r3, r2);
// Call the entry. // Call the entry.
__ mov(r0, Operand(2)); __ mov(r0, Operand(2));
@ -645,7 +645,7 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r2.bit() | r3.bit()); __ 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)); ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
__ TailCallExternalReference(ref, 2, 1); __ TailCallExternalReference(ref, 2, 1);
@ -660,7 +660,7 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r2.bit() | r3.bit()); __ ldm(ia, sp, r2.bit() | r3.bit());
__ stm(db_w, sp, r2.bit() | r3.bit()); __ Push(r3, r2);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
} }
@ -778,7 +778,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
__ bind(&index_ok); __ bind(&index_ok);
// Duplicate receiver and key since they are expected on the stack after // Duplicate receiver and key since they are expected on the stack after
// the KeyedLoadIC call. // the KeyedLoadIC call.
__ stm(db_w, sp, r0.bit() | r1.bit()); __ Push(r1, r0);
__ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS); __ InvokeBuiltin(Builtins::STRING_CHAR_AT, JUMP_JS);
__ bind(&miss); __ bind(&miss);
@ -1094,8 +1094,7 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
__ b(ne, &slow); __ b(ne, &slow);
// Everything is fine, call runtime. // Everything is fine, call runtime.
__ push(r1); // receiver __ Push(r1, r0); // Receiver, key.
__ push(r0); // key
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallExternalReference(ExternalReference( __ TailCallExternalReference(ExternalReference(
@ -1115,7 +1114,7 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r2.bit() | r3.bit()); __ 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)); ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
__ TailCallExternalReference(ref, 3, 1); __ TailCallExternalReference(ref, 3, 1);
@ -1130,7 +1129,7 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
// -- sp[1] : receiver // -- sp[1] : receiver
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object __ 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); __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
} }
@ -1684,8 +1683,7 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
// -- lr : return address // -- lr : return address
// ----------------------------------- // -----------------------------------
__ push(r1); __ Push(r1, r2, r0);
__ stm(db_w, sp, r2.bit() | r0.bit());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
@ -1729,8 +1727,7 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
__ BranchOnNotSmi(value, &miss); __ BranchOnNotSmi(value, &miss);
// Prepare tail call to StoreIC_ArrayLength. // Prepare tail call to StoreIC_ArrayLength.
__ push(receiver); __ Push(receiver, value);
__ push(value);
ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength)); ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength));
__ TailCallExternalReference(ref, 2, 1); __ TailCallExternalReference(ref, 2, 1);

View File

@ -93,6 +93,65 @@ class MacroAssembler: public Assembler {
// well as the ip register. // well as the ip register.
void RecordWrite(Register object, Register offset, Register scratch); 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 // Stack limit support

View File

@ -296,7 +296,7 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
// We jump to a runtime call that extends the properties array. // We jump to a runtime call that extends the properties array.
__ push(receiver_reg); __ push(receiver_reg);
__ mov(r2, Operand(Handle<Map>(transition))); __ mov(r2, Operand(Handle<Map>(transition)));
__ stm(db_w, sp, r2.bit() | r0.bit()); __ Push(r2, r0);
__ TailCallExternalReference( __ TailCallExternalReference(
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)),
3, 1); 3, 1);
@ -464,8 +464,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
__ EnterInternalFrame(); __ EnterInternalFrame();
__ push(receiver); __ push(receiver);
__ push(holder); __ Push(holder, name_);
__ push(name_);
CompileCallLoadPropertyWithInterceptor(masm, CompileCallLoadPropertyWithInterceptor(masm,
receiver, receiver,
@ -510,8 +509,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
Label cleanup; Label cleanup;
__ pop(scratch2); __ pop(scratch2);
__ push(receiver); __ Push(receiver, scratch2);
__ push(scratch2);
holder = stub_compiler->CheckPrototypes(holder_obj, holder, holder = stub_compiler->CheckPrototypes(holder_obj, holder,
lookup->holder(), scratch1, lookup->holder(), scratch1,
@ -523,8 +521,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
__ Move(holder, Handle<AccessorInfo>(callback)); __ Move(holder, Handle<AccessorInfo>(callback));
__ push(holder); __ push(holder);
__ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset)); __ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset));
__ push(scratch1); __ Push(scratch1, name_);
__ push(name_);
ExternalReference ref = ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
@ -725,13 +722,11 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss);
// Push the arguments on the JS stack of the caller. // Push the arguments on the JS stack of the caller.
__ push(receiver); // receiver __ push(receiver); // Receiver.
__ push(reg); // holder __ push(reg); // Holder.
__ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data
__ push(ip);
__ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset)); __ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset));
__ push(reg); __ Push(ip, reg, name_reg);
__ push(name_reg); // name
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
ExternalReference load_callback_property = ExternalReference load_callback_property =
@ -1105,8 +1100,7 @@ Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
// Call the interceptor. // Call the interceptor.
__ EnterInternalFrame(); __ EnterInternalFrame();
__ push(holder_reg); __ Push(holder_reg, name_reg);
__ push(name_reg);
CompileCallLoadPropertyWithInterceptor(masm(), CompileCallLoadPropertyWithInterceptor(masm(),
receiver, receiver,
holder_reg, holder_reg,
@ -1309,7 +1303,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
__ push(r1); // receiver __ push(r1); // receiver
__ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback info __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback info
__ stm(db_w, sp, ip.bit() | r2.bit() | r0.bit()); __ Push(ip, r2, r0);
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
ExternalReference store_callback_property = ExternalReference store_callback_property =
@ -1354,9 +1348,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
// checks. // checks.
ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
__ push(r1); // receiver. __ Push(r1, r2, r0); // Receiver, name, value.
__ push(r2); // name.
__ push(r0); // value.
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
ExternalReference store_ic_property = ExternalReference store_ic_property =

View File

@ -121,8 +121,7 @@ void VirtualFrame::MergeTo(VirtualFrame* expected) {
__ pop(r0); __ pop(r0);
break; break;
case CASE_NUMBER(R0_R1_TOS, NO_TOS_REGISTERS): case CASE_NUMBER(R0_R1_TOS, NO_TOS_REGISTERS):
__ push(r1); __ Push(r1, r0);
__ push(r0);
break; break;
case CASE_NUMBER(R0_R1_TOS, R0_TOS): case CASE_NUMBER(R0_R1_TOS, R0_TOS):
__ push(r1); __ push(r1);
@ -137,8 +136,7 @@ void VirtualFrame::MergeTo(VirtualFrame* expected) {
__ Swap(r0, r1, ip); __ Swap(r0, r1, ip);
break; break;
case CASE_NUMBER(R1_R0_TOS, NO_TOS_REGISTERS): case CASE_NUMBER(R1_R0_TOS, NO_TOS_REGISTERS):
__ push(r0); __ Push(r0, r1);
__ push(r1);
break; break;
case CASE_NUMBER(R1_R0_TOS, R0_TOS): case CASE_NUMBER(R1_R0_TOS, R0_TOS):
__ push(r0); __ push(r0);