Index: src/ic/ppc/handler-compiler-ppc.cc |
diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/ppc/handler-compiler-ppc.cc |
similarity index 87% |
copy from src/ic/arm/handler-compiler-arm.cc |
copy to src/ic/ppc/handler-compiler-ppc.cc |
index e49abf25cb37e499e1d7a15fdd38118ac12a0783..248c67a94c3e3ffed9ff599d3b15cb95f64ebcec 100644 |
--- a/src/ic/arm/handler-compiler-arm.cc |
+++ b/src/ic/ppc/handler-compiler-ppc.cc |
@@ -1,13 +1,16 @@ |
// Copyright 2014 the V8 project authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+// |
+// Copyright IBM Corp. 2012, 2013. All rights reserved. |
#include "src/v8.h" |
-#if V8_TARGET_ARCH_ARM |
+#if V8_TARGET_ARCH_PPC |
#include "src/ic/call-optimization.h" |
#include "src/ic/handler-compiler.h" |
+#include "src/ic/ic.h" |
namespace v8 { |
namespace internal { |
@@ -19,8 +22,8 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
Handle<JSFunction> getter) { |
// ----------- S t a t e ------------- |
- // -- r0 : receiver |
- // -- r2 : name |
+ // -- r3 : receiver |
+ // -- r5 : name |
// -- lr : return address |
// ----------------------------------- |
{ |
@@ -30,8 +33,8 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
// Call the JavaScript getter with the receiver on the stack. |
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
// Swap in the global receiver. |
- __ ldr(receiver, |
- FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
+ __ LoadP(receiver, |
+ FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
} |
__ push(receiver); |
ParameterCount actual(0); |
@@ -45,7 +48,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
} |
// Restore context register. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
} |
__ Ret(); |
} |
@@ -67,8 +70,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
// Call the JavaScript setter with receiver and value on the stack. |
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
// Swap in the global receiver. |
- __ ldr(receiver, |
- FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
+ __ LoadP(receiver, |
+ FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
} |
__ Push(receiver, value()); |
ParameterCount actual(1); |
@@ -82,10 +85,10 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
} |
// We have to return the passed value, not the return value of the setter. |
- __ pop(r0); |
+ __ pop(r3); |
// Restore context register. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
} |
__ Ret(); |
} |
@@ -107,28 +110,28 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
// Bail out if the receiver has a named interceptor or requires access checks. |
Register map = scratch1; |
- __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
- __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); |
- __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); |
- __ b(ne, miss_label); |
+ __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
+ __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); |
+ __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); |
+ __ bne(miss_label, cr0); |
// Check that receiver is a JSObject. |
- __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
- __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
- __ b(lt, miss_label); |
+ __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
+ __ cmpi(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
+ __ blt(miss_label); |
// Load properties array. |
Register properties = scratch0; |
- __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
+ __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
// Check that the properties array is a dictionary. |
- __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
+ __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
Register tmp = properties; |
__ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
__ cmp(map, tmp); |
- __ b(ne, miss_label); |
+ __ bne(miss_label); |
// Restore the temporarily used register. |
- __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
+ __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
NameDictionaryLookupStub::GenerateNegativeLookup( |
@@ -148,17 +151,18 @@ void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
// Check we're still in the same context. |
Register scratch = prototype; |
const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); |
- __ ldr(scratch, MemOperand(cp, offset)); |
- __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); |
- __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index))); |
+ __ LoadP(scratch, MemOperand(cp, offset)); |
+ __ LoadP(scratch, |
+ FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); |
+ __ LoadP(scratch, MemOperand(scratch, Context::SlotOffset(index))); |
__ Move(ip, function); |
__ cmp(ip, scratch); |
- __ b(ne, miss); |
+ __ bne(miss); |
// Load its initial map. The global functions all have initial maps. |
__ Move(prototype, Handle<Map>(function->initial_map())); |
// Load the prototype from the initial map. |
- __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
+ __ LoadP(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
} |
@@ -166,7 +170,7 @@ void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( |
MacroAssembler* masm, Register receiver, Register scratch1, |
Register scratch2, Label* miss_label) { |
__ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
- __ mov(r0, scratch1); |
+ __ mr(r3, scratch1); |
__ Ret(); |
} |
@@ -180,10 +184,10 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); |
DCHECK(cell->value()->IsTheHole()); |
__ mov(scratch, Operand(cell)); |
- __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); |
+ __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); |
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
__ cmp(scratch, ip); |
- __ b(ne, miss); |
+ __ bne(miss); |
} |
@@ -232,10 +236,10 @@ void PropertyHandlerCompiler::GenerateFastApiCall( |
DCHECK(optimization.is_simple_api_call()); |
// Abi for CallApiFunctionStub. |
- Register callee = r0; |
- Register call_data = r4; |
- Register holder = r2; |
- Register api_function_address = r1; |
+ Register callee = r3; |
+ Register call_data = r7; |
+ Register holder = r5; |
+ Register api_function_address = r4; |
// Put holder in place. |
CallOptimization::HolderLookup holder_lookup; |
@@ -265,7 +269,8 @@ void PropertyHandlerCompiler::GenerateFastApiCall( |
// Put call_data in place. |
if (isolate->heap()->InNewSpace(*call_data_obj)) { |
__ Move(call_data, api_call_info); |
- __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); |
+ __ LoadP(call_data, |
+ FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); |
} else if (call_data_obj->IsUndefined()) { |
call_data_undefined = true; |
__ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
@@ -325,7 +330,7 @@ void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
} |
-// Generate StoreTransition code, value is passed in r0 register. |
+// Generate StoreTransition code, value is passed in r3 register. |
// When leaving generated code after success, the receiver_reg and name_reg |
// may be clobbered. Upon branch to miss_label, the receiver and name |
// registers have their original values. |
@@ -333,7 +338,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
Handle<Map> transition, Handle<Name> name, Register receiver_reg, |
Register storage_reg, Register value_reg, Register scratch1, |
Register scratch2, Register scratch3, Label* miss_label, Label* slow) { |
- // r0 : value |
+ // r3 : value |
Label exit; |
int descriptor = transition->LastAdded(); |
@@ -346,7 +351,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); |
__ Move(scratch1, constant); |
__ cmp(value_reg, scratch1); |
- __ b(ne, miss_label); |
+ __ bne(miss_label); |
} else if (representation.IsSmi()) { |
__ JumpIfNotSmi(value_reg, miss_label); |
} else if (representation.IsHeapObject()) { |
@@ -354,16 +359,16 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
HeapType* field_type = descriptors->GetFieldType(descriptor); |
HeapType::Iterator<Map> it = field_type->Classes(); |
if (!it.Done()) { |
- __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
+ __ LoadP(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
Label do_store; |
while (true) { |
__ CompareMap(scratch1, it.Current(), &do_store); |
it.Advance(); |
if (it.Done()) { |
- __ b(ne, miss_label); |
+ __ bne(miss_label); |
break; |
} |
- __ b(eq, &do_store); |
+ __ beq(&do_store); |
} |
__ bind(&do_store); |
} |
@@ -375,17 +380,16 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
__ JumpIfNotSmi(value_reg, &heap_number); |
__ SmiUntag(scratch1, value_reg); |
- __ vmov(s0, scratch1); |
- __ vcvt_f64_s32(d0, s0); |
+ __ ConvertIntToDouble(scratch1, d0); |
__ jmp(&do_store); |
__ bind(&heap_number); |
__ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label, |
DONT_DO_SMI_CHECK); |
- __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
+ __ lfd(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
__ bind(&do_store); |
- __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
+ __ stfd(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); |
} |
// Stub never generated for objects that require access checks. |
@@ -397,8 +401,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
// The properties must be extended before we can store the value. |
// We jump to a runtime call that extends the properties array. |
__ push(receiver_reg); |
- __ mov(r2, Operand(transition)); |
- __ Push(r2, r0); |
+ __ mov(r5, Operand(transition)); |
+ __ Push(r5, r3); |
__ TailCallExternalReference( |
ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
isolate()), |
@@ -408,7 +412,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
// Update the map of the object. |
__ mov(scratch1, Operand(transition)); |
- __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
+ __ StoreP(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset), |
+ r0); |
// Update the write barrier for the map field. |
__ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, |
@@ -416,7 +421,7 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
OMIT_SMI_CHECK); |
if (details.type() == CONSTANT) { |
- DCHECK(value_reg.is(r0)); |
+ DCHECK(value_reg.is(r3)); |
__ Ret(); |
return; |
} |
@@ -436,15 +441,15 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
// Set the property straight into the object. |
int offset = transition->instance_size() + (index * kPointerSize); |
if (representation.IsDouble()) { |
- __ str(storage_reg, FieldMemOperand(receiver_reg, offset)); |
+ __ StoreP(storage_reg, FieldMemOperand(receiver_reg, offset), r0); |
} else { |
- __ str(value_reg, FieldMemOperand(receiver_reg, offset)); |
+ __ StoreP(value_reg, FieldMemOperand(receiver_reg, offset), r0); |
} |
if (!representation.IsSmi()) { |
// Update the write barrier for the array address. |
if (!representation.IsDouble()) { |
- __ mov(storage_reg, value_reg); |
+ __ mr(storage_reg, value_reg); |
} |
__ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, |
kLRHasNotBeenSaved, kDontSaveFPRegs, |
@@ -454,18 +459,18 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
// Write to the properties array. |
int offset = index * kPointerSize + FixedArray::kHeaderSize; |
// Get the properties array |
- __ ldr(scratch1, |
- FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); |
+ __ LoadP(scratch1, |
+ FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); |
if (representation.IsDouble()) { |
- __ str(storage_reg, FieldMemOperand(scratch1, offset)); |
+ __ StoreP(storage_reg, FieldMemOperand(scratch1, offset), r0); |
} else { |
- __ str(value_reg, FieldMemOperand(scratch1, offset)); |
+ __ StoreP(value_reg, FieldMemOperand(scratch1, offset), r0); |
} |
if (!representation.IsSmi()) { |
// Update the write barrier for the array address. |
if (!representation.IsDouble()) { |
- __ mov(storage_reg, value_reg); |
+ __ mr(storage_reg, value_reg); |
} |
__ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, |
kLRHasNotBeenSaved, kDontSaveFPRegs, |
@@ -473,8 +478,8 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition( |
} |
} |
- // Return the value (register r0). |
- DCHECK(value_reg.is(r0)); |
+ // Return the value (register r3). |
+ DCHECK(value_reg.is(r3)); |
__ bind(&exit); |
__ Ret(); |
} |
@@ -486,16 +491,16 @@ void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, |
DCHECK(lookup->representation().IsHeapObject()); |
__ JumpIfSmi(value_reg, miss_label); |
HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes(); |
- __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
+ __ LoadP(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset)); |
Label do_store; |
while (true) { |
__ CompareMap(scratch1(), it.Current(), &do_store); |
it.Advance(); |
if (it.Done()) { |
- __ b(ne, miss_label); |
+ __ bne(miss_label); |
break; |
} |
- __ b(eq, &do_store); |
+ __ beq(&do_store); |
} |
__ bind(&do_store); |
@@ -552,16 +557,16 @@ Register PropertyHandlerCompiler::CheckPrototypes( |
GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, |
scratch2); |
- __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
+ __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
reg = holder_reg; // From now on the object will be in holder_reg. |
- __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
+ __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
} else { |
Register map_reg = scratch1; |
if (depth != 1 || check == CHECK_ALL_MAPS) { |
// CheckMap implicitly loads the map of |reg| into |map_reg|. |
__ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); |
} else { |
- __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
+ __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); |
} |
// Check access rights to the global object. This has to happen after |
@@ -586,7 +591,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( |
bool load_prototype_from_map = |
heap()->InNewSpace(*prototype) || depth == 1; |
if (load_prototype_from_map) { |
- __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
+ __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); |
} else { |
__ mov(reg, Operand(prototype)); |
} |
@@ -641,7 +646,7 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { |
// Return the constant value. |
- __ Move(r0, value); |
+ __ Move(r3, value); |
__ Ret(); |
} |
@@ -663,18 +668,17 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback( |
__ push(receiver()); |
if (heap()->InNewSpace(callback->data())) { |
__ Move(scratch3(), callback); |
- __ ldr(scratch3(), |
- FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset)); |
+ __ LoadP(scratch3(), |
+ FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset)); |
} else { |
__ Move(scratch3(), Handle<Object>(callback->data(), isolate())); |
} |
__ push(scratch3()); |
__ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); |
- __ mov(scratch4(), scratch3()); |
+ __ mr(scratch4(), scratch3()); |
__ Push(scratch3(), scratch4()); |
__ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate()))); |
__ Push(scratch4(), reg); |
- __ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_ |
__ push(name()); |
// Abi for CallApiGetter |
@@ -731,8 +735,8 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( |
// the case, return immediately. |
Label interceptor_failed; |
__ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); |
- __ cmp(r0, scratch1()); |
- __ b(eq, &interceptor_failed); |
+ __ cmp(r3, scratch1()); |
+ __ beq(&interceptor_failed); |
frame_scope.GenerateLeaveFrame(); |
__ Ret(); |
@@ -768,9 +772,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
Handle<ExecutableAccessorInfo> callback) { |
Register holder_reg = Frontend(receiver(), name); |
- __ push(receiver()); // receiver |
- __ push(holder_reg); |
- __ mov(ip, Operand(callback)); // callback info |
+ __ Push(receiver(), holder_reg); // receiver |
+ __ mov(ip, Operand(callback)); // callback info |
__ push(ip); |
__ mov(ip, Operand(name)); |
__ Push(ip, value()); |
@@ -812,17 +815,17 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
// Get the value from the cell. |
Register result = StoreDescriptor::ValueRegister(); |
__ mov(result, Operand(cell)); |
- __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); |
+ __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset)); |
// Check for deleted property if property can actually be deleted. |
- if (is_configurable) { |
+ if (!is_configurable) { |
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
__ cmp(result, ip); |
- __ b(eq, &miss); |
+ __ beq(&miss); |
} |
Counters* counters = isolate()->counters(); |
- __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
+ __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6); |
__ Ret(); |
FrontendFooter(name, &miss); |