| Index: src/sh4/macro-assembler-sh4.h
|
| diff --git a/src/arm/macro-assembler-arm.h b/src/sh4/macro-assembler-sh4.h
|
| similarity index 71%
|
| copy from src/arm/macro-assembler-arm.h
|
| copy to src/sh4/macro-assembler-sh4.h
|
| index e3e39a3879e1b717296fbc466d7423336f852eeb..81756ff326ebe7b564e8a05084ccf736ea246afd 100644
|
| --- a/src/arm/macro-assembler-arm.h
|
| +++ b/src/sh4/macro-assembler-sh4.h
|
| @@ -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:
|
| @@ -25,8 +25,8 @@
|
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| -#ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_
|
| -#define V8_ARM_MACRO_ASSEMBLER_ARM_H_
|
| +#ifndef V8_SH4_MACRO_ASSEMBLER_SH4_H_
|
| +#define V8_SH4_MACRO_ASSEMBLER_SH4_H_
|
|
|
| #include "assembler.h"
|
| #include "frames.h"
|
| @@ -43,17 +43,6 @@ inline MemOperand FieldMemOperand(Register object, int offset) {
|
| return MemOperand(object, offset - kHeapObjectTag);
|
| }
|
|
|
| -
|
| -inline Operand SmiUntagOperand(Register object) {
|
| - return Operand(object, ASR, kSmiTagSize);
|
| -}
|
| -
|
| -
|
| -
|
| -// Give alias names to registers
|
| -const Register cp = { 8 }; // JavaScript context pointer
|
| -const Register kRootRegister = { 10 }; // Roots array pointer.
|
| -
|
| // Flags used for the AllocateInNewSpace functions.
|
| enum AllocationFlags {
|
| // No special flags.
|
| @@ -68,13 +57,6 @@ enum AllocationFlags {
|
| SIZE_IN_WORDS = 1 << 2
|
| };
|
|
|
| -// Flags used for AllocateHeapNumber
|
| -enum TaggingMode {
|
| - // Tag the result.
|
| - TAG_RESULT,
|
| - // Don't tag
|
| - DONT_TAG_RESULT
|
| -};
|
|
|
| // Flags used for the ObjectToDoubleVFPRegister function.
|
| enum ObjectToDoubleFlags {
|
| @@ -102,11 +84,6 @@ bool AreAliased(Register reg1,
|
| #endif
|
|
|
|
|
| -enum TargetAddressStorageMode {
|
| - CAN_INLINE_TARGET_ADDRESS,
|
| - NEVER_INLINE_TARGET_ADDRESS
|
| -};
|
| -
|
| // MacroAssembler implements a collection of frequently used macros.
|
| class MacroAssembler: public Assembler {
|
| public:
|
| @@ -116,78 +93,12 @@ class MacroAssembler: public Assembler {
|
| // macro assembler.
|
| MacroAssembler(Isolate* isolate, void* buffer, int size);
|
|
|
| - // Jump, Call, and Ret pseudo instructions implementing inter-working.
|
| - void Jump(Register target, Condition cond = al);
|
| - void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al);
|
| - void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
|
| - static int CallSize(Register target, Condition cond = al);
|
| - void Call(Register target, Condition cond = al);
|
| - int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
|
| - static int CallSizeNotPredictableCodeSize(Address target,
|
| - RelocInfo::Mode rmode,
|
| - Condition cond = al);
|
| - void Call(Address target, RelocInfo::Mode rmode,
|
| - Condition cond = al,
|
| - TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
|
| - int CallSize(Handle<Code> code,
|
| - RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
|
| - TypeFeedbackId ast_id = TypeFeedbackId::None(),
|
| - Condition cond = al);
|
| - void Call(Handle<Code> code,
|
| - RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
|
| - TypeFeedbackId ast_id = TypeFeedbackId::None(),
|
| - Condition cond = al,
|
| - TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
|
| - void Ret(Condition cond = al);
|
| -
|
| - // Emit code to discard a non-negative number of pointer-sized elements
|
| - // from the stack, clobbering only the sp register.
|
| - void Drop(int count, Condition cond = al);
|
| -
|
| - void Ret(int drop, Condition cond = al);
|
| -
|
| - // Swap two registers. If the scratch register is omitted then a slightly
|
| - // less efficient form using xor instead of mov is emitted.
|
| - void Swap(Register reg1,
|
| - Register reg2,
|
| - Register scratch = no_reg,
|
| - Condition cond = al);
|
| -
|
| -
|
| - void And(Register dst, Register src1, const Operand& src2,
|
| - Condition cond = al);
|
| - void Ubfx(Register dst, Register src, int lsb, int width,
|
| - Condition cond = al);
|
| - void Sbfx(Register dst, Register src, int lsb, int width,
|
| - Condition cond = al);
|
| - // The scratch register is not used for ARMv7.
|
| - // scratch can be the same register as src (in which case it is trashed), but
|
| - // not the same as dst.
|
| - void Bfi(Register dst,
|
| - Register src,
|
| - Register scratch,
|
| - int lsb,
|
| - int width,
|
| - Condition cond = al);
|
| - void Bfc(Register dst, Register src, int lsb, int width, Condition cond = al);
|
| - void Usat(Register dst, int satpos, const Operand& src,
|
| - Condition cond = al);
|
| -
|
| - void Call(Label* target);
|
| -
|
| - // Register move. May do nothing if the registers are identical.
|
| - void Move(Register dst, Handle<Object> value);
|
| - void Move(Register dst, Register src, Condition cond = al);
|
| - void Move(DoubleRegister dst, DoubleRegister src);
|
| -
|
| // Load an object from the root table.
|
| void LoadRoot(Register destination,
|
| - Heap::RootListIndex index,
|
| - Condition cond = al);
|
| + Heap::RootListIndex index);
|
| // Store an object to the root table.
|
| void StoreRoot(Register source,
|
| - Heap::RootListIndex index,
|
| - Condition cond = al);
|
| + Heap::RootListIndex index);
|
|
|
| void LoadHeapObject(Register dst, Handle<HeapObject> object);
|
|
|
| @@ -202,10 +113,6 @@ class MacroAssembler: public Assembler {
|
| // ---------------------------------------------------------------------------
|
| // GC Support
|
|
|
| - void IncrementalMarkingRecordWriteHelper(Register object,
|
| - Register value,
|
| - Register address);
|
| -
|
| enum RememberedSetFinalAction {
|
| kReturnAtEnd,
|
| kFallThroughAtEnd
|
| @@ -266,11 +173,13 @@ class MacroAssembler: public Assembler {
|
| Register scratch3,
|
| Label* object_is_white_and_not_data);
|
|
|
| - // Detects conservatively whether an object is data-only, i.e. it does need to
|
| - // be scanned by the garbage collector.
|
| - void JumpIfDataObject(Register value,
|
| - Register scratch,
|
| - Label* not_data_object);
|
| + // Check if object is in new space.
|
| + // scratch can be object itself, but it will be clobbered.
|
| + void InNewSpace(Register object,
|
| + Register scratch,
|
| + // eq for "in new space?", ne for "not in new space?"
|
| + Condition cond,
|
| + Label* branch);
|
|
|
| // Notify the garbage collector that we wrote a pointer into an object.
|
| // |object| is the object being stored into, |value| is the object being
|
| @@ -320,131 +229,85 @@ class MacroAssembler: public Assembler {
|
| RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
|
| SmiCheck smi_check = INLINE_SMI_CHECK);
|
|
|
| - // Push a handle.
|
| - void Push(Handle<Object> handle);
|
| +
|
| + // Mark the register as dead. Put the pattern 0xFFFFFFDE into the register.
|
| + void Dead(Register dead) {
|
| + // Fit in a single SH4 mov_imm_ instruction
|
| + mov(dead, Operand(static_cast<int>(0xFFFFFFDE)));
|
| + }
|
| +
|
| + // Mark up to four registers dead at a time.
|
| + void Dead(Register d1, Register d2, Register d3 = no_reg,
|
| + Register d4 = no_reg) {
|
| + Dead(d1);
|
| + Dead(d2);
|
| + if (d3.is_valid()) Dead(d3);
|
| + if (d4.is_valid()) Dead(d4);
|
| + }
|
| +
|
| + void Push(Handle<Object> handle) { push(Operand(handle), sh4_ip); }
|
|
|
| // Push two registers. Pushes leftmost register first (to highest address).
|
| - void Push(Register src1, Register src2, Condition cond = al) {
|
| + void Push(Register src1, Register src2) {
|
| ASSERT(!src1.is(src2));
|
| - if (src1.code() > src2.code()) {
|
| - stm(db_w, sp, src1.bit() | src2.bit(), cond);
|
| - } else {
|
| - str(src1, MemOperand(sp, 4, NegPreIndex), cond);
|
| - str(src2, MemOperand(sp, 4, NegPreIndex), cond);
|
| - }
|
| + push(src1);
|
| + push(src2);
|
| }
|
|
|
| // Push three registers. Pushes leftmost register first (to highest address).
|
| - void Push(Register src1, Register src2, Register src3, Condition cond = al) {
|
| + void Push(Register src1, Register src2, Register src3) {
|
| ASSERT(!src1.is(src2));
|
| ASSERT(!src2.is(src3));
|
| ASSERT(!src1.is(src3));
|
| - if (src1.code() > src2.code()) {
|
| - if (src2.code() > src3.code()) {
|
| - stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
|
| - } else {
|
| - stm(db_w, sp, src1.bit() | src2.bit(), cond);
|
| - str(src3, MemOperand(sp, 4, NegPreIndex), cond);
|
| - }
|
| - } else {
|
| - str(src1, MemOperand(sp, 4, NegPreIndex), cond);
|
| - Push(src2, src3, cond);
|
| - }
|
| + push(src1);
|
| + push(src2);
|
| + push(src3);
|
| }
|
|
|
| // Push four registers. Pushes leftmost register first (to highest address).
|
| - void Push(Register src1,
|
| - Register src2,
|
| - Register src3,
|
| - Register src4,
|
| - Condition cond = al) {
|
| + void Push(Register src1, Register src2,
|
| + Register src3, Register src4) {
|
| ASSERT(!src1.is(src2));
|
| ASSERT(!src2.is(src3));
|
| ASSERT(!src1.is(src3));
|
| ASSERT(!src1.is(src4));
|
| ASSERT(!src2.is(src4));
|
| ASSERT(!src3.is(src4));
|
| - if (src1.code() > src2.code()) {
|
| - if (src2.code() > src3.code()) {
|
| - if (src3.code() > src4.code()) {
|
| - stm(db_w,
|
| - sp,
|
| - src1.bit() | src2.bit() | src3.bit() | src4.bit(),
|
| - cond);
|
| - } else {
|
| - stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
|
| - str(src4, MemOperand(sp, 4, NegPreIndex), cond);
|
| - }
|
| - } else {
|
| - stm(db_w, sp, src1.bit() | src2.bit(), cond);
|
| - Push(src3, src4, cond);
|
| - }
|
| - } else {
|
| - str(src1, MemOperand(sp, 4, NegPreIndex), cond);
|
| - Push(src2, src3, src4, cond);
|
| - }
|
| + push(src1);
|
| + push(src2);
|
| + push(src3);
|
| + push(src4);
|
| }
|
|
|
| // Pop two registers. Pops rightmost register first (from lower address).
|
| - void Pop(Register src1, Register src2, Condition cond = al) {
|
| + void Pop(Register src1, Register src2) {
|
| ASSERT(!src1.is(src2));
|
| - if (src1.code() > src2.code()) {
|
| - ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
|
| - } else {
|
| - ldr(src2, MemOperand(sp, 4, PostIndex), cond);
|
| - ldr(src1, MemOperand(sp, 4, PostIndex), cond);
|
| - }
|
| + pop(src2);
|
| + pop(src1);
|
| }
|
|
|
| - // Pop three registers. Pops rightmost register first (from lower address).
|
| - void Pop(Register src1, Register src2, Register src3, Condition cond = al) {
|
| + // Pop three registers. Pops rightmost register first (from lower address).
|
| + void Pop(Register src1, Register src2, Register src3) {
|
| ASSERT(!src1.is(src2));
|
| ASSERT(!src2.is(src3));
|
| ASSERT(!src1.is(src3));
|
| - if (src1.code() > src2.code()) {
|
| - if (src2.code() > src3.code()) {
|
| - ldm(ia_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
|
| - } else {
|
| - ldr(src3, MemOperand(sp, 4, PostIndex), cond);
|
| - ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
|
| - }
|
| - } else {
|
| - Pop(src2, src3, cond);
|
| - str(src1, MemOperand(sp, 4, PostIndex), cond);
|
| - }
|
| + pop(src3);
|
| + pop(src2);
|
| + pop(src1);
|
| }
|
|
|
| - // Pop four registers. Pops rightmost register first (from lower address).
|
| - void Pop(Register src1,
|
| - Register src2,
|
| - Register src3,
|
| - Register src4,
|
| - Condition cond = al) {
|
| + // Pop four registers. Pops rightmost register first (from lower address).
|
| + void Pop(Register src1, Register src2, Register src3, Register src4) {
|
| ASSERT(!src1.is(src2));
|
| ASSERT(!src2.is(src3));
|
| ASSERT(!src1.is(src3));
|
| ASSERT(!src1.is(src4));
|
| ASSERT(!src2.is(src4));
|
| ASSERT(!src3.is(src4));
|
| - if (src1.code() > src2.code()) {
|
| - if (src2.code() > src3.code()) {
|
| - if (src3.code() > src4.code()) {
|
| - ldm(ia_w,
|
| - sp,
|
| - src1.bit() | src2.bit() | src3.bit() | src4.bit(),
|
| - cond);
|
| - } else {
|
| - ldr(src4, MemOperand(sp, 4, PostIndex), cond);
|
| - ldm(ia_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
|
| - }
|
| - } else {
|
| - Pop(src3, src4, cond);
|
| - ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
|
| - }
|
| - } else {
|
| - Pop(src2, src3, src4, cond);
|
| - ldr(src1, MemOperand(sp, 4, PostIndex), cond);
|
| - }
|
| + pop(src4);
|
| + pop(src3);
|
| + pop(src2);
|
| + pop(src1);
|
| }
|
|
|
| // Push and pop the registers that can hold pointers, as defined by the
|
| @@ -464,57 +327,60 @@ class MacroAssembler: public Assembler {
|
| // Load two consecutive registers with two consecutive memory locations.
|
| void Ldrd(Register dst1,
|
| Register dst2,
|
| - const MemOperand& src,
|
| - Condition cond = al);
|
| + const MemOperand& src);
|
|
|
| // Store two consecutive registers to two consecutive memory locations.
|
| void Strd(Register src1,
|
| Register src2,
|
| - const MemOperand& dst,
|
| - Condition cond = al);
|
| -
|
| - // Clear specified FPSCR bits.
|
| - void ClearFPSCRBits(const uint32_t bits_to_clear,
|
| - const Register scratch,
|
| - const Condition cond = al);
|
| -
|
| - // Compare double values and move the result to the normal condition flags.
|
| - void VFPCompareAndSetFlags(const DwVfpRegister src1,
|
| - const DwVfpRegister src2,
|
| - const Condition cond = al);
|
| - void VFPCompareAndSetFlags(const DwVfpRegister src1,
|
| - const double src2,
|
| - const Condition cond = al);
|
| -
|
| - // Compare double values and then load the fpscr flags to a register.
|
| - void VFPCompareAndLoadFlags(const DwVfpRegister src1,
|
| - const DwVfpRegister src2,
|
| - const Register fpscr_flags,
|
| - const Condition cond = al);
|
| - void VFPCompareAndLoadFlags(const DwVfpRegister src1,
|
| - const double src2,
|
| - const Register fpscr_flags,
|
| - const Condition cond = al);
|
| -
|
| - void Vmov(const DwVfpRegister dst,
|
| - const double imm,
|
| - const Register scratch = no_reg,
|
| - const Condition cond = al);
|
| + const MemOperand& dst);
|
| +
|
| + void IsObjectJSStringType(Register object,
|
| + Register scratch,
|
| + Label* fail);
|
| +
|
| +#ifdef ENABLE_DEBUGGER_SUPPORT
|
| + // ---------------------------------------------------------------------------
|
| + // Debugger Support
|
| +
|
| + void DebugBreak();
|
| +#endif
|
| +
|
| + // ---------------------------------------------------------------------------
|
| + // Support for marking unimplemented code generator function
|
| + // Should be called with UNIMPLEMENTED_BREAK define below.
|
| + void UnimplementedBreak(const char *file, int line);
|
| +#ifdef DEBUG
|
| +#define UNIMPLEMENTED_BREAK() UnimplementedBreak(__FILE__, __LINE__)
|
| +#else
|
| +#define UNIMPLEMENTED_BREAK() UnimplementedBreak("", 0)
|
| +#endif
|
| +
|
| + // ---------------------------------------------------------------------------
|
| + // Activation frames
|
| +
|
| + void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
|
| + void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
|
| +
|
| + void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
|
| + void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
|
| +
|
| + // Expects object in r0 and returns map with validated enum cache
|
| + // in r0. Assumes that any other register can be used as a scratch.
|
| + void CheckEnumCache(Register null_value, Label* call_runtime);
|
|
|
| // Enter exit frame.
|
| // stack_space - extra stack space, used for alignment before call to C.
|
| - void EnterExitFrame(bool save_doubles, int stack_space = 0);
|
| + void EnterExitFrame(bool save_doubles, int stack_space = 0,
|
| + Register scratch = sh4_ip);
|
|
|
| // Leave the current exit frame. Expects the return value in r0.
|
| // Expect the number of values, pushed prior to the exit frame, to
|
| // remove in a register (or no_reg, if there is nothing to remove).
|
| void LeaveExitFrame(bool save_doubles, Register argument_count);
|
|
|
| - // Get the actual activation frame alignment for target environment.
|
| - static int ActivationFrameAlignment();
|
| -
|
| void LoadContext(Register dst, int context_chain_length);
|
|
|
| +
|
| // Conditionally load the cached Array transitioned map of type
|
| // transitioned_kind from the native context if the map in register
|
| // map_in_out is the cached Array map in the native context of
|
| @@ -543,7 +409,7 @@ class MacroAssembler: public Assembler {
|
| void InitializeRootRegister() {
|
| ExternalReference roots_array_start =
|
| ExternalReference::roots_array_start(isolate());
|
| - mov(kRootRegister, Operand(roots_array_start));
|
| + mov(roots, Operand(roots_array_start));
|
| }
|
|
|
| // ---------------------------------------------------------------------------
|
| @@ -583,25 +449,128 @@ class MacroAssembler: public Assembler {
|
| const CallWrapper& call_wrapper,
|
| CallKind call_kind);
|
|
|
| + // Expression support
|
| + void Set(Register dst, const Operand& x);
|
| + void Set(const Operand& dst, const Operand& x);
|
| +
|
| + // Compare object type for heap object.
|
| + // Incoming register is heap_object and outgoing register is map.
|
| + void CmpObjectType(Register heap_object, InstanceType type, Register map);
|
| +
|
| + // Compare instance type for map.
|
| + void CmpInstanceType(Register map, InstanceType type);
|
| +
|
| + // Check if the map of an object is equal to a specified map and branch to a
|
| + // specified target if equal. Skip the smi check if not required (object is
|
| + // known to be a heap object)
|
| + void DispatchMap(Register obj,
|
| + Register scratch,
|
| + Handle<Map> map,
|
| + Handle<Code> success,
|
| + SmiCheckType smi_check_type);
|
| +
|
| + // Compare the object in a register to a value from the root list.
|
| + // Uses the ip register as scratch.
|
| + void CompareRoot(Register obj, Heap::RootListIndex index);
|
| +
|
| + // Check if a heap object's type is in the JSObject range, not including
|
| + // JSFunction. The object's map will be loaded in the map register.
|
| + // Any or all of the three registers may be the same.
|
| + // The contents of the scratch register will always be overwritten.
|
| void IsObjectJSObjectType(Register heap_object,
|
| Register map,
|
| Register scratch,
|
| Label* fail);
|
|
|
| - void IsInstanceJSObjectType(Register map,
|
| - Register scratch,
|
| - Label* fail);
|
| + // The contents of the scratch register will be overwritten.
|
| + void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
|
|
|
| - void IsObjectJSStringType(Register object,
|
| - Register scratch,
|
| - Label* fail);
|
| + // ---------------------------------------------------------------------------
|
| + // String utilities
|
| +
|
| + // Checks if both objects are sequential ASCII strings and jumps to label
|
| + // if either is not. Assumes that neither object is a smi.
|
| + void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1,
|
| + Register object2,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* failure);
|
| +
|
| + // Checks if both objects are sequential ASCII strings and jumps to label
|
| + // if either is not.
|
| + void JumpIfNotBothSequentialAsciiStrings(Register first,
|
| + Register second,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* not_flat_ascii_strings);
|
| +
|
| + // Checks if both instance types are sequential ASCII strings and jumps to
|
| + // label if either is not.
|
| + void JumpIfBothInstanceTypesAreNotSequentialAscii(
|
| + Register first_object_instance_type,
|
| + Register second_object_instance_type,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* failure);
|
| +
|
| + // Check if instance type is sequential ASCII string and jump to label if
|
| + // it is not.
|
| + void JumpIfInstanceTypeIsNotSequentialAscii(Register type,
|
| + Register scratch,
|
| + Label* failure);
|
| +
|
| + // Abort execution if argument is not a number. Used in debug code.
|
| + void AbortIfNotNumber(Register object);
|
| +
|
| + // Abort execution if argument is not a smi. Used in debug code.
|
| + void AbortIfNotSmi(Register object);
|
| +
|
| + // Abort execution if argument is a smi. Used in debug code.
|
| + void AbortIfSmi(Register object);
|
| +
|
| + // Abort execution if argument is a string. Used in debug code.
|
| + void AbortIfNotString(Register object);
|
| +
|
| + // Abort execution if argument is not the root value with the given index.
|
| + void AbortIfNotRootValue(Register src,
|
| + Heap::RootListIndex root_value_index,
|
| + const char* message);
|
| +
|
| + // Prints the value of the register to stdout. Use for debug only.
|
| + void PrintRegisterValue(Register reg);
|
|
|
| -#ifdef ENABLE_DEBUGGER_SUPPORT
|
| // ---------------------------------------------------------------------------
|
| - // Debugger Support
|
| + // Patching helpers.
|
| +
|
| + // Get the location of a relocated constant (its address in the constant pool)
|
| + // from its load site.
|
| + void GetRelocatedValueLocation(Register ldr_location,
|
| + Register result);
|
| +
|
| + void LoadInstanceDescriptors(Register map,
|
| + Register descriptors,
|
| + Register scratch);
|
| + void EnumLength(Register dst, Register map);
|
| + void NumberOfOwnDescriptors(Register dst, Register map);
|
| +
|
| + template<typename Field>
|
| + void DecodeField(Register reg) {
|
| + static const int shift = Field::kShift;
|
| + static const int mask = (Field::kMask >> shift) << kSmiTagSize;
|
| + lsr(reg, reg, Operand(shift));
|
| + land(reg, reg, Operand(mask));
|
| + }
|
| +
|
| +
|
| +
|
| + // ---------------------------------------------------------------------------
|
| + // HeapNumber utilities
|
| +
|
| + void JumpIfNotHeapNumber(Register object,
|
| + Register heap_number_map,
|
| + Register scratch,
|
| + Label* on_not_heap_number);
|
|
|
| - void DebugBreak();
|
| -#endif
|
|
|
| // ---------------------------------------------------------------------------
|
| // Exception handling
|
| @@ -613,7 +582,7 @@ class MacroAssembler: public Assembler {
|
| // Must preserve the result register.
|
| void PopTryHandler();
|
|
|
| - // Passes thrown value to the handler of top of the try handler chain.
|
| + // Activate the top handler in the try hander chain.
|
| void Throw(Register value);
|
|
|
| // Propagates an uncatchable exception to the top of the current JS stack's
|
| @@ -640,62 +609,39 @@ class MacroAssembler: public Assembler {
|
| Register t1,
|
| Register t2);
|
|
|
| -
|
| - inline void MarkCode(NopMarkerTypes type) {
|
| - nop(type);
|
| - }
|
| -
|
| - // Check if the given instruction is a 'type' marker.
|
| - // i.e. check if is is a mov r<type>, r<type> (referenced as nop(type))
|
| - // These instructions are generated to mark special location in the code,
|
| - // like some special IC code.
|
| - static inline bool IsMarkedCode(Instr instr, int type) {
|
| - ASSERT((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
|
| - return IsNop(instr, type);
|
| - }
|
| -
|
| -
|
| - static inline int GetCodeMarker(Instr instr) {
|
| - int dst_reg_offset = 12;
|
| - int dst_mask = 0xf << dst_reg_offset;
|
| - int src_mask = 0xf;
|
| - int dst_reg = (instr & dst_mask) >> dst_reg_offset;
|
| - int src_reg = instr & src_mask;
|
| - uint32_t non_register_mask = ~(dst_mask | src_mask);
|
| - uint32_t mov_mask = al | 13 << 21;
|
| -
|
| - // Return <n> if we have a mov rn rn, else return -1.
|
| - int type = ((instr & non_register_mask) == mov_mask) &&
|
| - (dst_reg == src_reg) &&
|
| - (FIRST_IC_MARKER <= dst_reg) && (dst_reg < LAST_CODE_MARKER)
|
| - ? src_reg
|
| - : -1;
|
| - ASSERT((type == -1) ||
|
| - ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
|
| - return type;
|
| - }
|
| -
|
| -
|
| // ---------------------------------------------------------------------------
|
| // Allocation support
|
|
|
| - // Allocate an object in new space. The object_size is specified
|
| - // either in bytes or in words if the allocation flag SIZE_IN_WORDS
|
| - // is passed. If the new space is exhausted control continues at the
|
| - // gc_required label. The allocated object is returned in result. If
|
| - // the flag tag_allocated_object is true the result is tagged as as
|
| - // a heap object. All registers are clobbered also when control
|
| - // continues at the gc_required label.
|
| + // Allocate an object in new space. If the new space is exhausted control
|
| + // continues at the gc_required label. The allocated object is returned in
|
| + // result and end of the new object is returned in result_end. The register
|
| + // scratch can be passed as no_reg in which case an additional object
|
| + // reference will be added to the reloc info. The returned pointers in result
|
| + // and result_end have not yet been tagged as heap objects. If
|
| + // result_contains_top_on_entry is true the content of result is known to be
|
| + // the allocation top on entry (could be result_end from a previous call to
|
| + // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
|
| + // should be no_reg as it is never used.
|
| void AllocateInNewSpace(int object_size,
|
| Register result,
|
| - Register scratch1,
|
| - Register scratch2,
|
| + Register result_end,
|
| + Register scratch,
|
| Label* gc_required,
|
| AllocationFlags flags);
|
| +
|
| + void AllocateInNewSpace(int header_size,
|
| + ScaleFactor element_size,
|
| + Register element_count,
|
| + Register result,
|
| + Register result_end,
|
| + Register scratch,
|
| + Label* gc_required,
|
| + AllocationFlags flags);
|
| +
|
| void AllocateInNewSpace(Register object_size,
|
| Register result,
|
| - Register scratch1,
|
| - Register scratch2,
|
| + Register result_end,
|
| + Register scratch,
|
| Label* gc_required,
|
| AllocationFlags flags);
|
|
|
| @@ -706,6 +652,18 @@ class MacroAssembler: public Assembler {
|
| void UndoAllocationInNewSpace(Register object, Register scratch);
|
|
|
|
|
| + // Allocate a heap number in new space with undefined value. The
|
| + // register scratch2 can be passed as no_reg; the others must be
|
| + // valid registers. Returns tagged pointer in result register, or
|
| + // jumps to gc_required if new space is full.
|
| + void AllocateHeapNumber(Register result,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register heap_number_map,
|
| + Label* gc_required);
|
| +
|
| + // Allocate a sequential string. All the header fields of the string object
|
| + // are initialized.
|
| void AllocateTwoByteString(Register result,
|
| Register length,
|
| Register scratch1,
|
| @@ -718,11 +676,20 @@ class MacroAssembler: public Assembler {
|
| Register scratch2,
|
| Register scratch3,
|
| Label* gc_required);
|
| + void AllocateAsciiString(Register result,
|
| + int length,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* gc_required);
|
| +
|
| + // Allocate a raw cons string object. Only the map field of the result is
|
| + // initialized.
|
| void AllocateTwoByteConsString(Register result,
|
| Register length,
|
| Register scratch1,
|
| Register scratch2,
|
| Label* gc_required);
|
| +
|
| void AllocateAsciiConsString(Register result,
|
| Register length,
|
| Register scratch1,
|
| @@ -739,30 +706,14 @@ class MacroAssembler: public Assembler {
|
| Register scratch2,
|
| Label* gc_required);
|
|
|
| - // Allocates a heap number or jumps to the gc_required label if the young
|
| - // space is full and a scavenge is needed. All registers are clobbered also
|
| - // when control continues at the gc_required label.
|
| - void AllocateHeapNumber(Register result,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register heap_number_map,
|
| - Label* gc_required,
|
| - TaggingMode tagging_mode = TAG_RESULT);
|
| - void AllocateHeapNumberWithValue(Register result,
|
| - DwVfpRegister value,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register heap_number_map,
|
| - Label* gc_required);
|
| -
|
| // Copies a fixed number of fields of heap objects from src to dst.
|
| void CopyFields(Register dst, Register src, RegList temps, int field_count);
|
|
|
| - // Copies a number of bytes from src to dst. All registers are clobbered. On
|
| - // exit src and dst will point to the place just after where the last byte was
|
| - // read or written and length will be zero.
|
| - void CopyBytes(Register src,
|
| - Register dst,
|
| + // Copy memory, byte-by-byte, from source to destination. Not optimized for
|
| + // long or aligned copies.
|
| + // The contents of index and scratch are destroyed.
|
| + void CopyBytes(Register source,
|
| + Register destination,
|
| Register length,
|
| Register scratch);
|
|
|
| @@ -797,15 +748,18 @@ class MacroAssembler: public Assembler {
|
| void CompareObjectType(Register heap_object,
|
| Register map,
|
| Register type_reg,
|
| - InstanceType type);
|
| + InstanceType type,
|
| + Condition cond);
|
|
|
| // Compare instance type in a map. map contains a valid map object whose
|
| // object type should be compared with the given type. This both
|
| - // sets the flags and leaves the object type in the type_reg register.
|
| + // sets the flags and leaves the object type in the type_reg register. It
|
| + // leaves the heap object in the heap_object register unless the heap_object
|
| + // register is the same register as type_reg.
|
| void CompareInstanceType(Register map,
|
| Register type_reg,
|
| - InstanceType type);
|
| -
|
| + InstanceType type,
|
| + Condition cond);
|
|
|
| // Check if a map for a JSObject indicates that the object has fast elements.
|
| // Jump to the specified label if it does not.
|
| @@ -876,20 +830,6 @@ class MacroAssembler: public Assembler {
|
| SmiCheckType smi_check_type);
|
|
|
|
|
| - // Check if the map of an object is equal to a specified map and branch to a
|
| - // specified target if equal. Skip the smi check if not required (object is
|
| - // known to be a heap object)
|
| - void DispatchMap(Register obj,
|
| - Register scratch,
|
| - Handle<Map> map,
|
| - Handle<Code> success,
|
| - SmiCheckType smi_check_type);
|
| -
|
| -
|
| - // Compare the object in a register to a value from the root list.
|
| - // Uses the ip register as scratch.
|
| - void CompareRoot(Register obj, Heap::RootListIndex index);
|
| -
|
|
|
| // Load and check the instance type of an object for being a string.
|
| // Loads the type into the second argument register.
|
| @@ -918,36 +858,10 @@ class MacroAssembler: public Assembler {
|
| void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
|
| void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
|
|
|
| - // Uses VFP instructions to Convert a Smi to a double.
|
| - void IntegerToDoubleConversionWithVFP3(Register inReg,
|
| - Register outHighReg,
|
| - Register outLowReg);
|
| -
|
| - // Load the value of a number object into a VFP double register. If the object
|
| - // is not a number a jump to the label not_number is performed and the VFP
|
| - // double register is unchanged.
|
| - void ObjectToDoubleVFPRegister(
|
| - Register object,
|
| - DwVfpRegister value,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register heap_number_map,
|
| - SwVfpRegister scratch3,
|
| - Label* not_number,
|
| - ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
|
| -
|
| - // Load the value of a smi object into a VFP double register. The register
|
| - // scratch1 can be the same register as smi in which case smi will hold the
|
| - // untagged value afterwards.
|
| - void SmiToDoubleVFPRegister(Register smi,
|
| - DwVfpRegister value,
|
| - Register scratch1,
|
| - SwVfpRegister scratch2);
|
| -
|
| // Convert the HeapNumber pointed to by source to a 32bits signed integer
|
| // dest. If the HeapNumber does not fit into a 32bits signed integer branch
|
| // to not_int32 label. If VFP3 is available double_scratch is used but not
|
| - // scratch2.
|
| + // scratch2. TODO: SH4, use fp reg.
|
| void ConvertToInt32(Register source,
|
| Register dest,
|
| Register scratch,
|
| @@ -955,22 +869,29 @@ class MacroAssembler: public Assembler {
|
| DwVfpRegister double_scratch,
|
| Label *not_int32);
|
|
|
| - // Truncates a double using a specific rounding mode, and writes the value
|
| - // to the result register.
|
| + // Load the value of a smi object into a FPU double register. The register
|
| + // scratch1 can be the same register as smi in which case smi will hold the
|
| + // untagged value afterwards.
|
| + void SmiToDoubleFPURegister(Register smi,
|
| + DwVfpRegister value,
|
| + Register scratch1);
|
| +
|
| +
|
| +
|
| + // Truncates a double using a specific rounding mode.
|
| // Clears the z flag (ne condition) if an overflow occurs.
|
| - // If kCheckForInexactConversion is passed, the z flag is also cleared if the
|
| - // conversion was inexact, i.e. if the double value could not be converted
|
| - // exactly to a 32-bit integer.
|
| - void EmitVFPTruncate(VFPRoundingMode rounding_mode,
|
| + // If exact_conversion is true, the z flag is also cleared if the conversion
|
| + // was inexact, ie. if the double value could not be converted exactly
|
| + // to a 32bit integer.
|
| + void EmitFPUTruncate(FPURoundingMode rounding_mode,
|
| Register result,
|
| DwVfpRegister double_input,
|
| Register scratch,
|
| - DwVfpRegister double_scratch,
|
| CheckForInexactConversion check
|
| = kDontCheckForInexactConversion);
|
|
|
| // Helper for EmitECMATruncate.
|
| - // This will truncate a floating-point value outside of the signed 32bit
|
| + // This will truncate a floating-point value outside of the singed 32bit
|
| // integer range to a 32bit signed integer.
|
| // Expects the double value loaded in input_high and input_low.
|
| // Exits with the answer in 'result'.
|
| @@ -1003,10 +924,10 @@ class MacroAssembler: public Assembler {
|
| // Runtime calls
|
|
|
| // Call a code stub.
|
| - void CallStub(CodeStub* stub, Condition cond = al);
|
| + void CallStub(CodeStub* stub);
|
|
|
| // Call a code stub.
|
| - void TailCallStub(CodeStub* stub, Condition cond = al);
|
| + void TailCallStub(CodeStub* stub);
|
|
|
| // Call a runtime routine.
|
| void CallRuntime(const Runtime::Function* f, int num_arguments);
|
| @@ -1050,29 +971,14 @@ class MacroAssembler: public Assembler {
|
| void PrepareCallCFunction(int num_reg_arguments,
|
| Register scratch);
|
|
|
| - // There are two ways of passing double arguments on ARM, depending on
|
| - // whether soft or hard floating point ABI is used. These functions
|
| - // abstract parameter passing for the three different ways we call
|
| - // C functions from generated code.
|
| - void SetCallCDoubleArguments(DoubleRegister dreg);
|
| - void SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2);
|
| - void SetCallCDoubleArguments(DoubleRegister dreg, Register reg);
|
| -
|
| // Calls a C function and cleans up the space for arguments allocated
|
| // by PrepareCallCFunction. The called function is not allowed to trigger a
|
| // garbage collection, since that might move the code and invalidate the
|
| // return address (unless this is somehow accounted for by the called
|
| // function).
|
| - void CallCFunction(ExternalReference function, int num_arguments);
|
| + void CallCFunction(ExternalReference function, int num_reg_arguments,
|
| + int num_double_arguments = 0);
|
| void CallCFunction(Register function, int num_arguments);
|
| - void CallCFunction(ExternalReference function,
|
| - int num_reg_arguments,
|
| - int num_double_arguments);
|
| - void CallCFunction(Register function,
|
| - int num_reg_arguments,
|
| - int num_double_arguments);
|
| -
|
| - void GetCFunctionDoubleResult(const DoubleRegister dst);
|
|
|
| // Calls an API function. Allocates HandleScope, extracts returned value
|
| // from handle and propagates exceptions. Restores context. stack_space
|
| @@ -1096,11 +1002,51 @@ class MacroAssembler: public Assembler {
|
| // Store the function for the given builtin in the target register.
|
| void GetBuiltinFunction(Register target, Builtins::JavaScript id);
|
|
|
| + // ---------------------------------------------------------------------------
|
| + // Utilities
|
| +
|
| + void Ret(Condition cond = al);
|
| +
|
| + void Drop(int stack_elements);
|
| + void Ret(int drop);
|
| +
|
| + void Jump(Register target);
|
| + void Jump(intptr_t target, RelocInfo::Mode rmode);
|
| + void Jump(Handle<Code> code, RelocInfo::Mode rmode);
|
| + void Call(Label* target) { call(target); }
|
| + void Call(Handle<Code> code,
|
| + RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
|
| + TypeFeedbackId ast_id = TypeFeedbackId::None());
|
| +
|
| + // Emit call to the code we are currently generating.
|
| + void CallSelf() {
|
| + UNIMPLEMENTED();
|
| + }
|
| +
|
| + void Move(Register dst, Handle<Object> value);
|
| + // Move if the registers are not identical.
|
| + void Move(Register target, Register source);
|
| +
|
| + void Usat(Register dst, int satpos, Register src);
|
| + void Ubfx(Register dst, Register src, int lsb, int width);
|
| + void Sbfx(Register dst, Register src, int lsb, int width);
|
| + void Bfc(Register dst, int lsb, int width);
|
| + // scratch can be the same register as src (in which case it is trashed), but
|
| + // not the same as dst.
|
| + void Bfi(Register dst,
|
| + Register src,
|
| + Register scratch,
|
| + int lsb,
|
| + int width);
|
| +
|
| Handle<Object> CodeObject() {
|
| ASSERT(!code_object_.is_null());
|
| return code_object_;
|
| }
|
|
|
| + // Record code generator line mapping through comments.
|
| + // Use -code_comments to enable.
|
| + MacroAssembler* RecordFunctionLine(const char* function, int line);
|
|
|
| // ---------------------------------------------------------------------------
|
| // StatsCounter support
|
| @@ -1119,7 +1065,9 @@ class MacroAssembler: public Assembler {
|
| // Calls Abort(msg) if the condition cond is not satisfied.
|
| // Use --debug_code to enable.
|
| void Assert(Condition cond, const char* msg);
|
| - void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
|
| +
|
| + void AssertRegisterIsRoot(Register reg, Register scratch,
|
| + Heap::RootListIndex index);
|
| void AssertFastElements(Register elements);
|
|
|
| // Like Assert(), but always enabled.
|
| @@ -1128,6 +1076,12 @@ class MacroAssembler: public Assembler {
|
| // Print a message to stdout and abort execution.
|
| void Abort(const char* msg);
|
|
|
| + // Print an object to stdout.
|
| + void DebugPrint(Register obj);
|
| +
|
| + // Check that the stack is aligned.
|
| + void CheckStackAlignment();
|
| +
|
| // Verify restrictions about code generated in stubs.
|
| void set_generating_stub(bool value) { generating_stub_ = value; }
|
| bool generating_stub() { return generating_stub_; }
|
| @@ -1137,14 +1091,6 @@ class MacroAssembler: public Assembler {
|
| bool has_frame() { return has_frame_; }
|
| inline bool AllowThisStubCall(CodeStub* stub);
|
|
|
| - // EABI variant for double arguments in use.
|
| - bool use_eabi_hardfloat() {
|
| -#if USE_EABI_HARDFLOAT
|
| - return true;
|
| -#else
|
| - return false;
|
| -#endif
|
| - }
|
|
|
| // ---------------------------------------------------------------------------
|
| // Number utilities
|
| @@ -1170,28 +1116,27 @@ class MacroAssembler: public Assembler {
|
| // ---------------------------------------------------------------------------
|
| // Smi utilities
|
|
|
| - void SmiTag(Register reg, SBit s = LeaveCC) {
|
| - add(reg, reg, Operand(reg), s);
|
| + void SmiTag(Register reg) {
|
| + add(reg, reg, reg);
|
| }
|
| - void SmiTag(Register dst, Register src, SBit s = LeaveCC) {
|
| - add(dst, src, Operand(src), s);
|
| + void SmiTag(Register dst, Register src) {
|
| + add(dst, src, src);
|
| }
|
|
|
| // Try to convert int32 to smi. If the value is to large, preserve
|
| // the original value and jump to not_a_smi. Destroys scratch and
|
| // sets flags.
|
| void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
|
| - mov(scratch, reg);
|
| - SmiTag(scratch, SetCC);
|
| - b(vs, not_a_smi);
|
| + addv(scratch, reg, reg);
|
| + b(t, not_a_smi);
|
| mov(reg, scratch);
|
| }
|
|
|
| - void SmiUntag(Register reg, SBit s = LeaveCC) {
|
| - mov(reg, Operand(reg, ASR, kSmiTagSize), s);
|
| + void SmiUntag(Register reg) {
|
| + asr(reg, reg, Operand(kSmiTagSize));
|
| }
|
| - void SmiUntag(Register dst, Register src, SBit s = LeaveCC) {
|
| - mov(dst, Operand(src, ASR, kSmiTagSize), s);
|
| + void SmiUntag(Register dst, Register src) {
|
| + asr(dst, src, Operand(kSmiTagSize));
|
| }
|
|
|
| // Untag the source value into destination and jump if source is a smi.
|
| @@ -1203,118 +1148,40 @@ class MacroAssembler: public Assembler {
|
| void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
|
|
|
| // Jump the register contains a smi.
|
| - inline void JumpIfSmi(Register value, Label* smi_label) {
|
| + inline void JumpIfSmi(Register value, Label* smi_label,
|
| + Label::Distance distance = Label::kFar) {
|
| tst(value, Operand(kSmiTagMask));
|
| - b(eq, smi_label);
|
| + if (distance == Label::kFar)
|
| + bt(smi_label);
|
| + else
|
| + bt_near(smi_label);
|
| }
|
| // Jump if either of the registers contain a non-smi.
|
| - inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
|
| + inline void JumpIfNotSmi(Register value, Label* not_smi_label,
|
| + Label::Distance distance = Label::kFar) {
|
| tst(value, Operand(kSmiTagMask));
|
| - b(ne, not_smi_label);
|
| + if (distance == Label::kFar)
|
| + bf(not_smi_label);
|
| + else
|
| + bf_near(not_smi_label);
|
| }
|
| +
|
| // Jump if either of the registers contain a non-smi.
|
| - void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
|
| + void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi,
|
| + Label::Distance distance = Label::kFar);
|
| // Jump if either of the registers contain a smi.
|
| - void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
|
| -
|
| - // Abort execution if argument is a smi, enabled via --debug-code.
|
| - void AssertNotSmi(Register object);
|
| - void AssertSmi(Register object);
|
| -
|
| - // Abort execution if argument is a string, enabled via --debug-code.
|
| - void AssertString(Register object);
|
| -
|
| - // Abort execution if argument is not the root value with the given index,
|
| - // enabled via --debug-code.
|
| - void AssertRootValue(Register src,
|
| - Heap::RootListIndex root_value_index,
|
| - const char* message);
|
| -
|
| - // ---------------------------------------------------------------------------
|
| - // HeapNumber utilities
|
| -
|
| - void JumpIfNotHeapNumber(Register object,
|
| - Register heap_number_map,
|
| - Register scratch,
|
| - Label* on_not_heap_number);
|
| -
|
| - // ---------------------------------------------------------------------------
|
| - // String utilities
|
| -
|
| - // Checks if both objects are sequential ASCII strings and jumps to label
|
| - // if either is not. Assumes that neither object is a smi.
|
| - void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1,
|
| - Register object2,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Label* failure);
|
| -
|
| - // Checks if both objects are sequential ASCII strings and jumps to label
|
| - // if either is not.
|
| - void JumpIfNotBothSequentialAsciiStrings(Register first,
|
| - Register second,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Label* not_flat_ascii_strings);
|
| -
|
| - // Checks if both instance types are sequential ASCII strings and jumps to
|
| - // label if either is not.
|
| - void JumpIfBothInstanceTypesAreNotSequentialAscii(
|
| - Register first_object_instance_type,
|
| - Register second_object_instance_type,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Label* failure);
|
| -
|
| - // Check if instance type is sequential ASCII string and jump to label if
|
| - // it is not.
|
| - void JumpIfInstanceTypeIsNotSequentialAscii(Register type,
|
| - Register scratch,
|
| - Label* failure);
|
| -
|
| -
|
| - // ---------------------------------------------------------------------------
|
| - // Patching helpers.
|
| -
|
| - // Get the location of a relocated constant (its address in the constant pool)
|
| - // from its load site.
|
| - void GetRelocatedValueLocation(Register ldr_location,
|
| - Register result);
|
| -
|
| -
|
| - void ClampUint8(Register output_reg, Register input_reg);
|
| -
|
| - void ClampDoubleToUint8(Register result_reg,
|
| - DoubleRegister input_reg,
|
| - DoubleRegister temp_double_reg);
|
| -
|
| -
|
| - void LoadInstanceDescriptors(Register map, Register descriptors);
|
| - void EnumLength(Register dst, Register map);
|
| - void NumberOfOwnDescriptors(Register dst, Register map);
|
| -
|
| - template<typename Field>
|
| - void DecodeField(Register reg) {
|
| - static const int shift = Field::kShift;
|
| - static const int mask = (Field::kMask >> shift) << kSmiTagSize;
|
| - mov(reg, Operand(reg, LSR, shift));
|
| - and_(reg, reg, Operand(mask));
|
| - }
|
| -
|
| + void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi,
|
| + Label::Distance distance = Label::kFar);
|
| // Activation support.
|
| void EnterFrame(StackFrame::Type type);
|
| void LeaveFrame(StackFrame::Type type);
|
|
|
| - // Expects object in r0 and returns map with validated enum cache
|
| - // in r0. Assumes that any other register can be used as a scratch.
|
| - void CheckEnumCache(Register null_value, Label* call_runtime);
|
|
|
| private:
|
| void CallCFunctionHelper(Register function,
|
| int num_reg_arguments,
|
| int num_double_arguments);
|
|
|
| - void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
|
|
|
| // Helper functions for generating invokes.
|
| void InvokePrologue(const ParameterCount& expected,
|
| @@ -1327,18 +1194,14 @@ class MacroAssembler: public Assembler {
|
| const CallWrapper& call_wrapper,
|
| CallKind call_kind);
|
|
|
| + void LeaveExitFrameEpilogue();
|
| +
|
| void InitializeNewString(Register string,
|
| Register length,
|
| Heap::RootListIndex map_index,
|
| Register scratch1,
|
| Register scratch2);
|
|
|
| - // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
|
| - void InNewSpace(Register object,
|
| - Register scratch,
|
| - Condition cond, // eq for new space, ne otherwise.
|
| - Label* branch);
|
| -
|
| // Helper for finding the mark bits for an address. Afterwards, the
|
| // bitmap register points at the word with the mark bits and the mask
|
| // the position of the first bit. Leaves addr_reg unchanged.
|
| @@ -1346,6 +1209,19 @@ class MacroAssembler: public Assembler {
|
| Register bitmap_reg,
|
| Register mask_reg);
|
|
|
| + // Allocation support helpers.
|
| + void LoadAllocationTopHelper(Register result,
|
| + Register scratch,
|
| + AllocationFlags flags);
|
| + void UpdateAllocationTopHelper(Register result_end, Register scratch);
|
| +
|
| + // Helper for PopHandleScope. Allowed to perform a GC and returns
|
| + // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
|
| + // possibly returns a failure object indicating an allocation failure.
|
| + MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
|
| + Register scratch,
|
| + bool gc_allowed);
|
| +
|
| // Helper for throwing exceptions. Compute a handler address and jump to
|
| // it. See the implementation for register usage.
|
| void JumpToHandlerEntry();
|
| @@ -1380,12 +1256,6 @@ class CodePatcher {
|
| // Macro assembler to emit code.
|
| MacroAssembler* masm() { return &masm_; }
|
|
|
| - // Emit an instruction directly.
|
| - void Emit(Instr instr);
|
| -
|
| - // Emit an address directly.
|
| - void Emit(Address addr);
|
| -
|
| // Emit the condition part of an instruction leaving the rest of the current
|
| // instruction unchanged.
|
| void EmitCondition(Condition cond);
|
| @@ -1411,16 +1281,13 @@ inline MemOperand GlobalObjectOperand() {
|
| }
|
|
|
|
|
| -#ifdef GENERATED_CODE_COVERAGE
|
| -#define CODE_COVERAGE_STRINGIFY(x) #x
|
| -#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
|
| -#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
|
| -#define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
|
| +#ifdef DEBUG
|
| +# define ACCESS_MASM(masm) masm->RecordFunctionLine(__FUNCTION__, __LINE__)->
|
| #else
|
| -#define ACCESS_MASM(masm) masm->
|
| +# define ACCESS_MASM(masm) masm->
|
| #endif
|
|
|
|
|
| } } // namespace v8::internal
|
|
|
| -#endif // V8_ARM_MACRO_ASSEMBLER_ARM_H_
|
| +#endif // V8_SH4_MACRO_ASSEMBLER_SH4_H_
|
|
|