diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index a7960fa379..cacc921739 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -87,34 +87,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor( } -void LoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { a0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedLoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { a1 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void StringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { a0, a2 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedStringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { a1, a0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { Register registers[] = { a2, a1, a0 }; diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc index 59db832a1d..73c4d5e69d 100644 --- a/src/mips/debug-mips.cc +++ b/src/mips/debug-mips.cc @@ -185,16 +185,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { - // Calling convention for IC load (from ic-mips.cc). - // ----------- S t a t e ------------- - // -- a2 : name - // -- ra : return address - // -- a0 : receiver - // -- [sp] : receiver - // ----------------------------------- - // Registers a0 and a2 contain objects that need to be pushed on the - // expression stack of the fake JS frame. - Generate_DebugBreakCallHelper(masm, a0.bit() | a2.bit(), 0); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); } @@ -213,11 +206,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- ra : return address - // -- a0 : key - // -- a1 : receiver - Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit(), 0); + // Calling convention for keyed IC load (from ic-arm.cc). + Register receiver = KeyedLoadIC::ReceiverRegister(); + Register name = KeyedLoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); } diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 4824e9f983..3a0c256367 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1397,8 +1397,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, __ bind(&fast); } - __ lw(a0, GlobalObjectOperand()); - __ li(a2, Operand(var->name())); + __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ li(LoadIC::NameRegister(), Operand(var->name())); ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; @@ -1480,10 +1480,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - // Use inline caching. Variable name is passed in a2 and the global - // object (receiver) in a0. - __ lw(a0, GlobalObjectOperand()); - __ li(a2, Operand(var->name())); + __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ li(LoadIC::NameRegister(), Operand(var->name())); CallLoadIC(CONTEXTUAL); context()->Plug(v0); break; @@ -2023,7 +2021,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // [sp + 0 * kPointerSize] g Label l_catch, l_try, l_suspend, l_continuation, l_resume; - Label l_next, l_call, l_loop; + Label l_next, l_call; // Initial send value is undefined. __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); __ Branch(&l_next); @@ -2070,14 +2068,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = 'next'; arg = received; __ bind(&l_next); + Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); + Register keyedload_name = KeyedLoadIC::NameRegister(); + ASSERT(keyedload_receiver.is(a1)); + ASSERT(keyedload_name.is(a0)); + __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ Push(a2, a3, a0); // "next", iter, received // result = receiver[f](arg); __ bind(&l_call); - __ lw(a1, MemOperand(sp, kPointerSize)); - __ lw(a0, MemOperand(sp, 2 * kPointerSize)); + __ lw(keyedload_receiver, MemOperand(sp, kPointerSize)); + __ lw(keyedload_name, MemOperand(sp, 2 * kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ mov(a0, v0); @@ -2090,21 +2093,25 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ Drop(1); // The function is still on the stack; drop it. // if (!result.done) goto l_try; - __ bind(&l_loop); - __ mov(a0, v0); - __ push(a0); // save result - __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" - CallLoadIC(NOT_CONTEXTUAL); // result.done in v0 - __ mov(a0, v0); + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + ASSERT(load_receiver.is(a0)); + ASSERT(load_name.is(a2)); + + __ mov(load_receiver, v0); + __ push(v0); // save result + __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" + CallLoadIC(NOT_CONTEXTUAL); // v0=result.done + __ mov(load_receiver, v0); Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); CallIC(bool_ic); __ Branch(&l_try, eq, v0, Operand(zero_reg)); // result.value - __ pop(a0); // result - __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" - CallLoadIC(NOT_CONTEXTUAL); // result.value in v0 - context()->DropAndPlug(2, v0); // drop iter and g + __ pop(load_receiver); // result + __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" + CallLoadIC(NOT_CONTEXTUAL); // v0=result.value + context()->DropAndPlug(2, v0); // drop iter and g break; } } @@ -2265,9 +2272,9 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); - __ mov(a0, result_register()); - __ li(a2, Operand(key->value())); - // Call load IC. It has arguments receiver and property name a0 and a2. + __ mov(LoadIC::ReceiverRegister(), result_register()); + __ li(LoadIC::NameRegister(), Operand(key->value())); + // Call load IC. It has register arguments receiver and property. CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); } @@ -2275,7 +2282,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); __ mov(a0, result_register()); - // Call keyed load IC. It has arguments key and receiver in a0 and a1. + // Call keyed load IC. It has register arguments receiver and key. Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, prop->PropertyFeedbackId()); } @@ -2573,13 +2580,16 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); + ASSERT(a0.is(LoadIC::ReceiverRegister())); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(v0); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(a1); + ASSERT(a0.is(KeyedLoadIC::NameRegister())); + ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); + __ pop(KeyedLoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(v0); } @@ -2631,12 +2641,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { // Load the key. VisitForAccumulatorValue(key); + ASSERT(a0.is(KeyedLoadIC::NameRegister())); Expression* callee = expr->expression(); // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ lw(a1, MemOperand(sp, 0)); + __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4085,8 +4096,10 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ lw(a0, GlobalObjectOperand()); __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset)); __ push(a0); + // Load the function from the receiver. - __ li(a2, Operand(expr->name())); + ASSERT(a0.is(LoadIC::ReceiverRegister())); + __ li(LoadIC::NameRegister(), Operand(expr->name())); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); // Push the target function under the receiver. @@ -4270,7 +4283,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } else { VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); - __ lw(a1, MemOperand(sp, 0)); + ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); + __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); __ push(v0); EmitKeyedPropertyLoad(prop); } @@ -4423,8 +4437,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { VariableProxy* proxy = expr->AsVariableProxy(); if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "[ Global variable"); - __ lw(a0, GlobalObjectOperand()); - __ li(a2, Operand(proxy->name())); + __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ li(LoadIC::NameRegister(), Operand(proxy->name())); // Use a regular load, not a contextual load, to avoid a reference // error. CallLoadIC(NOT_CONTEXTUAL); diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc index 080631aaa8..24db0ce0f0 100644 --- a/src/mips/ic-mips.cc +++ b/src/mips/ic-mips.cc @@ -322,6 +322,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // -- ra : return address // -- a0 : receiver // ----------------------------------- + ASSERT(a0.is(ReceiverRegister())); + ASSERT(a2.is(NameRegister())); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); @@ -339,6 +341,9 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // -- lr : return address // -- a0 : receiver // ----------------------------------- + ASSERT(a0.is(ReceiverRegister())); + ASSERT(a2.is(NameRegister())); + Label miss, slow; GenerateNameDictionaryReceiverCheck(masm, a0, a1, a3, t0, &miss); @@ -357,18 +362,18 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { } +// A register that isn't one of the parameters to the load ic. +static const Register LoadIC_TempRegister() { return a3; } + + void LoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- a2 : name - // -- ra : return address - // -- a0 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); - __ mov(a3, a0); - __ Push(a3, a2); + __ mov(LoadIC_TempRegister(), ReceiverRegister()); + __ Push(LoadIC_TempRegister(), NameRegister()); // Perform tail call to the entry. ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); @@ -377,14 +382,10 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- a2 : name - // -- ra : return address - // -- a0 : receiver - // ----------------------------------- + // The return address is on the stack. - __ mov(a3, a0); - __ Push(a3, a2); + __ mov(LoadIC_TempRegister(), ReceiverRegister()); + __ Push(LoadIC_TempRegister(), NameRegister()); __ TailCallRuntime(Runtime::kGetProperty, 2, 1); } @@ -486,6 +487,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- a0 : key // -- a1 : receiver // ----------------------------------- + ASSERT(a1.is(ReceiverRegister())); + ASSERT(a0.is(NameRegister())); Label slow, notin; MemOperand mapped_location = GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, ¬in, &slow); @@ -541,16 +544,12 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- ra : return address - // -- a0 : key - // -- a1 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); - __ Push(a1, a0); + __ Push(ReceiverRegister(), NameRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -568,13 +567,9 @@ const Register KeyedLoadIC::NameRegister() { return a0; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- ra : return address - // -- a0 : key - // -- a1 : receiver - // ----------------------------------- + // The return address is on the stack. - __ Push(a1, a0); + __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); } @@ -589,8 +584,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; - Register key = a0; - Register receiver = a1; + Register key = NameRegister(); + Register receiver = ReceiverRegister(); + ASSERT(key.is(a0)); + ASSERT(receiver.is(a1)); Isolate* isolate = masm->isolate(); @@ -759,17 +756,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- ra : return address - // -- a0 : key (index) - // -- a1 : receiver - // ----------------------------------- + // Return address is on the stack. Label miss; - Register receiver = a1; - Register index = a0; + Register receiver = ReceiverRegister(); + Register index = NameRegister(); Register scratch = a3; Register result = v0; + ASSERT(!scratch.is(receiver) && !scratch.is(index)); StringCharAtGenerator char_at_generator(receiver, index, @@ -1078,30 +1072,33 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- ra : return address - // -- a0 : key - // -- a1 : receiver - // ----------------------------------- + // Return address is on the stack. Label slow; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + Register scratch1 = a2; + Register scratch2 = a3; + ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); + ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); + // Check that the receiver isn't a smi. - __ JumpIfSmi(a1, &slow); + __ JumpIfSmi(receiver, &slow); // Check that the key is an array index, that is Uint32. - __ And(t0, a0, Operand(kSmiTagMask | kSmiSignMask)); + __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); __ Branch(&slow, ne, t0, Operand(zero_reg)); // Get the map of the receiver. - __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); + __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ lbu(a3, FieldMemOperand(a2, Map::kBitFieldOffset)); - __ And(a3, a3, Operand(kSlowCaseBitFieldMask)); - __ Branch(&slow, ne, a3, Operand(1 << Map::kHasIndexedInterceptor)); + __ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset)); + __ And(scratch2, scratch2, Operand(kSlowCaseBitFieldMask)); + __ Branch(&slow, ne, scratch2, Operand(1 << Map::kHasIndexedInterceptor)); // Everything is fine, call runtime. - __ Push(a1, a0); // Receiver, key. + __ Push(receiver, key); // Receiver, key. // Perform tail call to the entry. __ TailCallExternalReference(ExternalReference( diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index dd2d67e3fd..d82033f875 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -2880,10 +2880,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->global_object()).is(a0)); + ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(v0)); - __ li(a2, Operand(instr->name())); + __ li(LoadIC::NameRegister(), Operand(instr->name())); ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3004,11 +3004,11 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(a0)); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(v0)); // Name is always in a2. - __ li(a2, Operand(instr->name())); + __ li(LoadIC::NameRegister(), Operand(instr->name())); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3327,8 +3327,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(a1)); - ASSERT(ToRegister(instr->key()).is(a0)); + ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index bcdb7dd1b3..6b75886ebd 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -2030,7 +2030,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* global_object = UseFixed(instr->global_object(), a0); + LOperand* global_object = UseFixed(instr->global_object(), + LoadIC::ReceiverRegister()); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, v0), instr); @@ -2084,7 +2085,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), a0); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(context, object), v0); return MarkAsCall(result, instr); @@ -2144,8 +2145,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), a1); - LOperand* key = UseFixed(instr->key(), a0); + LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0); diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index bc8a50cfb0..16c69d57ad 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -1470,6 +1470,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- a0 : key // -- a1 : receiver // ----------------------------------- + ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); + ASSERT(a0.is(KeyedLoadIC::NameRegister())); Label slow, miss; Register key = a0;