Index: src/sh4/builtins-sh4.cc |
diff --git a/src/arm/builtins-arm.cc b/src/sh4/builtins-sh4.cc |
similarity index 90% |
copy from src/arm/builtins-arm.cc |
copy to src/sh4/builtins-sh4.cc |
index 2d1d7b1199712556880ac857eec03ab7facc2aa6..f8c34cebb6a1d56d9bf0f2886e4f23ab4054b07c 100644 |
--- a/src/arm/builtins-arm.cc |
+++ b/src/sh4/builtins-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,7 +27,7 @@ |
#include "v8.h" |
-#if defined(V8_TARGET_ARCH_ARM) |
+#if defined(V8_TARGET_ARCH_SH4) |
#include "codegen.h" |
#include "debug.h" |
@@ -42,6 +42,10 @@ namespace internal { |
#define __ ACCESS_MASM(masm) |
+// Define register map |
+#include "map-sh4.h" |
+ |
+ |
void Builtins::Generate_Adaptor(MacroAssembler* masm, |
CFunctionId id, |
BuiltinExtraArguments extra_args) { |
@@ -185,8 +189,8 @@ static void AllocateEmptyJSArray(MacroAssembler* masm, |
__ bind(&loop); |
__ str(scratch3, MemOperand(scratch1, kPointerSize, PostIndex)); |
__ bind(&entry); |
- __ cmp(scratch1, scratch2); |
- __ b(lt, &loop); |
+ __ cmpge(scratch1, scratch2); |
+ __ bf(&loop); |
} |
} |
@@ -223,9 +227,10 @@ static void AllocateJSArray(MacroAssembler* masm, |
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
__ mov(elements_array_end, |
Operand((JSArray::kSize + FixedArray::kHeaderSize) / kPointerSize)); |
+ __ asr(scratch1, array_size, Operand(kSmiTagSize)); |
__ add(elements_array_end, |
elements_array_end, |
- Operand(array_size, ASR, kSmiTagSize)); |
+ scratch1); |
__ AllocateInNewSpace( |
elements_array_end, |
result, |
@@ -277,9 +282,11 @@ static void AllocateJSArray(MacroAssembler* masm, |
// elements_array_storage: elements array element storage |
// array_size: smi-tagged size of elements array |
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
+ __ lsl(elements_array_end, array_size, |
+ Operand(kPointerSizeLog2 - kSmiTagSize)); |
__ add(elements_array_end, |
elements_array_storage, |
- Operand(array_size, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ elements_array_end); |
// Fill the allocated FixedArray with the hole value if requested. |
// result: JSObject |
@@ -288,13 +295,13 @@ static void AllocateJSArray(MacroAssembler* masm, |
if (fill_with_hole) { |
Label loop, entry; |
__ LoadRoot(scratch1, Heap::kTheHoleValueRootIndex); |
- __ jmp(&entry); |
+ __ jmp_near(&entry); |
__ bind(&loop); |
__ str(scratch1, |
MemOperand(elements_array_storage, kPointerSize, PostIndex)); |
__ bind(&entry); |
- __ cmp(elements_array_storage, elements_array_end); |
- __ b(lt, &loop); |
+ __ cmpge(elements_array_storage, elements_array_end); |
+ __ bf(&loop); |
} |
} |
@@ -335,7 +342,7 @@ static void ArrayNativeCode(MacroAssembler* masm, |
// Set up return value, remove receiver from stack and return. |
__ mov(r0, r2); |
__ add(sp, sp, Operand(kPointerSize)); |
- __ Jump(lr); |
+ __ Ret(); |
// Check for one argument. Bail out if argument is not smi or if it is |
// negative. |
@@ -351,14 +358,15 @@ static void ArrayNativeCode(MacroAssembler* masm, |
__ b(&empty_array); |
__ bind(¬_empty_array); |
- __ and_(r3, r2, Operand(kIntptrSignBit | kSmiTagMask), SetCC); |
+ __ land(r3, r2, Operand(kIntptrSignBit | kSmiTagMask)); |
+ __ cmp(r3, Operand(0)); |
__ b(ne, call_generic_code); |
// Handle construction of an empty array of a certain size. Bail out if size |
// is too large to actually allocate an elements array. |
STATIC_ASSERT(kSmiTag == 0); |
- __ cmp(r2, Operand(JSObject::kInitialMaxFastElementArray << kSmiTagSize)); |
- __ b(ge, call_generic_code); |
+ __ cmpge(r2, Operand(JSObject::kInitialMaxFastElementArray << kSmiTagSize)); |
+ __ bt(call_generic_code); |
// r0: argc |
// r1: constructor |
@@ -375,14 +383,14 @@ static void ArrayNativeCode(MacroAssembler* masm, |
true, |
call_generic_code); |
__ IncrementCounter(counters->array_function_native(), 1, r2, r4); |
- // Set up return value, remove receiver and argument from stack and return. |
+ // Setup return value, remove receiver and argument from stack and return. |
__ mov(r0, r3); |
__ add(sp, sp, Operand(2 * kPointerSize)); |
- __ Jump(lr); |
+ __ Ret(); |
// Handle construction of an array from a list of arguments. |
__ bind(&argc_two_or_more); |
- __ mov(r2, Operand(r0, LSL, kSmiTagSize)); // Convet argc to a smi. |
+ __ lsl(r2, r0, Operand(kSmiTagSize)); // Convet argc to a smi. |
// r0: argc |
// r1: constructor |
@@ -419,8 +427,8 @@ static void ArrayNativeCode(MacroAssembler* masm, |
} |
__ str(r2, MemOperand(r5, -kPointerSize, PreIndex)); |
__ bind(&entry); |
- __ cmp(r4, r5); |
- __ b(lt, &loop); |
+ __ cmpge(r4, r5); |
+ __ bf(&loop); |
__ bind(&finish); |
__ mov(sp, r7); |
@@ -432,7 +440,7 @@ static void ArrayNativeCode(MacroAssembler* masm, |
// sp[0]: receiver |
__ add(sp, sp, Operand(kPointerSize)); |
__ mov(r0, r3); |
- __ Jump(lr); |
+ __ Ret(); |
__ bind(&has_non_smi_element); |
// Double values are handled by the runtime. |
@@ -465,8 +473,8 @@ static void ArrayNativeCode(MacroAssembler* masm, |
__ bind(&loop2); |
__ ldr(r2, MemOperand(r7, kPointerSize, PostIndex)); |
__ str(r2, MemOperand(r5, -kPointerSize, PreIndex)); |
- __ cmp(r4, r5); |
- __ b(lt, &loop2); |
+ __ cmpge(r4, r5); |
+ __ bf(&loop2); |
__ b(&finish); |
} |
@@ -487,7 +495,7 @@ void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
__ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
__ tst(r2, Operand(kSmiTagMask)); |
__ Assert(ne, "Unexpected initial map for InternalArray function"); |
- __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE, eq); |
__ Assert(eq, "Unexpected initial map for InternalArray function"); |
} |
@@ -521,7 +529,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
__ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
__ tst(r2, Operand(kSmiTagMask)); |
__ Assert(ne, "Unexpected initial map for Array function"); |
- __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE, eq); |
__ Assert(eq, "Unexpected initial map for Array function"); |
} |
@@ -554,7 +562,7 @@ void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { |
__ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
__ tst(r2, Operand(kSmiTagMask)); |
__ Assert(ne, "Unexpected initial map for Array function"); |
- __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE, eq); |
__ Assert(eq, "Unexpected initial map for Array function"); |
} |
@@ -584,7 +592,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { |
Register function = r1; |
if (FLAG_debug_code) { |
__ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2); |
- __ cmp(function, Operand(r2)); |
+ __ cmp(function, r2); |
__ Assert(eq, "Unexpected String function"); |
} |
@@ -594,7 +602,8 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { |
__ b(eq, &no_arguments); |
// First args = sp[(argc - 1) * 4]. |
__ sub(r0, r0, Operand(1)); |
- __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
+ __ lsl(r0, r0, Operand(kPointerSizeLog2)); |
+ __ ldr(r0, MemOperand(sp, r0)); |
// sp now point to args[0], drop args[0] + receiver. |
__ Drop(2); |
@@ -703,7 +712,7 @@ static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
__ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
__ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); |
__ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
- __ mov(pc, r2); |
+ __ jmp(r2); |
} |
@@ -756,7 +765,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
FrameScope scope(masm, StackFrame::CONSTRUCT); |
// Preserve the two incoming parameters on the stack. |
- __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
+ __ lsl(r0, r0, Operand(kSmiTagSize)); |
__ push(r0); // Smi-tagged arguments count. |
__ push(r1); // Constructor function. |
@@ -774,20 +783,20 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
__ b(ne, &rt_call); |
#endif |
- // Load the initial map and verify that it is in fact a map. |
- // r1: constructor function |
- __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
- __ JumpIfSmi(r2, &rt_call); |
- __ CompareObjectType(r2, r3, r4, MAP_TYPE); |
- __ b(ne, &rt_call); |
+ // Load the initial map and verify that it is in fact a map. |
+ // r1: constructor function |
+ __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
+ __ JumpIfSmi(r2, &rt_call); |
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE, eq); |
+ __ b(ne, &rt_call); |
- // Check that the constructor is not constructing a JSFunction (see |
- // comments in Runtime_NewObject in runtime.cc). In which case the |
- // initial map's instance type would be JS_FUNCTION_TYPE. |
- // r1: constructor function |
- // r2: initial map |
- __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE); |
- __ b(eq, &rt_call); |
+ // Check that the constructor is not constructing a JSFunction (see comments |
+ // in Runtime_NewObject in runtime.cc). In which case the initial map's |
+ // instance type would be JS_FUNCTION_TYPE. |
+ // r1: constructor function |
+ // r2: initial map |
+ __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE, eq); |
+ __ b(eq, &rt_call); |
if (count_constructions) { |
Label allocate; |
@@ -796,7 +805,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
MemOperand constructor_count = |
FieldMemOperand(r3, SharedFunctionInfo::kConstructionCountOffset); |
__ ldrb(r4, constructor_count); |
- __ sub(r4, r4, Operand(1), SetCC); |
+ __ sub(r4, r4, Operand(1)); |
+ __ cmpeq(r4, Operand(0)); |
__ strb(r4, constructor_count); |
__ b(ne, &allocate); |
@@ -839,18 +849,20 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
// r3: object size (in words) |
// r4: JSObject (not tagged) |
// r5: First in-object property of JSObject (not tagged) |
- __ add(r6, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object. |
+ __ lsl(r6, r3, Operand(kPointerSizeLog2)); |
+ __ add(r6, r4, r6); // End of object. |
ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); |
__ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
if (count_constructions) { |
__ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); |
__ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, |
kBitsPerByte); |
- __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r0, r0, Operand(kPointerSizeLog2)); |
+ __ add(r0, r5, r0); |
// r0: offset of first field after pre-allocated fields |
if (FLAG_debug_code) { |
- __ cmp(r0, r6); |
- __ Assert(le, "Unexpected number of pre-allocated property fields."); |
+ __ cmpgt(r0, r6); |
+ __ Assert(ne, "Unexpected number of pre-allocated property fields."); |
} |
__ InitializeFieldsWithFiller(r5, r0, r7); |
// To allow for truncation. |
@@ -875,14 +887,16 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
__ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); |
__ Ubfx(r6, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, |
kBitsPerByte); |
- __ add(r3, r3, Operand(r6)); |
+ __ add(r3, r3, r6); |
__ Ubfx(r6, r0, Map::kInObjectPropertiesByte * kBitsPerByte, |
kBitsPerByte); |
- __ sub(r3, r3, Operand(r6), SetCC); |
+ __ sub(r3, r3, r6); |
+ __ cmpeq(r6, Operand(0)); |
// Done if no extra properties are to be allocated. |
__ b(eq, &allocated); |
- __ Assert(pl, "Property allocation count failed."); |
+ __ cmpge(r6, Operand(0)); |
+ __ Assert(eq, "Property allocation count failed."); |
// Scale the number of elements by pointer size and add the header for |
// FixedArrays to the start of the next object calculation from above. |
@@ -909,7 +923,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset); |
__ str(r6, MemOperand(r2, kPointerSize, PostIndex)); |
ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset); |
- __ mov(r0, Operand(r3, LSL, kSmiTagSize)); |
+ __ lsl(r0, r3, Operand(kSmiTagSize)); |
__ str(r0, MemOperand(r2, kPointerSize, PostIndex)); |
// Initialize the fields to undefined. |
@@ -918,22 +932,23 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
// r3: number of elements in properties array |
// r4: JSObject |
// r5: FixedArray (not tagged) |
- __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2)); // End of object. |
+ __ lsl(r6, r3, Operand(kPointerSizeLog2)); |
+ __ add(r6, r2, r6); // End of object. |
ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize); |
{ Label loop, entry; |
if (count_constructions) { |
__ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
} else if (FLAG_debug_code) { |
- __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); |
- __ cmp(r7, r8); |
+ __ LoadRoot(cp, Heap::kUndefinedValueRootIndex); |
+ __ cmp(r7, cp); |
__ Assert(eq, "Undefined value not loaded."); |
} |
__ b(&entry); |
__ bind(&loop); |
__ str(r7, MemOperand(r2, kPointerSize, PostIndex)); |
__ bind(&entry); |
- __ cmp(r2, r6); |
- __ b(lt, &loop); |
+ __ cmpge(r2, r6); |
+ __ bf(&loop); |
} |
// Store the initialized FixedArray into the properties field of |
@@ -982,7 +997,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
__ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); |
// Set up number of arguments for function call below |
- __ mov(r0, Operand(r3, LSR, kSmiTagSize)); |
+ __ lsr(r0, r3, Operand(kSmiTagSize)); |
// Copy arguments and receiver to the expression stack. |
// r0: number of arguments |
@@ -996,11 +1011,13 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
Label loop, entry; |
__ b(&entry); |
__ bind(&loop); |
- __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); |
+ __ lsl(ip, r3, Operand(kPointerSizeLog2 - 1)); |
+ __ ldr(ip, MemOperand(r2, ip)); |
__ push(ip); |
__ bind(&entry); |
- __ sub(r3, r3, Operand(2), SetCC); |
- __ b(ge, &loop); |
+ __ sub(r3, r3, Operand(2)); |
+ __ cmpge(r3, Operand(0)); |
+ __ bt(&loop); |
// Call the function. |
// r0: number of arguments |
@@ -1044,8 +1061,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
// If the type of the result (stored in its map) is less than |
// FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. |
- __ CompareObjectType(r0, r3, r3, FIRST_SPEC_OBJECT_TYPE); |
- __ b(ge, &exit); |
+ __ CompareObjectType(r0, r3, r3, FIRST_SPEC_OBJECT_TYPE, ge); |
+ __ bt(&exit); |
// Throw away the result of the constructor invocation and use the |
// on-stack receiver as the result. |
@@ -1064,10 +1081,11 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
// Leave construct frame. |
} |
- __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); |
+ __ lsl(ip, r1, Operand(kPointerSizeLog2 - 1)); |
+ __ add(sp, sp, ip); |
__ add(sp, sp, Operand(kPointerSize)); |
__ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2); |
- __ Jump(lr); |
+ __ rts(); |
} |
@@ -1093,7 +1111,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
// r1: function |
// r2: receiver |
// r3: argc |
- // r4: argv |
+ // r4: argv (JSEntryStub does set it) |
// r5-r7, cp may be clobbered |
// Clear the context before we push it when entering the internal frame. |
@@ -1117,9 +1135,10 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
// r3: argc |
// r4: argv, i.e. points to first arg |
Label loop, entry; |
- __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r3, Operand(kPointerSizeLog2)); |
+ __ add(r2, r4, r2); |
// r2 points past last arg. |
- __ b(&entry); |
+ __ b_near(&entry); |
__ bind(&loop); |
__ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter |
__ ldr(r0, MemOperand(r0)); // dereference handle |
@@ -1131,15 +1150,17 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
// Initialize all JavaScript callee-saved registers, since they will be seen |
// by the garbage collector as part of handlers. |
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex); |
- __ mov(r5, Operand(r4)); |
- __ mov(r6, Operand(r4)); |
- __ mov(r7, Operand(r4)); |
- if (kR9Available == 1) { |
- __ mov(r9, Operand(r4)); |
- } |
+ __ mov(sh4_r5, r4); |
+ __ mov(sh4_r6, r4); |
+ __ mov(sh4_r7, r4); |
+ __ mov(sh4_r8, r4); |
+ __ mov(sh4_r9, r4); |
// Invoke the code and pass argc as r0. |
- __ mov(r0, Operand(r3)); |
+ __ mov(r0, r3); |
+ |
+ // r0: argc |
+ // r1: function |
if (is_construct) { |
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
__ CallStub(&stub); |
@@ -1152,7 +1173,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
// return. |
// Respect ABI stack constraint. |
} |
- __ Jump(lr); |
+ __ rts(); |
// r0: result |
} |
@@ -1242,14 +1263,14 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
// Switch on the state. |
Label with_tos_register, unknown_state; |
__ cmp(r6, Operand(FullCodeGenerator::NO_REGISTERS)); |
- __ b(ne, &with_tos_register); |
+ __ b(ne, &with_tos_register, Label::kNear); |
__ add(sp, sp, Operand(1 * kPointerSize)); // Remove state. |
__ Ret(); |
__ bind(&with_tos_register); |
__ ldr(r0, MemOperand(sp, 1 * kPointerSize)); |
__ cmp(r6, Operand(FullCodeGenerator::TOS_REG)); |
- __ b(ne, &unknown_state); |
+ __ b(ne, &unknown_state, Label::kNear); |
__ add(sp, sp, Operand(2 * kPointerSize)); // Remove state. |
__ Ret(); |
@@ -1273,48 +1294,20 @@ void Builtins::Generate_NotifyOSR(MacroAssembler* masm) { |
// doesn't do any garbage collection which allows us to save/restore |
// the registers without worrying about which of them contain |
// pointers. This seems a bit fragile. |
- __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved | lr.bit() | fp.bit()); |
+ __ Push(pr, fp); |
+ __ pushm(kJSCallerSaved | kCalleeSaved); |
{ |
FrameScope scope(masm, StackFrame::INTERNAL); |
__ CallRuntime(Runtime::kNotifyOSR, 0); |
} |
- __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved | lr.bit() | fp.bit()); |
+ __ popm(kJSCallerSaved | kCalleeSaved); |
+ __ Pop(pr, fp); |
__ Ret(); |
} |
void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
- CpuFeatures::TryForceFeatureScope scope(VFP3); |
- if (!CPU::SupportsCrankshaft()) { |
- __ Abort("Unreachable code: Cannot optimize without VFP3 support."); |
- return; |
- } |
- |
- // Lookup the function in the JavaScript frame and push it as an |
- // argument to the on-stack replacement function. |
- __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ push(r0); |
- __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
- } |
- |
- // If the result was -1 it means that we couldn't optimize the |
- // function. Just return and continue in the unoptimized version. |
- Label skip; |
- __ cmp(r0, Operand(Smi::FromInt(-1))); |
- __ b(ne, &skip); |
- __ Ret(); |
- |
- __ bind(&skip); |
- // Untag the AST id and push it on the stack. |
- __ SmiUntag(r0); |
- __ push(r0); |
- |
- // Generate the code for doing the frame-to-frame translation using |
- // the deoptimizer infrastructure. |
- Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
- generator.Generate(); |
+ __ UNIMPLEMENTED_BREAK(); |
} |
@@ -1322,8 +1315,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
// 1. Make sure we have at least one argument. |
// r0: actual number of arguments |
{ Label done; |
- __ cmp(r0, Operand(0)); |
- __ b(ne, &done); |
+ __ tst(r0, r0); |
+ __ b(ne, &done, Label::kNear); |
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
__ push(r2); |
__ add(r0, r0, Operand(1)); |
@@ -1334,9 +1327,10 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
// if it is a function. |
// r0: actual number of arguments |
Label slow, non_function; |
- __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r1, r0, Operand(kPointerSizeLog2)); |
+ __ ldr(r1, MemOperand(sp, r1)); |
__ JumpIfSmi(r1, &non_function); |
- __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
+ __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE, eq); |
__ b(ne, &slow); |
// 3a. Patch the first argument if necessary when calling a function. |
@@ -1360,12 +1354,13 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ b(ne, &shift_arguments); |
// Compute the receiver in non-strict mode. |
- __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r0, Operand(kPointerSizeLog2)); |
+ __ add(r2, sp, r2); |
__ ldr(r2, MemOperand(r2, -kPointerSize)); |
// r0: actual number of arguments |
// r1: function |
// r2: first argument |
- __ JumpIfSmi(r2, &convert_to_object); |
+ __ JumpIfSmi(r2, &convert_to_object, Label::kNear); |
__ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
__ cmp(r2, r3); |
@@ -1375,15 +1370,15 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ b(eq, &use_global_receiver); |
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
- __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE); |
- __ b(ge, &shift_arguments); |
+ __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE, ge); |
+ __ bt(&shift_arguments); |
__ bind(&convert_to_object); |
{ |
// Enter an internal frame in order to preserve argument count. |
FrameScope scope(masm, StackFrame::INTERNAL); |
- __ mov(r0, Operand(r0, LSL, kSmiTagSize)); // Smi-tagged. |
+ __ lsl(r0, r0, Operand(kSmiTagSize)); // Smi-tagged. |
__ push(r0); |
__ push(r2); |
@@ -1391,15 +1386,16 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ mov(r2, r0); |
__ pop(r0); |
- __ mov(r0, Operand(r0, ASR, kSmiTagSize)); |
+ __ asr(r0, r0, Operand(kSmiTagSize)); |
// Exit the internal frame. |
} |
- // Restore the function to r1, and the flag to r4. |
- __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
+ // Restore the function to r1. |
+ __ lsl(r1, r0, Operand(kPointerSizeLog2)); |
+ __ ldr(r1, MemOperand(sp, r1)); |
__ mov(r4, Operand(0, RelocInfo::NONE)); |
- __ jmp(&patch_receiver); |
+ __ jmp_near(&patch_receiver); |
// Use the global receiver object from the called function as the |
// receiver. |
@@ -1412,7 +1408,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
__ bind(&patch_receiver); |
- __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r3, r0, Operand(kPointerSizeLog2)); |
+ __ add(r3, sp, r3); |
__ str(r2, MemOperand(r3, -kPointerSize)); |
__ jmp(&shift_arguments); |
@@ -1433,7 +1430,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
// r0: actual number of arguments |
// r1: function |
// r4: call type (0: JS function, 1: function proxy, 2: non-function) |
- __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r0, Operand(kPointerSizeLog2)); |
+ __ add(r2, sp, r2); |
__ str(r1, MemOperand(r2, -kPointerSize)); |
// 4. Shift arguments and return address one slot down on the stack |
@@ -1445,7 +1443,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ bind(&shift_arguments); |
{ Label loop; |
// Calculate the copy start address (destination). Copy end address is sp. |
- __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r0, Operand(kPointerSizeLog2)); |
+ __ add(r2, sp, r2); |
__ bind(&loop); |
__ ldr(ip, MemOperand(r2, -kPointerSize)); |
@@ -1466,7 +1465,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
// r4: call type (0: JS function, 1: function proxy, 2: non-function) |
{ Label function, non_proxy; |
__ tst(r4, r4); |
- __ b(eq, &function); |
+ __ b(eq, &function, Label::kNear); |
// Expected number of arguments is 0 for CALL_NON_FUNCTION. |
__ mov(r2, Operand(0, RelocInfo::NONE)); |
__ SetCallKind(r5, CALL_AS_METHOD); |
@@ -1481,7 +1480,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
__ bind(&non_proxy); |
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
+ __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
RelocInfo::CODE_TARGET); |
__ bind(&function); |
} |
@@ -1491,17 +1490,18 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
// (tail-call) to the code in register edx without checking arguments. |
// r0: actual number of arguments |
// r1: function |
+ Label end; |
__ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
__ ldr(r2, |
FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ mov(r2, Operand(r2, ASR, kSmiTagSize)); |
+ __ asr(r2, r2, Operand(kSmiTagSize)); |
__ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
__ SetCallKind(r5, CALL_AS_METHOD); |
__ cmp(r2, r0); // Check formal and actual parameter counts. |
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
- RelocInfo::CODE_TARGET, |
- ne); |
- |
+ __ bt_near(&end); |
+ __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
+ RelocInfo::CODE_TARGET); |
+ __ bind(&end); |
ParameterCount expected(0); |
__ InvokeCode(r3, expected, expected, JUMP_FUNCTION, |
NullCallWrapper(), CALL_AS_METHOD); |
@@ -1533,8 +1533,9 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// here which will cause r2 to become negative. |
__ sub(r2, sp, r2); |
// Check if the arguments will overflow the stack. |
- __ cmp(r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
- __ b(gt, &okay); // Signed comparison. |
+ __ lsl(ip, r0, Operand(kPointerSizeLog2 - kSmiTagSize)); |
+ __ cmpgt(r2, ip); |
+ __ bt_near(&okay); // Signed comparison. |
// Out of stack space. |
__ ldr(r1, MemOperand(fp, kFunctionOffset)); |
@@ -1555,8 +1556,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// Check that the function is a JS function (otherwise it must be a proxy). |
Label push_receiver; |
__ ldr(r1, MemOperand(fp, kFunctionOffset)); |
- __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
- __ b(ne, &push_receiver); |
+ __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE, eq); |
+ __ bf(&push_receiver); |
// Change context eagerly to get the right global object if necessary. |
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
@@ -1587,8 +1588,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// Check if the receiver is already a JavaScript object. |
// r0: receiver |
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
- __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE); |
- __ b(ge, &push_receiver); |
+ __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE, ge); |
+ __ bt(&push_receiver); |
// Convert the receiver to a regular object. |
// r0: receiver |
@@ -1602,7 +1603,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
const int kGlobalOffset = |
Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; |
__ ldr(r0, FieldMemOperand(cp, kGlobalOffset)); |
- __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); |
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset)); |
__ ldr(r0, FieldMemOperand(r0, kGlobalOffset)); |
__ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
@@ -1614,7 +1615,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// Copy all arguments from the array to the stack. |
Label entry, loop; |
__ ldr(r0, MemOperand(fp, kIndexOffset)); |
- __ b(&entry); |
+ __ b_near(&entry); |
// Load the current argument from the arguments array and push it to the |
// stack. |
@@ -1643,16 +1644,16 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// Invoke the function. |
Label call_proxy; |
ParameterCount actual(r0); |
- __ mov(r0, Operand(r0, ASR, kSmiTagSize)); |
+ __ asr(r0, r0, Operand(kSmiTagSize)); |
__ ldr(r1, MemOperand(fp, kFunctionOffset)); |
- __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
- __ b(ne, &call_proxy); |
+ __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE, eq); |
+ __ bf(&call_proxy); |
__ InvokeFunction(r1, actual, CALL_FUNCTION, |
NullCallWrapper(), CALL_AS_METHOD); |
frame_scope.GenerateLeaveFrame(); |
__ add(sp, sp, Operand(3 * kPointerSize)); |
- __ Jump(lr); |
+ __ rts(); |
// Invoke the function proxy. |
__ bind(&call_proxy); |
@@ -1667,14 +1668,15 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
// Tear down the internal frame and remove function, receiver and args. |
} |
__ add(sp, sp, Operand(3 * kPointerSize)); |
- __ Jump(lr); |
+ __ rts(); |
} |
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
- __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
+ __ lsl(r0, r0, Operand(kSmiTagSize)); |
__ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
- __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | fp.bit() | lr.bit()); |
+ __ push(pr); |
+ __ Push(fp, r4, r1, r0); |
__ add(fp, sp, Operand(3 * kPointerSize)); |
} |
@@ -1687,8 +1689,9 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
// then tear down the parameters. |
__ ldr(r1, MemOperand(fp, -3 * kPointerSize)); |
__ mov(sp, fp); |
- __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
- __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ Pop(pr, fp); |
+ __ lsl(ip, r1, Operand(kPointerSizeLog2 - kSmiTagSize)); |
+ __ add(sp, sp, ip); |
__ add(sp, sp, Operand(kPointerSize)); // adjust for receiver |
} |
@@ -1705,8 +1708,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
Label invoke, dont_adapt_arguments; |
Label enough, too_few; |
- __ cmp(r0, r2); |
- __ b(lt, &too_few); |
+ __ cmpge(r0, r2); |
+ __ bf(&too_few); |
__ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); |
__ b(eq, &dont_adapt_arguments); |
@@ -1719,10 +1722,12 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// r1: function |
// r2: expected number of arguments |
// r3: code entry to call |
- __ add(r0, fp, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ lsl(r0, r0, Operand(kPointerSizeLog2 - kSmiTagSize)); |
+ __ add(r0, fp, r0); |
// adjust for return address and receiver |
__ add(r0, r0, Operand(2 * kPointerSize)); |
- __ sub(r2, r0, Operand(r2, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r2, Operand(kPointerSizeLog2)); |
+ __ sub(r2, r0, r2); |
// Copy the arguments (including the receiver) to the new stack frame. |
// r0: copy start address |
@@ -1750,7 +1755,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// r1: function |
// r2: expected number of arguments |
// r3: code entry to call |
- __ add(r0, fp, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ lsl(r0, r0, Operand(kPointerSizeLog2 - kSmiTagSize)); |
+ __ add(r0, fp, r0); |
// Copy the arguments (including the receiver) to the new stack frame. |
// r0: copy start address |
@@ -1771,7 +1777,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// r2: expected number of arguments |
// r3: code entry to call |
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
- __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2)); |
+ __ lsl(r2, r2, Operand(kPointerSizeLog2)); |
+ __ sub(r2, fp, r2); |
__ sub(r2, r2, Operand(4 * kPointerSize)); // Adjust for frame. |
Label fill; |
@@ -1783,21 +1790,21 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
// Call the entry point. |
__ bind(&invoke); |
- __ Call(r3); |
+ __ jsr(r3); |
// Store offset of return address for deoptimizer. |
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); |
// Exit frame and return. |
LeaveArgumentsAdaptorFrame(masm); |
- __ Jump(lr); |
+ __ rts(); |
// ------------------------------------------- |
// Dont adapt arguments. |
// ------------------------------------------- |
__ bind(&dont_adapt_arguments); |
- __ Jump(r3); |
+ __ jmp(r3); |
} |
@@ -1805,4 +1812,4 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
} } // namespace v8::internal |
-#endif // V8_TARGET_ARCH_ARM |
+#endif // V8_TARGET_ARCH_SH4 |