Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Unified Diff: src/sh4/ic-sh4.cc

Issue 11275184: First draft of the sh4 port Base URL: http://github.com/v8/v8.git@master
Patch Set: Use GYP and fixe some typos Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/sh4/full-codegen-sh4.cc ('k') | src/sh4/lithium-codegen-sh4.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/sh4/ic-sh4.cc
diff --git a/src/arm/ic-arm.cc b/src/sh4/ic-sh4.cc
similarity index 91%
copy from src/arm/ic-arm.cc
copy to src/sh4/ic-sh4.cc
index 48395897da826b34adad426cabf92407376d1075..95f16c6f5497984f54cfdaf5abb5f7d7abe34c12 100644
--- a/src/arm/ic-arm.cc
+++ b/src/sh4/ic-sh4.cc
@@ -1,4 +1,4 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2011-2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -27,9 +27,9 @@
#include "v8.h"
-#if defined(V8_TARGET_ARCH_ARM)
+#if defined(V8_TARGET_ARCH_SH4)
-#include "assembler-arm.h"
+#include "assembler-sh4.h"
#include "code-stubs.h"
#include "codegen.h"
#include "disasm.h"
@@ -47,18 +47,20 @@ namespace internal {
#define __ ACCESS_MASM(masm)
+ // ARM to SH4 mapping
+#include "map-sh4.h"
static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm,
Register type,
Label* global_object) {
// Register usage:
// type: holds the receiver instance type on entry.
- __ cmp(type, Operand(JS_GLOBAL_OBJECT_TYPE));
- __ b(eq, global_object);
- __ cmp(type, Operand(JS_BUILTINS_OBJECT_TYPE));
- __ b(eq, global_object);
- __ cmp(type, Operand(JS_GLOBAL_PROXY_TYPE));
- __ b(eq, global_object);
+ __ cmpeq(type, Operand(JS_GLOBAL_OBJECT_TYPE));
+ __ bt(global_object);
+ __ cmpeq(type, Operand(JS_BUILTINS_OBJECT_TYPE));
+ __ bt(global_object);
+ __ cmpeq(type, Operand(JS_GLOBAL_PROXY_TYPE));
+ __ bt(global_object);
}
@@ -82,8 +84,8 @@ static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm,
__ JumpIfSmi(receiver, miss);
// Check that the receiver is a valid JS object.
- __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE);
- __ b(lt, miss);
+ __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE, ge);
+ __ bf(miss);
// If this assert fails, we have to check upper bound too.
STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
@@ -94,13 +96,13 @@ static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm,
__ ldrb(t1, FieldMemOperand(t0, Map::kBitFieldOffset));
__ tst(t1, Operand((1 << Map::kIsAccessCheckNeeded) |
(1 << Map::kHasNamedInterceptor)));
- __ b(ne, miss);
+ __ bf(miss);
__ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHashTableMapRootIndex);
- __ cmp(t1, ip);
- __ b(ne, miss);
+ __ cmpeq(t1, ip);
+ __ bf(miss);
}
@@ -199,7 +201,7 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
__ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
__ tst(scratch1, Operand(kTypeAndReadOnlyMask));
- __ b(ne, miss);
+ __ bf(miss);
// Store the value at the masked, scaled index and return.
const int kValueOffset = kElementsStartOffset + kPointerSize;
@@ -283,8 +285,8 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
// objects work as intended.
ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
__ ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
- __ cmp(scratch, Operand(JS_OBJECT_TYPE));
- __ b(lt, slow);
+ __ cmpge(scratch, Operand(JS_OBJECT_TYPE));
+ __ bf(slow);
}
@@ -333,14 +335,14 @@ static void GenerateFastArrayLoad(MacroAssembler* masm,
}
// Check that the key (index) is within bounds.
__ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ cmp(key, Operand(scratch1));
- __ b(hs, out_of_range);
+ __ cmphs(key, scratch1);
+ __ bt(out_of_range);
// Fast case: Do the load.
__ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// The key is a smi.
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
- __ ldr(scratch2,
- MemOperand(scratch1, key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ lsl(scratch2, key, Operand(kPointerSizeLog2 - kSmiTagSize));
+ __ ldr(scratch2, MemOperand(scratch1, scratch2));
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
__ cmp(scratch2, ip);
// In case the loaded value is the_hole we have to consult GetProperty
@@ -360,8 +362,8 @@ static void GenerateKeyStringCheck(MacroAssembler* masm,
Label* not_symbol) {
// The key is not a smi.
// Is it a string?
- __ CompareObjectType(key, map, hash, FIRST_NONSTRING_TYPE);
- __ b(ge, not_symbol);
+ __ CompareObjectType(key, map, hash, FIRST_NONSTRING_TYPE, ge);
+ __ bt(not_symbol);
// Is the string an array index, with cached numeric value?
__ ldr(hash, FieldMemOperand(key, String::kHashFieldOffset));
@@ -407,9 +409,9 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// to probe.
//
// Check for number.
- __ JumpIfSmi(r1, &number);
- __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE);
- __ b(ne, &non_number);
+ __ JumpIfSmi(r1, &number, Label::kNear);
+ __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE, eq);
+ __ bf_near(&non_number);
__ bind(&number);
StubCompiler::GenerateLoadGlobalFunctionPrototype(
masm, Context::NUMBER_FUNCTION_INDEX, r1);
@@ -417,8 +419,8 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Check for string.
__ bind(&non_number);
- __ cmp(r3, Operand(FIRST_NONSTRING_TYPE));
- __ b(hs, &non_string);
+ __ cmphs(r3, Operand(FIRST_NONSTRING_TYPE));
+ __ bt_near(&non_string);
StubCompiler::GenerateLoadGlobalFunctionPrototype(
masm, Context::STRING_FUNCTION_INDEX, r1);
__ b(&probe);
@@ -454,8 +456,8 @@ static void GenerateFunctionTailCall(MacroAssembler* masm,
__ JumpIfSmi(r1, miss);
// Check that the value is a JSFunction.
- __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE);
- __ b(ne, miss);
+ __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE, eq);
+ __ bf(miss);
// Invoke the function.
ParameterCount actual(argc);
@@ -519,7 +521,7 @@ void CallICBase::GenerateMiss(MacroAssembler* masm,
__ CallStub(&stub);
// Move result to r1 and leave the internal frame.
- __ mov(r1, Operand(r0));
+ __ mov(r1, r0);
}
// Check if the receiver is a global object of some sort.
@@ -527,11 +529,11 @@ void CallICBase::GenerateMiss(MacroAssembler* masm,
if (id == IC::kCallIC_Miss) {
Label invoke, global;
__ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver
- __ JumpIfSmi(r2, &invoke);
- __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE);
- __ b(eq, &global);
- __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE));
- __ b(ne, &invoke);
+ __ JumpIfSmi(r2, &invoke, Label::kNear);
+ __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE, eq);
+ __ bt_near(&global);
+ __ cmpeq(r3, Operand(JS_BUILTINS_OBJECT_TYPE));
+ __ bf_near(&invoke);
// Patch the receiver on the stack.
__ bind(&global);
@@ -609,7 +611,7 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
__ LoadRoot(ip, Heap::kHashTableMapRootIndex);
__ cmp(r3, ip);
__ b(ne, &slow_load);
- __ mov(r0, Operand(r2, ASR, kSmiTagSize));
+ __ asr(r0, r2, Operand(kSmiTagSize));
// r0: untagged index
__ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5);
__ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3);
@@ -770,8 +772,8 @@ static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
// requires access checks.
__ JumpIfSmi(object, slow_case);
// Check that the object is some kind of JSObject.
- __ CompareObjectType(object, scratch1, scratch2, FIRST_JS_RECEIVER_TYPE);
- __ b(lt, slow_case);
+ __ CompareObjectType(object, scratch1, scratch2, FIRST_JS_RECEIVER_TYPE, ge);
+ __ bf(slow_case);
// Check that the key is a positive smi.
__ tst(key, Operand(0x80000001));
@@ -786,8 +788,8 @@ static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
// to the unmapped lookup with the parameter map in scratch1.
__ ldr(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
__ sub(scratch2, scratch2, Operand(Smi::FromInt(2)));
- __ cmp(key, Operand(scratch2));
- __ b(cs, unmapped_case);
+ __ cmphs(key, scratch2);
+ __ b(t, unmapped_case);
// Load element index and check whether it is the hole.
const int kOffset =
@@ -829,8 +831,8 @@ static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
__ CheckMap(backing_store, scratch, fixed_array_map, slow_case,
DONT_DO_SMI_CHECK);
__ ldr(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
- __ cmp(key, Operand(scratch));
- __ b(cs, slow_case);
+ __ cmphs(key, scratch);
+ __ b(t, slow_case);
__ mov(scratch, Operand(kPointerSize >> 1));
__ mul(scratch, key, scratch);
__ add(scratch,
@@ -999,9 +1001,9 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// r3: elements map
// r4: elements
__ LoadRoot(ip, Heap::kHashTableMapRootIndex);
- __ cmp(r3, ip);
- __ b(ne, &slow);
- __ mov(r2, Operand(r0, ASR, kSmiTagSize));
+ __ cmpeq(r3, ip);
+ __ bf(&slow);
+ __ asr(r2, r0, Operand(kSmiTagSize));
__ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5);
__ Ret();
@@ -1023,16 +1025,17 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHashTableMapRootIndex);
__ cmp(r4, ip);
- __ b(eq, &probe_dictionary);
+ __ bt(&probe_dictionary);
// Load the map of the receiver, compute the keyed lookup cache hash
// based on 32 bits of the map pointer and the string hash.
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
- __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift));
+ __ asr(r3, r2, Operand(KeyedLookupCache::kMapHashShift));
__ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset));
- __ eor(r3, r3, Operand(r4, ASR, String::kHashShift));
+ __ asr(r4, r4, Operand(String::kHashShift));
+ __ eor(r3, r3, r4);
int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
- __ And(r3, r3, Operand(mask));
+ __ land(r3, r3, Operand(mask));
// Load the key (consisting of map and symbol) from the cache and
// check for match.
@@ -1043,7 +1046,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
ExternalReference::keyed_lookup_cache_keys(isolate);
__ mov(r4, Operand(cache_keys));
- __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1));
+ __ lsl(r5, r3, Operand(kPointerSizeLog2 + 1));
+ __ add(r4, r4, r5);
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
Label try_next_entry;
@@ -1062,8 +1066,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ cmp(r2, r5);
__ b(ne, &slow);
__ ldr(r5, MemOperand(r4));
- __ cmp(r0, r5);
- __ b(ne, &slow);
+ __ cmpeq(r0, r5);
+ __ bf(&slow);
// Get field offset.
// r0 : key
@@ -1080,10 +1084,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
if (i != 0) {
__ add(r3, r3, Operand(i));
}
- __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
+ __ lsl(r6, r3, Operand(kPointerSizeLog2));
+ __ ldr(r5, MemOperand(r4, r6));
__ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset));
- __ sub(r5, r5, r6, SetCC);
- __ b(ge, &property_array_property);
+ __ sub(r5, r5, r6);
+ __ cmpge(r5, Operand(0));
+ __ bt(&property_array_property);
if (i != 0) {
__ jmp(&load_in_object_property);
}
@@ -1094,7 +1100,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset));
__ add(r6, r6, r5); // Index from start of object.
__ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag.
- __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2));
+ __ lsl(r0, r6, Operand(kPointerSizeLog2));
+ __ ldr(r0, MemOperand(r1, r0));
__ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
1, r2, r3);
__ Ret();
@@ -1103,7 +1110,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ bind(&property_array_property);
__ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset));
__ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2));
+ __ lsl(r0, r5, Operand(kPointerSizeLog2));
+ __ ldr(r0, MemOperand(r1, r0));
__ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
1, r2, r3);
__ Ret();
@@ -1171,11 +1179,11 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
Label slow;
// Check that the receiver isn't a smi.
- __ JumpIfSmi(r1, &slow);
+ __ JumpIfSmi(r1, &slow, Label::kNear);
// Check that the key is an array index, that is Uint32.
__ tst(r0, Operand(kSmiTagMask | kSmiSignMask));
- __ b(ne, &slow);
+ __ bf_near(&slow);
// Get the map of the receiver.
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
@@ -1183,9 +1191,9 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// Check that it has indexed interceptor and access checks
// are not enabled for this object.
__ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
- __ and_(r3, r3, Operand(kSlowCaseBitFieldMask));
- __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor));
- __ b(ne, &slow);
+ __ land(r3, r3, Operand(kSlowCaseBitFieldMask));
+ __ cmpeq(r3, Operand(1 << Map::kHasIndexedInterceptor));
+ __ bf_near(&slow);
// Everything is fine, call runtime.
__ Push(r1, r0); // Receiver, key.
@@ -1339,7 +1347,8 @@ static void KeyedStoreGenerateGenericHelper(
}
// It's irrelevant whether array is smi-only or not when writing a smi.
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ lsl(scratch_value, address, Operand(kPointerSizeLog2 - kSmiTagSize));
+ __ add(address, address, scratch_value);
__ str(value, MemOperand(address));
__ Ret();
@@ -1356,7 +1365,8 @@ static void KeyedStoreGenerateGenericHelper(
__ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ lsl(scratch_value, key, Operand(kPointerSizeLog2 - kSmiTagSize));
+ __ add(address, address, scratch_value);
__ str(value, MemOperand(address));
// Update write barrier for the elements array address.
__ mov(scratch_value, value); // Preserve the value which is returned.
@@ -1461,30 +1471,30 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// r4 and r5 are used as general scratch registers.
// Check that the key is a smi.
- __ JumpIfNotSmi(key, &slow);
+ __ JumpIfNotSmi(key, &slow, Label::kNear);
// Check that the object isn't a smi.
- __ JumpIfSmi(receiver, &slow);
+ __ JumpIfSmi(receiver, &slow, Label::kNear);
// Get the map of the object.
__ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
// Check that the receiver does not require access checks. We need
// to do this because this generic stub does not perform map checks.
__ ldrb(ip, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
__ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded));
- __ b(ne, &slow);
+ __ bf_near(&slow);
// Check if the object is a JS array or not.
__ ldrb(r4, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
__ cmp(r4, Operand(JS_ARRAY_TYPE));
__ b(eq, &array);
// Check that the object is some kind of JSObject.
- __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
- __ b(lt, &slow);
+ __ cmpge(r4, Operand(FIRST_JS_OBJECT_TYPE));
+ __ bf_near(&slow);
// Object case: Check key against length in the elements array.
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
// Check array bounds. Both the key and the length of FixedArray are smis.
__ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ cmp(key, Operand(ip));
- __ b(lo, &fast_object);
+ __ cmphs(key, ip);
+ __ bf(&fast_object);
// Slow case, handle jump to runtime.
__ bind(&slow);
@@ -1499,12 +1509,14 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// element to the array by writing to array[array.length].
__ bind(&extra);
// Condition code from comparing key and array length is still available.
- __ b(ne, &slow); // Only support writing to writing to array[array.length].
+ __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
+ __ cmpeq(key, ip);
+ __ bf(&slow); // Only support writing to writing to array[array.length].
// Check for room in the elements backing store.
// Both the key and the length of FixedArray are smis.
__ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ cmp(key, Operand(ip));
- __ b(hs, &slow);
+ __ cmphs(key, ip);
+ __ bt(&slow);
__ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
__ cmp(elements_map,
Operand(masm->isolate()->factory()->fixed_array_map()));
@@ -1525,8 +1537,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// Check the key against the length in the array.
__ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ cmp(key, Operand(ip));
- __ b(hs, &extra);
+ __ cmphs(key, ip);
+ __ bt(&extra);
+ // Fall through to fast case.
KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
&slow, kCheckMap, kDontIncrementLength,
@@ -1600,14 +1613,14 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
__ JumpIfSmi(receiver, &miss);
// Check that the object is a JS array.
- __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
- __ b(ne, &miss);
+ __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE, eq);
+ __ bf(&miss);
// Check that elements are FixedArray.
// We rely on StoreIC_ArrayLength below to deal with all types of
// fast elements (including COW).
__ ldr(scratch, FieldMemOperand(receiver, JSArray::kElementsOffset));
- __ CompareObjectType(scratch, scratch, scratch, FIXED_ARRAY_TYPE);
+ __ CompareObjectType(scratch, scratch, scratch, FIXED_ARRAY_TYPE, eq);
__ b(ne, &miss);
// Check that the array has fast properties, otherwise the length
@@ -1734,9 +1747,9 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
Address cmp_instruction_address =
- Assembler::return_address_from_call_start(address);
+ address + Assembler::kCallTargetAddressOffset;
- // If the instruction following the call is not a cmp rx, #yyy, nothing
+ // If the instruction following the call is not a cmp #ii, rx, nothing
// was inlined.
Instr instr = Assembler::instr_at(cmp_instruction_address);
if (!Assembler::IsCmpImmediate(instr)) {
@@ -1745,10 +1758,11 @@ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
// The delta to the start of the map check instruction and the
// condition code uses at the patched jump.
- int delta = Assembler::GetCmpImmediateRawImmediate(instr);
- delta +=
- Assembler::GetCmpImmediateRegister(instr).code() * kOff12Mask;
- // If the delta is 0 the instruction is cmp r0, #0 which also signals that
+ int delta = Assembler::GetCmpImmediateAsUnsigned(instr);
+ // TODO(stm): is this needed for ST40 ?
+ // delta += Assembler::GetCmpImmediateRegister(instr).code() * kOff12Mask
+
+ // If the delta is 0 the instruction is cmp #0, r0 which also signals that
// nothing was inlined.
if (delta == 0) {
return;
@@ -1762,36 +1776,57 @@ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
#endif
Address patch_address =
- cmp_instruction_address - delta * Instruction::kInstrSize;
+ cmp_instruction_address - delta * Assembler::kInstrSize;
Instr instr_at_patch = Assembler::instr_at(patch_address);
+#ifdef DEBUG
+ Instr instr_before_patch =
+ Assembler::instr_at(patch_address - Assembler::kInstrSize);
+#endif
Instr branch_instr =
- Assembler::instr_at(patch_address + Instruction::kInstrSize);
- // This is patching a conditional "jump if not smi/jump if smi" site.
- // Enabling by changing from
- // cmp rx, rx
- // b eq/ne, <target>
- // to
- // tst rx, #kSmiTagMask
- // b ne/eq, <target>
- // and vice-versa to be disabled again.
- CodePatcher patcher(patch_address, 2);
- Register reg = Assembler::GetRn(instr_at_patch);
- if (check == ENABLE_INLINED_SMI_CHECK) {
- ASSERT(Assembler::IsCmpRegister(instr_at_patch));
- ASSERT_EQ(Assembler::GetRn(instr_at_patch).code(),
- Assembler::GetRm(instr_at_patch).code());
- patcher.masm()->tst(reg, Operand(kSmiTagMask));
- } else {
- ASSERT(check == DISABLE_INLINED_SMI_CHECK);
- ASSERT(Assembler::IsTstImmediate(instr_at_patch));
- patcher.masm()->cmp(reg, reg);
- }
+ Assembler::instr_at(patch_address + Assembler::kInstrSize);
+ ASSERT(Assembler::IsCmpRegister(instr_at_patch));
+ ASSERT_EQ(Assembler::GetRn(instr_at_patch).code(),
+ Assembler::GetRm(instr_at_patch).code());
+ ASSERT(Assembler::IsMovImmediate(instr_before_patch));
+ ASSERT_EQ(Assembler::GetRn(instr_before_patch).code(), sh4_ip.code());
ASSERT(Assembler::IsBranch(branch_instr));
- if (Assembler::GetCondition(branch_instr) == eq) {
- patcher.EmitCondition(ne);
+ if (Assembler::GetCondition(branch_instr) == f) {
+ // This is patching a "jump if not smi" site to be active.
+ // Changing
+ // mov #kSmiTagMask, sh4_ip
+ // cmp rx, rx
+ // bf <skip> // actually a bt <target>
+ // ...
+ // bra <target>
+ // skip:
+ // to
+ // mov #kSmiTagMask, sh4_ip
+ // tst rx, sh4_ip
+ // bt <skip> // actually implements a bf <target>
+ // ...
+ CodePatcher patcher(patch_address, 2);
+ Register reg = Assembler::GetRn(instr_at_patch);
+ patcher.masm()->tst(reg, sh4_ip);
+ patcher.EmitCondition(t);
} else {
- ASSERT(Assembler::GetCondition(branch_instr) == ne);
- patcher.EmitCondition(eq);
+ ASSERT(Assembler::GetCondition(branch_instr) == t);
+ // This is patching a "jump if smi" site to be active.
+ // Changing
+ // mov #kSmiTagMask, sh4_ip
+ // cmp rx, rx
+ // bt <skip> // actually a bf <target>
+ // ...
+ // bra <target>
+ // skip:
+ // to
+ // mov #kSmiTagMask, sh4_ip
+ // tst rx, sh4_ip
+ // bf <target>
+ // ...
+ CodePatcher patcher(patch_address, 2);
+ Register reg = Assembler::GetRn(instr_at_patch);
+ patcher.masm()->tst(reg, sh4_ip);
+ patcher.EmitCondition(f);
}
}
« no previous file with comments | « src/sh4/full-codegen-sh4.cc ('k') | src/sh4/lithium-codegen-sh4.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698