js/src/jit/mips/MacroAssembler-mips.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef jit_mips_MacroAssembler_mips_h
     8 #define jit_mips_MacroAssembler_mips_h
    10 #include "jsopcode.h"
    12 #include "jit/IonCaches.h"
    13 #include "jit/IonFrames.h"
    14 #include "jit/mips/Assembler-mips.h"
    15 #include "jit/MoveResolver.h"
    17 namespace js {
    18 namespace jit {
    20 enum LoadStoreSize
    21 {
    22     SizeByte = 8,
    23     SizeHalfWord = 16,
    24     SizeWord = 32,
    25     SizeDouble = 64
    26 };
    28 enum LoadStoreExtension
    29 {
    30     ZeroExtend = 0,
    31     SignExtend = 1
    32 };
    34 enum JumpKind
    35 {
    36     LongJump = 0,
    37     ShortJump = 1
    38 };
    40 struct ImmTag : public Imm32
    41 {
    42     ImmTag(JSValueTag mask)
    43       : Imm32(int32_t(mask))
    44     { }
    45 };
    47 struct ImmType : public ImmTag
    48 {
    49     ImmType(JSValueType type)
    50       : ImmTag(JSVAL_TYPE_TO_TAG(type))
    51     { }
    52 };
    54 static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data);
    55 static const ValueOperand softfpReturnOperand = ValueOperand(v1, v0);
    57 static Register CallReg = t9;
    58 static const int defaultShift = 3;
    59 static_assert(1 << defaultShift == sizeof(jsval), "The defaultShift is wrong");
    61 class MacroAssemblerMIPS : public Assembler
    62 {
    63   public:
    65     void convertBoolToInt32(Register source, Register dest);
    66     void convertInt32ToDouble(const Register &src, const FloatRegister &dest);
    67     void convertInt32ToDouble(const Address &src, FloatRegister dest);
    68     void convertUInt32ToDouble(const Register &src, const FloatRegister &dest);
    69     void convertUInt32ToFloat32(const Register &src, const FloatRegister &dest);
    70     void convertDoubleToFloat32(const FloatRegister &src, const FloatRegister &dest);
    71     void branchTruncateDouble(const FloatRegister &src, const Register &dest, Label *fail);
    72     void convertDoubleToInt32(const FloatRegister &src, const Register &dest, Label *fail,
    73                               bool negativeZeroCheck = true);
    74     void convertFloat32ToInt32(const FloatRegister &src, const Register &dest, Label *fail,
    75                                bool negativeZeroCheck = true);
    77     void convertFloat32ToDouble(const FloatRegister &src, const FloatRegister &dest);
    78     void branchTruncateFloat32(const FloatRegister &src, const Register &dest, Label *fail);
    79     void convertInt32ToFloat32(const Register &src, const FloatRegister &dest);
    80     void convertInt32ToFloat32(const Address &src, FloatRegister dest);
    83     void addDouble(FloatRegister src, FloatRegister dest);
    84     void subDouble(FloatRegister src, FloatRegister dest);
    85     void mulDouble(FloatRegister src, FloatRegister dest);
    86     void divDouble(FloatRegister src, FloatRegister dest);
    88     void negateDouble(FloatRegister reg);
    89     void inc64(AbsoluteAddress dest);
    91   public:
    93     void ma_move(Register rd, Register rs);
    95     void ma_li(Register dest, const ImmGCPtr &ptr);
    97     void ma_li(const Register &dest, AbsoluteLabel *label);
    99     void ma_li(Register dest, Imm32 imm);
   100     void ma_liPatchable(Register dest, Imm32 imm);
   101     void ma_liPatchable(Register dest, ImmPtr imm);
   103     // Shift operations
   104     void ma_sll(Register rd, Register rt, Imm32 shift);
   105     void ma_srl(Register rd, Register rt, Imm32 shift);
   106     void ma_sra(Register rd, Register rt, Imm32 shift);
   107     void ma_ror(Register rd, Register rt, Imm32 shift);
   108     void ma_rol(Register rd, Register rt, Imm32 shift);
   110     void ma_sll(Register rd, Register rt, Register shift);
   111     void ma_srl(Register rd, Register rt, Register shift);
   112     void ma_sra(Register rd, Register rt, Register shift);
   113     void ma_ror(Register rd, Register rt, Register shift);
   114     void ma_rol(Register rd, Register rt, Register shift);
   116     // Negate
   117     void ma_negu(Register rd, Register rs);
   119     void ma_not(Register rd, Register rs);
   121     // and
   122     void ma_and(Register rd, Register rs);
   123     void ma_and(Register rd, Register rs, Register rt);
   124     void ma_and(Register rd, Imm32 imm);
   125     void ma_and(Register rd, Register rs, Imm32 imm);
   127     // or
   128     void ma_or(Register rd, Register rs);
   129     void ma_or(Register rd, Register rs, Register rt);
   130     void ma_or(Register rd, Imm32 imm);
   131     void ma_or(Register rd, Register rs, Imm32 imm);
   133     // xor
   134     void ma_xor(Register rd, Register rs);
   135     void ma_xor(Register rd, Register rs, Register rt);
   136     void ma_xor(Register rd, Imm32 imm);
   137     void ma_xor(Register rd, Register rs, Imm32 imm);
   139     // load
   140     void ma_load(const Register &dest, Address address, LoadStoreSize size = SizeWord,
   141                  LoadStoreExtension extension = SignExtend);
   142     void ma_load(const Register &dest, const BaseIndex &src, LoadStoreSize size = SizeWord,
   143                  LoadStoreExtension extension = SignExtend);
   145     // store
   146     void ma_store(const Register &data, Address address, LoadStoreSize size = SizeWord,
   147                   LoadStoreExtension extension = SignExtend);
   148     void ma_store(const Register &data, const BaseIndex &dest, LoadStoreSize size = SizeWord,
   149                   LoadStoreExtension extension = SignExtend);
   150     void ma_store(const Imm32 &imm, const BaseIndex &dest, LoadStoreSize size = SizeWord,
   151                   LoadStoreExtension extension = SignExtend);
   153     void computeScaledAddress(const BaseIndex &address, Register dest);
   155     void computeEffectiveAddress(const Address &address, Register dest) {
   156         ma_addu(dest, address.base, Imm32(address.offset));
   157     }
   159     void computeEffectiveAddress(const BaseIndex &address, Register dest) {
   160         computeScaledAddress(address, dest);
   161         if (address.offset) {
   162             ma_addu(dest, dest, Imm32(address.offset));
   163         }
   164     }
   166     // arithmetic based ops
   167     // add
   168     void ma_addu(Register rd, Register rs, Imm32 imm);
   169     void ma_addu(Register rd, Register rs);
   170     void ma_addu(Register rd, Imm32 imm);
   171     void ma_addTestOverflow(Register rd, Register rs, Register rt, Label *overflow);
   172     void ma_addTestOverflow(Register rd, Register rs, Imm32 imm, Label *overflow);
   174     // subtract
   175     void ma_subu(Register rd, Register rs, Register rt);
   176     void ma_subu(Register rd, Register rs, Imm32 imm);
   177     void ma_subu(Register rd, Imm32 imm);
   178     void ma_subTestOverflow(Register rd, Register rs, Register rt, Label *overflow);
   179     void ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label *overflow);
   181     // multiplies.  For now, there are only few that we care about.
   182     void ma_mult(Register rs, Imm32 imm);
   183     void ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label *overflow);
   184     void ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label *overflow);
   186     // divisions
   187     void ma_div_branch_overflow(Register rd, Register rs, Register rt, Label *overflow);
   188     void ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label *overflow);
   190     // fast mod, uses scratch registers, and thus needs to be in the assembler
   191     // implicitly assumes that we can overwrite dest at the beginning of the sequence
   192     void ma_mod_mask(Register src, Register dest, Register hold, int32_t shift,
   193                      Label *negZero = nullptr);
   195     // memory
   196     // shortcut for when we know we're transferring 32 bits of data
   197     void ma_lw(Register data, Address address);
   199     void ma_sw(Register data, Address address);
   200     void ma_sw(Imm32 imm, Address address);
   202     void ma_pop(Register r);
   203     void ma_push(Register r);
   205     // branches when done from within mips-specific code
   206     void ma_b(Register lhs, Register rhs, Label *l, Condition c, JumpKind jumpKind = LongJump);
   207     void ma_b(Register lhs, Imm32 imm, Label *l, Condition c, JumpKind jumpKind = LongJump);
   208     void ma_b(Register lhs, Address addr, Label *l, Condition c, JumpKind jumpKind = LongJump);
   209     void ma_b(Address addr, Imm32 imm, Label *l, Condition c, JumpKind jumpKind = LongJump);
   210     void ma_b(Label *l, JumpKind jumpKind = LongJump);
   211     void ma_bal(Label *l, JumpKind jumpKind = LongJump);
   213     // fp instructions
   214     void ma_lis(FloatRegister dest, float value);
   215     void ma_lid(FloatRegister dest, double value);
   216     void ma_liNegZero(FloatRegister dest);
   218     void ma_mv(FloatRegister src, ValueOperand dest);
   219     void ma_mv(ValueOperand src, FloatRegister dest);
   221     void ma_ls(FloatRegister fd, Address address);
   222     void ma_ld(FloatRegister fd, Address address);
   223     void ma_sd(FloatRegister fd, Address address);
   224     void ma_sd(FloatRegister fd, BaseIndex address);
   225     void ma_ss(FloatRegister fd, Address address);
   226     void ma_ss(FloatRegister fd, BaseIndex address);
   228     void ma_pop(FloatRegister fs);
   229     void ma_push(FloatRegister fs);
   231     //FP branches
   232     void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label *label, DoubleCondition c,
   233                  JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
   234     void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label *label, DoubleCondition c,
   235                  JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
   238     // These fuctions abstract the access to high part of the double precision
   239     // float register. It is intended to work on both 32 bit and 64 bit
   240     // floating point coprocessor.
   241     // :TODO: (Bug 985881) Modify this for N32 ABI to use mthc1 and mfhc1
   242     void moveToDoubleHi(Register src, FloatRegister dest) {
   243         as_mtc1(src, getOddPair(dest));
   244     }
   245     void moveFromDoubleHi(FloatRegister src, Register dest) {
   246         as_mfc1(dest, getOddPair(src));
   247     }
   249     void moveToDoubleLo(Register src, FloatRegister dest) {
   250         as_mtc1(src, dest);
   251     }
   252     void moveFromDoubleLo(FloatRegister src, Register dest) {
   253         as_mfc1(dest, src);
   254     }
   256     void moveToFloat32(Register src, FloatRegister dest) {
   257         as_mtc1(src, dest);
   258     }
   259     void moveFromFloat32(FloatRegister src, Register dest) {
   260         as_mfc1(dest, src);
   261     }
   263   protected:
   264     void branchWithCode(InstImm code, Label *label, JumpKind jumpKind);
   265     Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
   267     void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
   268                               DoubleCondition c, FloatTestKind *testKind,
   269                               FPConditionBit fcc = FCC0);
   271   public:
   272     // calls an Ion function, assumes that the stack is untouched (8 byte alinged)
   273     void ma_callIon(const Register reg);
   274     // callso an Ion function, assuming that sp has already been decremented
   275     void ma_callIonNoPush(const Register reg);
   276     // calls an ion function, assuming that the stack is currently not 8 byte aligned
   277     void ma_callIonHalfPush(const Register reg);
   279     void ma_call(ImmPtr dest);
   281     void ma_jump(ImmPtr dest);
   283     void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c);
   284     void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c);
   285     void ma_cmp_set(Register rd, Register rs, Address addr, Condition c);
   286     void ma_cmp_set(Register dst, Address lhs, Register imm, Condition c);
   287     void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
   288     void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
   289 };
   291 class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
   292 {
   293     // Number of bytes the stack is adjusted inside a call to C. Calls to C may
   294     // not be nested.
   295     bool inCall_;
   296     uint32_t args_;
   297     // The actual number of arguments that were passed, used to assert that
   298     // the initial number of arguments declared was correct.
   299     uint32_t passedArgs_;
   301     uint32_t usedArgSlots_;
   302     MoveOp::Type firstArgType;
   304     bool dynamicAlignment_;
   306     bool enoughMemory_;
   307     // Compute space needed for the function call and set the properties of the
   308     // callee.  It returns the space which has to be allocated for calling the
   309     // function.
   310     //
   311     // arg            Number of arguments of the function.
   312     void setupABICall(uint32_t arg);
   314   protected:
   315     MoveResolver moveResolver_;
   317     // Extra bytes currently pushed onto the frame beyond frameDepth_. This is
   318     // needed to compute offsets to stack slots while temporary space has been
   319     // reserved for unexpected spills or C++ function calls. It is maintained
   320     // by functions which track stack alignment, which for clear distinction
   321     // use StudlyCaps (for example, Push, Pop).
   322     uint32_t framePushed_;
   323     void adjustFrame(int value) {
   324         setFramePushed(framePushed_ + value);
   325     }
   326   public:
   327     MacroAssemblerMIPSCompat()
   328       : inCall_(false),
   329         enoughMemory_(true),
   330         framePushed_(0)
   331     { }
   332     bool oom() const {
   333         return Assembler::oom();
   334     }
   336   public:
   337     using MacroAssemblerMIPS::call;
   339     void j(Label *dest) {
   340         ma_b(dest);
   341     }
   343     void mov(Register src, Register dest) {
   344         as_or(dest, src, zero);
   345     }
   346     void mov(ImmWord imm, Register dest) {
   347         ma_li(dest, Imm32(imm.value));
   348     }
   349     void mov(ImmPtr imm, Register dest) {
   350         mov(ImmWord(uintptr_t(imm.value)), dest);
   351     }
   352     void mov(Register src, Address dest) {
   353         MOZ_ASSUME_UNREACHABLE("NYI-IC");
   354     }
   355     void mov(Address src, Register dest) {
   356         MOZ_ASSUME_UNREACHABLE("NYI-IC");
   357     }
   359     void call(const Register reg) {
   360         as_jalr(reg);
   361         as_nop();
   362     }
   364     void call(Label *label) {
   365         // for now, assume that it'll be nearby?
   366         ma_bal(label);
   367     }
   369     void call(ImmWord imm) {
   370         call(ImmPtr((void*)imm.value));
   371     }
   372     void call(ImmPtr imm) {
   373         BufferOffset bo = m_buffer.nextOffset();
   374         addPendingJump(bo, imm, Relocation::HARDCODED);
   375         ma_call(imm);
   376     }
   377     void call(AsmJSImmPtr imm) {
   378         movePtr(imm, CallReg);
   379         call(CallReg);
   380     }
   381     void call(JitCode *c) {
   382         BufferOffset bo = m_buffer.nextOffset();
   383         addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
   384         ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
   385         ma_callIonHalfPush(ScratchRegister);
   386     }
   387     void branch(JitCode *c) {
   388         BufferOffset bo = m_buffer.nextOffset();
   389         addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
   390         ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
   391         as_jr(ScratchRegister);
   392         as_nop();
   393     }
   394     void branch(const Register reg) {
   395         as_jr(reg);
   396         as_nop();
   397     }
   398     void nop() {
   399         as_nop();
   400     }
   401     void ret() {
   402         ma_pop(ra);
   403         as_jr(ra);
   404         as_nop();
   405     }
   406     void retn(Imm32 n) {
   407         // pc <- [sp]; sp += n
   408         ma_lw(ra, Address(StackPointer, 0));
   409         ma_addu(StackPointer, StackPointer, n);
   410         as_jr(ra);
   411         as_nop();
   412     }
   413     void push(Imm32 imm) {
   414         ma_li(ScratchRegister, imm);
   415         ma_push(ScratchRegister);
   416     }
   417     void push(ImmWord imm) {
   418         ma_li(ScratchRegister, Imm32(imm.value));
   419         ma_push(ScratchRegister);
   420     }
   421     void push(ImmGCPtr imm) {
   422         ma_li(ScratchRegister, imm);
   423         ma_push(ScratchRegister);
   424     }
   425     void push(const Address &address) {
   426         ma_lw(ScratchRegister, address);
   427         ma_push(ScratchRegister);
   428     }
   429     void push(const Register &reg) {
   430         ma_push(reg);
   431     }
   432     void push(const FloatRegister &reg) {
   433         ma_push(reg);
   434     }
   435     void pop(const Register &reg) {
   436         ma_pop(reg);
   437     }
   438     void pop(const FloatRegister &reg) {
   439         ma_pop(reg);
   440     }
   442     // Emit a branch that can be toggled to a non-operation. On MIPS we use
   443     // "andi" instruction to toggle the branch.
   444     // See ToggleToJmp(), ToggleToCmp().
   445     CodeOffsetLabel toggledJump(Label *label);
   447     // Emit a "jalr" or "nop" instruction. ToggleCall can be used to patch
   448     // this instruction.
   449     CodeOffsetLabel toggledCall(JitCode *target, bool enabled);
   451     static size_t ToggledCallSize() {
   452         // Four instructions used in: MacroAssemblerMIPSCompat::toggledCall
   453         return 4 * sizeof(uint32_t);
   454     }
   456     CodeOffsetLabel pushWithPatch(ImmWord imm) {
   457         CodeOffsetLabel label = movWithPatch(imm, ScratchRegister);
   458         ma_push(ScratchRegister);
   459         return label;
   460     }
   462     CodeOffsetLabel movWithPatch(ImmWord imm, Register dest) {
   463         CodeOffsetLabel label = currentOffset();
   464         ma_liPatchable(dest, Imm32(imm.value));
   465         return label;
   466     }
   467     CodeOffsetLabel movWithPatch(ImmPtr imm, Register dest) {
   468         return movWithPatch(ImmWord(uintptr_t(imm.value)), dest);
   469     }
   471     void jump(Label *label) {
   472         ma_b(label);
   473     }
   474     void jump(Register reg) {
   475         as_jr(reg);
   476         as_nop();
   477     }
   478     void jump(const Address &address) {
   479         ma_lw(ScratchRegister, address);
   480         as_jr(ScratchRegister);
   481         as_nop();
   482     }
   484     void neg32(Register reg) {
   485         ma_negu(reg, reg);
   486     }
   487     void negl(Register reg) {
   488         ma_negu(reg, reg);
   489     }
   491     // Returns the register containing the type tag.
   492     Register splitTagForTest(const ValueOperand &value) {
   493         return value.typeReg();
   494     }
   496     void branchTestGCThing(Condition cond, const Address &address, Label *label);
   497     void branchTestGCThing(Condition cond, const BaseIndex &src, Label *label);
   499     void branchTestPrimitive(Condition cond, const ValueOperand &value, Label *label);
   500     void branchTestPrimitive(Condition cond, const Register &tag, Label *label);
   502     void branchTestValue(Condition cond, const ValueOperand &value, const Value &v, Label *label);
   503     void branchTestValue(Condition cond, const Address &valaddr, const ValueOperand &value,
   504                          Label *label);
   506     // unboxing code
   507     void unboxInt32(const ValueOperand &operand, const Register &dest);
   508     void unboxInt32(const Address &src, const Register &dest);
   509     void unboxBoolean(const ValueOperand &operand, const Register &dest);
   510     void unboxBoolean(const Address &src, const Register &dest);
   511     void unboxDouble(const ValueOperand &operand, const FloatRegister &dest);
   512     void unboxDouble(const Address &src, const FloatRegister &dest);
   513     void unboxString(const ValueOperand &operand, const Register &dest);
   514     void unboxString(const Address &src, const Register &dest);
   515     void unboxObject(const ValueOperand &src, const Register &dest);
   516     void unboxValue(const ValueOperand &src, AnyRegister dest);
   517     void unboxPrivate(const ValueOperand &src, Register dest);
   519     void notBoolean(const ValueOperand &val) {
   520         as_xori(val.payloadReg(), val.payloadReg(), 1);
   521     }
   523     // boxing code
   524     void boxDouble(const FloatRegister &src, const ValueOperand &dest);
   525     void boxNonDouble(JSValueType type, const Register &src, const ValueOperand &dest);
   527     // Extended unboxing API. If the payload is already in a register, returns
   528     // that register. Otherwise, provides a move to the given scratch register,
   529     // and returns that.
   530     Register extractObject(const Address &address, Register scratch);
   531     Register extractObject(const ValueOperand &value, Register scratch) {
   532         return value.payloadReg();
   533     }
   534     Register extractInt32(const ValueOperand &value, Register scratch) {
   535         return value.payloadReg();
   536     }
   537     Register extractBoolean(const ValueOperand &value, Register scratch) {
   538         return value.payloadReg();
   539     }
   540     Register extractTag(const Address &address, Register scratch);
   541     Register extractTag(const BaseIndex &address, Register scratch);
   542     Register extractTag(const ValueOperand &value, Register scratch) {
   543         return value.typeReg();
   544     }
   546     void boolValueToDouble(const ValueOperand &operand, const FloatRegister &dest);
   547     void int32ValueToDouble(const ValueOperand &operand, const FloatRegister &dest);
   548     void loadInt32OrDouble(const Address &address, const FloatRegister &dest);
   549     void loadInt32OrDouble(Register base, Register index,
   550                            const FloatRegister &dest, int32_t shift = defaultShift);
   551     void loadConstantDouble(double dp, const FloatRegister &dest);
   553     void boolValueToFloat32(const ValueOperand &operand, const FloatRegister &dest);
   554     void int32ValueToFloat32(const ValueOperand &operand, const FloatRegister &dest);
   555     void loadConstantFloat32(float f, const FloatRegister &dest);
   557     void branchTestInt32(Condition cond, const ValueOperand &value, Label *label);
   558     void branchTestInt32(Condition cond, const Register &tag, Label *label);
   559     void branchTestInt32(Condition cond, const Address &address, Label *label);
   560     void branchTestInt32(Condition cond, const BaseIndex &src, Label *label);
   562     void branchTestBoolean(Condition cond, const ValueOperand &value, Label *label);
   563     void branchTestBoolean(Condition cond, const Register &tag, Label *label);
   564     void branchTestBoolean(Condition cond, const BaseIndex &src, Label *label);
   566     void branch32(Condition cond, Register lhs, Register rhs, Label *label) {
   567         ma_b(lhs, rhs, label, cond);
   568     }
   569     void branch32(Condition cond, Register lhs, Imm32 imm, Label *label) {
   570         ma_b(lhs, imm, label, cond);
   571     }
   572     void branch32(Condition cond, const Operand &lhs, Register rhs, Label *label) {
   573         if (lhs.getTag() == Operand::REG) {
   574             ma_b(lhs.toReg(), rhs, label, cond);
   575         } else {
   576             branch32(cond, lhs.toAddress(), rhs, label);
   577         }
   578     }
   579     void branch32(Condition cond, const Operand &lhs, Imm32 rhs, Label *label) {
   580         if (lhs.getTag() == Operand::REG) {
   581             ma_b(lhs.toReg(), rhs, label, cond);
   582         } else {
   583             branch32(cond, lhs.toAddress(), rhs, label);
   584         }
   585     }
   586     void branch32(Condition cond, const Address &lhs, Register rhs, Label *label) {
   587         ma_lw(ScratchRegister, lhs);
   588         ma_b(ScratchRegister, rhs, label, cond);
   589     }
   590     void branch32(Condition cond, const Address &lhs, Imm32 rhs, Label *label) {
   591         ma_lw(SecondScratchReg, lhs);
   592         ma_b(SecondScratchReg, rhs, label, cond);
   593     }
   594     void branchPtr(Condition cond, const Address &lhs, Register rhs, Label *label) {
   595         branch32(cond, lhs, rhs, label);
   596     }
   598     void branchPrivatePtr(Condition cond, const Address &lhs, ImmPtr ptr, Label *label) {
   599         branchPtr(cond, lhs, ptr, label);
   600     }
   602     void branchPrivatePtr(Condition cond, const Address &lhs, Register ptr, Label *label) {
   603         branchPtr(cond, lhs, ptr, label);
   604     }
   606     void branchPrivatePtr(Condition cond, Register lhs, ImmWord ptr, Label *label) {
   607         branchPtr(cond, lhs, ptr, label);
   608     }
   610     void branchTestDouble(Condition cond, const ValueOperand &value, Label *label);
   611     void branchTestDouble(Condition cond, const Register &tag, Label *label);
   612     void branchTestDouble(Condition cond, const Address &address, Label *label);
   613     void branchTestDouble(Condition cond, const BaseIndex &src, Label *label);
   615     void branchTestNull(Condition cond, const ValueOperand &value, Label *label);
   616     void branchTestNull(Condition cond, const Register &tag, Label *label);
   617     void branchTestNull(Condition cond, const BaseIndex &src, Label *label);
   619     void branchTestObject(Condition cond, const ValueOperand &value, Label *label);
   620     void branchTestObject(Condition cond, const Register &tag, Label *label);
   621     void branchTestObject(Condition cond, const BaseIndex &src, Label *label);
   623     void branchTestString(Condition cond, const ValueOperand &value, Label *label);
   624     void branchTestString(Condition cond, const Register &tag, Label *label);
   625     void branchTestString(Condition cond, const BaseIndex &src, Label *label);
   627     void branchTestUndefined(Condition cond, const ValueOperand &value, Label *label);
   628     void branchTestUndefined(Condition cond, const Register &tag, Label *label);
   629     void branchTestUndefined(Condition cond, const BaseIndex &src, Label *label);
   630     void branchTestUndefined(Condition cond, const Address &address, Label *label);
   632     void branchTestNumber(Condition cond, const ValueOperand &value, Label *label);
   633     void branchTestNumber(Condition cond, const Register &tag, Label *label);
   635     void branchTestMagic(Condition cond, const ValueOperand &value, Label *label);
   636     void branchTestMagic(Condition cond, const Register &tag, Label *label);
   637     void branchTestMagic(Condition cond, const Address &address, Label *label);
   638     void branchTestMagic(Condition cond, const BaseIndex &src, Label *label);
   640     void branchTestMagicValue(Condition cond, const ValueOperand &val, JSWhyMagic why,
   641                               Label *label) {
   642         MOZ_ASSERT(cond == Equal || cond == NotEqual);
   643         // Test for magic
   644         Label notmagic;
   645         branchTestMagic(cond, val, &notmagic);
   646         // Test magic value
   647         branch32(cond, val.payloadReg(), Imm32(static_cast<int32_t>(why)), label);
   648         bind(&notmagic);
   649     }
   651     void branchTestInt32Truthy(bool b, const ValueOperand &value, Label *label);
   653     void branchTestStringTruthy(bool b, const ValueOperand &value, Label *label);
   655     void branchTestDoubleTruthy(bool b, const FloatRegister &value, Label *label);
   657     void branchTestBooleanTruthy(bool b, const ValueOperand &operand, Label *label);
   659     void branchTest32(Condition cond, const Register &lhs, const Register &rhs, Label *label) {
   660         MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
   661         if (lhs == rhs) {
   662             ma_b(lhs, rhs, label, cond);
   663         } else {
   664             as_and(ScratchRegister, lhs, rhs);
   665             ma_b(ScratchRegister, ScratchRegister, label, cond);
   666         }
   667     }
   668     void branchTest32(Condition cond, const Register &lhs, Imm32 imm, Label *label) {
   669         ma_li(ScratchRegister, imm);
   670         branchTest32(cond, lhs, ScratchRegister, label);
   671     }
   672     void branchTest32(Condition cond, const Address &address, Imm32 imm, Label *label) {
   673         ma_lw(SecondScratchReg, address);
   674         branchTest32(cond, SecondScratchReg, imm, label);
   675     }
   676     void branchTestPtr(Condition cond, const Register &lhs, const Register &rhs, Label *label) {
   677         branchTest32(cond, lhs, rhs, label);
   678     }
   679     void branchTestPtr(Condition cond, const Register &lhs, const Imm32 rhs, Label *label) {
   680         branchTest32(cond, lhs, rhs, label);
   681     }
   682     void branchTestPtr(Condition cond, const Address &lhs, Imm32 imm, Label *label) {
   683         branchTest32(cond, lhs, imm, label);
   684     }
   685     void branchPtr(Condition cond, Register lhs, Register rhs, Label *label) {
   686         ma_b(lhs, rhs, label, cond);
   687     }
   688     void branchPtr(Condition cond, Register lhs, ImmGCPtr ptr, Label *label) {
   689         ma_li(ScratchRegister, ptr);
   690         ma_b(lhs, ScratchRegister, label, cond);
   691     }
   692     void branchPtr(Condition cond, Register lhs, ImmWord imm, Label *label) {
   693         ma_b(lhs, Imm32(imm.value), label, cond);
   694     }
   695     void branchPtr(Condition cond, Register lhs, ImmPtr imm, Label *label) {
   696         branchPtr(cond, lhs, ImmWord(uintptr_t(imm.value)), label);
   697     }
   698     void branchPtr(Condition cond, Register lhs, AsmJSImmPtr imm, Label *label) {
   699         movePtr(imm, ScratchRegister);
   700         branchPtr(cond, lhs, ScratchRegister, label);
   701     }
   702     void branchPtr(Condition cond, Register lhs, Imm32 imm, Label *label) {
   703         ma_b(lhs, imm, label, cond);
   704     }
   705     void decBranchPtr(Condition cond, const Register &lhs, Imm32 imm, Label *label) {
   706         subPtr(imm, lhs);
   707         branch32(cond, lhs, Imm32(0), label);
   708     }
   710 protected:
   711     uint32_t getType(const Value &val);
   712     void moveData(const Value &val, Register data);
   713 public:
   714     void moveValue(const Value &val, Register type, Register data);
   716     CodeOffsetJump jumpWithPatch(RepatchLabel *label);
   718     template <typename T>
   719     CodeOffsetJump branchPtrWithPatch(Condition cond, Register reg, T ptr, RepatchLabel *label) {
   720         movePtr(ptr, ScratchRegister);
   721         Label skipJump;
   722         ma_b(reg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
   723         CodeOffsetJump off = jumpWithPatch(label);
   724         bind(&skipJump);
   725         return off;
   726     }
   728     template <typename T>
   729     CodeOffsetJump branchPtrWithPatch(Condition cond, Address addr, T ptr, RepatchLabel *label) {
   730         loadPtr(addr, SecondScratchReg);
   731         movePtr(ptr, ScratchRegister);
   732         Label skipJump;
   733         ma_b(SecondScratchReg, ScratchRegister, &skipJump, InvertCondition(cond), ShortJump);
   734         CodeOffsetJump off = jumpWithPatch(label);
   735         bind(&skipJump);
   736         return off;
   737     }
   738     void branchPtr(Condition cond, Address addr, ImmGCPtr ptr, Label *label) {
   739         ma_lw(SecondScratchReg, addr);
   740         ma_li(ScratchRegister, ptr);
   741         ma_b(SecondScratchReg, ScratchRegister, label, cond);
   742     }
   743     void branchPtr(Condition cond, Address addr, ImmWord ptr, Label *label) {
   744         ma_lw(SecondScratchReg, addr);
   745         ma_b(SecondScratchReg, Imm32(ptr.value), label, cond);
   746     }
   747     void branchPtr(Condition cond, Address addr, ImmPtr ptr, Label *label) {
   748         branchPtr(cond, addr, ImmWord(uintptr_t(ptr.value)), label);
   749     }
   750     void branchPtr(Condition cond, const AbsoluteAddress &addr, const Register &ptr, Label *label) {
   751         loadPtr(addr, ScratchRegister);
   752         ma_b(ScratchRegister, ptr, label, cond);
   753     }
   754     void branchPtr(Condition cond, const AsmJSAbsoluteAddress &addr, const Register &ptr,
   755                    Label *label) {
   756         loadPtr(addr, ScratchRegister);
   757         ma_b(ScratchRegister, ptr, label, cond);
   758     }
   759     void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) {
   760         loadPtr(lhs, SecondScratchReg); // ma_b might use scratch
   761         ma_b(SecondScratchReg, rhs, label, cond);
   762     }
   763     void branch32(Condition cond, const AbsoluteAddress &lhs, const Register &rhs, Label *label) {
   764         loadPtr(lhs, ScratchRegister);
   765         ma_b(ScratchRegister, rhs, label, cond);
   766     }
   768     void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) {
   769         if (dest.isFloat())
   770             loadInt32OrDouble(address, dest.fpu());
   771         else
   772             ma_lw(dest.gpr(), address);
   773     }
   775     void loadUnboxedValue(BaseIndex address, MIRType type, AnyRegister dest) {
   776         if (dest.isFloat())
   777             loadInt32OrDouble(address.base, address.index, dest.fpu(), address.scale);
   778         else
   779             load32(address, dest.gpr());
   780     }
   782     void moveValue(const Value &val, const ValueOperand &dest);
   784     void moveValue(const ValueOperand &src, const ValueOperand &dest) {
   785         MOZ_ASSERT(src.typeReg() != dest.payloadReg());
   786         MOZ_ASSERT(src.payloadReg() != dest.typeReg());
   787         if (src.typeReg() != dest.typeReg())
   788             ma_move(dest.typeReg(), src.typeReg());
   789         if (src.payloadReg() != dest.payloadReg())
   790             ma_move(dest.payloadReg(), src.payloadReg());
   791     }
   793     void storeValue(ValueOperand val, Operand dst);
   794     void storeValue(ValueOperand val, const BaseIndex &dest);
   795     void storeValue(JSValueType type, Register reg, BaseIndex dest);
   796     void storeValue(ValueOperand val, const Address &dest);
   797     void storeValue(JSValueType type, Register reg, Address dest);
   798     void storeValue(const Value &val, Address dest);
   799     void storeValue(const Value &val, BaseIndex dest);
   801     void loadValue(Address src, ValueOperand val);
   802     void loadValue(Operand dest, ValueOperand val) {
   803         loadValue(dest.toAddress(), val);
   804     }
   805     void loadValue(const BaseIndex &addr, ValueOperand val);
   806     void tagValue(JSValueType type, Register payload, ValueOperand dest);
   808     void pushValue(ValueOperand val);
   809     void popValue(ValueOperand val);
   810     void pushValue(const Value &val) {
   811         jsval_layout jv = JSVAL_TO_IMPL(val);
   812         push(Imm32(jv.s.tag));
   813         if (val.isMarkable())
   814             push(ImmGCPtr(reinterpret_cast<gc::Cell *>(val.toGCThing())));
   815         else
   816             push(Imm32(jv.s.payload.i32));
   817     }
   818     void pushValue(JSValueType type, Register reg) {
   819         push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
   820         ma_push(reg);
   821     }
   822     void pushValue(const Address &addr);
   823     void Push(const ValueOperand &val) {
   824         pushValue(val);
   825         framePushed_ += sizeof(Value);
   826     }
   827     void Pop(const ValueOperand &val) {
   828         popValue(val);
   829         framePushed_ -= sizeof(Value);
   830     }
   831     void storePayload(const Value &val, Address dest);
   832     void storePayload(Register src, Address dest);
   833     void storePayload(const Value &val, Register base, Register index, int32_t shift = defaultShift);
   834     void storePayload(Register src, Register base, Register index, int32_t shift = defaultShift);
   835     void storeTypeTag(ImmTag tag, Address dest);
   836     void storeTypeTag(ImmTag tag, Register base, Register index, int32_t shift = defaultShift);
   838     void makeFrameDescriptor(Register frameSizeReg, FrameType type) {
   839         ma_sll(frameSizeReg, frameSizeReg, Imm32(FRAMESIZE_SHIFT));
   840         ma_or(frameSizeReg, frameSizeReg, Imm32(type));
   841     }
   843     void linkExitFrame();
   844     void linkParallelExitFrame(const Register &pt);
   845     void handleFailureWithHandler(void *handler);
   846     void handleFailureWithHandlerTail();
   848     /////////////////////////////////////////////////////////////////
   849     // Common interface.
   850     /////////////////////////////////////////////////////////////////
   851   public:
   852     // The following functions are exposed for use in platform-shared code.
   853     void Push(const Register &reg) {
   854         ma_push(reg);
   855         adjustFrame(sizeof(intptr_t));
   856     }
   857     void Push(const Imm32 imm) {
   858         ma_li(ScratchRegister, imm);
   859         ma_push(ScratchRegister);
   860         adjustFrame(sizeof(intptr_t));
   861     }
   862     void Push(const ImmWord imm) {
   863         ma_li(ScratchRegister, Imm32(imm.value));
   864         ma_push(ScratchRegister);
   865         adjustFrame(sizeof(intptr_t));
   866     }
   867     void Push(const ImmPtr imm) {
   868         Push(ImmWord(uintptr_t(imm.value)));
   869     }
   870     void Push(const ImmGCPtr ptr) {
   871         ma_li(ScratchRegister, ptr);
   872         ma_push(ScratchRegister);
   873         adjustFrame(sizeof(intptr_t));
   874     }
   875     void Push(const FloatRegister &f) {
   876         ma_push(f);
   877         adjustFrame(sizeof(double));
   878     }
   880     CodeOffsetLabel PushWithPatch(const ImmWord &word) {
   881         framePushed_ += sizeof(word.value);
   882         return pushWithPatch(word);
   883     }
   884     CodeOffsetLabel PushWithPatch(const ImmPtr &imm) {
   885         return PushWithPatch(ImmWord(uintptr_t(imm.value)));
   886     }
   888     void Pop(const Register &reg) {
   889         ma_pop(reg);
   890         adjustFrame(-sizeof(intptr_t));
   891     }
   892     void implicitPop(uint32_t args) {
   893         MOZ_ASSERT(args % sizeof(intptr_t) == 0);
   894         adjustFrame(-args);
   895     }
   896     uint32_t framePushed() const {
   897         return framePushed_;
   898     }
   899     void setFramePushed(uint32_t framePushed) {
   900         framePushed_ = framePushed;
   901     }
   903     // Builds an exit frame on the stack, with a return address to an internal
   904     // non-function. Returns offset to be passed to markSafepointAt().
   905     bool buildFakeExitFrame(const Register &scratch, uint32_t *offset);
   907     void callWithExitFrame(JitCode *target);
   908     void callWithExitFrame(JitCode *target, Register dynStack);
   910     // Makes an Ion call using the only two methods that it is sane for
   911     // indep code to make a call
   912     void callIon(const Register &callee);
   914     void reserveStack(uint32_t amount);
   915     void freeStack(uint32_t amount);
   916     void freeStack(Register amount);
   918     void add32(Register src, Register dest);
   919     void add32(Imm32 imm, Register dest);
   920     void add32(Imm32 imm, const Address &dest);
   921     void sub32(Imm32 imm, Register dest);
   922     void sub32(Register src, Register dest);
   924     void and32(Imm32 imm, Register dest);
   925     void and32(Imm32 imm, const Address &dest);
   926     void or32(Imm32 imm, const Address &dest);
   927     void xor32(Imm32 imm, Register dest);
   928     void xorPtr(Imm32 imm, Register dest);
   929     void xorPtr(Register src, Register dest);
   930     void orPtr(Imm32 imm, Register dest);
   931     void orPtr(Register src, Register dest);
   932     void andPtr(Imm32 imm, Register dest);
   933     void andPtr(Register src, Register dest);
   934     void addPtr(Register src, Register dest);
   935     void subPtr(Register src, Register dest);
   936     void addPtr(const Address &src, Register dest);
   937     void not32(Register reg);
   939     void move32(const Imm32 &imm, const Register &dest);
   940     void move32(const Register &src, const Register &dest);
   942     void movePtr(const Register &src, const Register &dest);
   943     void movePtr(const ImmWord &imm, const Register &dest);
   944     void movePtr(const ImmPtr &imm, const Register &dest);
   945     void movePtr(const AsmJSImmPtr &imm, const Register &dest);
   946     void movePtr(const ImmGCPtr &imm, const Register &dest);
   948     void load8SignExtend(const Address &address, const Register &dest);
   949     void load8SignExtend(const BaseIndex &src, const Register &dest);
   951     void load8ZeroExtend(const Address &address, const Register &dest);
   952     void load8ZeroExtend(const BaseIndex &src, const Register &dest);
   954     void load16SignExtend(const Address &address, const Register &dest);
   955     void load16SignExtend(const BaseIndex &src, const Register &dest);
   957     void load16ZeroExtend(const Address &address, const Register &dest);
   958     void load16ZeroExtend(const BaseIndex &src, const Register &dest);
   960     void load32(const Address &address, const Register &dest);
   961     void load32(const BaseIndex &address, const Register &dest);
   962     void load32(const AbsoluteAddress &address, const Register &dest);
   964     void loadPtr(const Address &address, const Register &dest);
   965     void loadPtr(const BaseIndex &src, const Register &dest);
   966     void loadPtr(const AbsoluteAddress &address, const Register &dest);
   967     void loadPtr(const AsmJSAbsoluteAddress &address, const Register &dest);
   969     void loadPrivate(const Address &address, const Register &dest);
   971     void loadDouble(const Address &addr, const FloatRegister &dest);
   972     void loadDouble(const BaseIndex &src, const FloatRegister &dest);
   974     // Load a float value into a register, then expand it to a double.
   975     void loadFloatAsDouble(const Address &addr, const FloatRegister &dest);
   976     void loadFloatAsDouble(const BaseIndex &src, const FloatRegister &dest);
   978     void loadFloat32(const Address &addr, const FloatRegister &dest);
   979     void loadFloat32(const BaseIndex &src, const FloatRegister &dest);
   981     void store8(const Register &src, const Address &address);
   982     void store8(const Imm32 &imm, const Address &address);
   983     void store8(const Register &src, const BaseIndex &address);
   984     void store8(const Imm32 &imm, const BaseIndex &address);
   986     void store16(const Register &src, const Address &address);
   987     void store16(const Imm32 &imm, const Address &address);
   988     void store16(const Register &src, const BaseIndex &address);
   989     void store16(const Imm32 &imm, const BaseIndex &address);
   991     void store32(const Register &src, const AbsoluteAddress &address);
   992     void store32(const Register &src, const Address &address);
   993     void store32(const Register &src, const BaseIndex &address);
   994     void store32(const Imm32 &src, const Address &address);
   995     void store32(const Imm32 &src, const BaseIndex &address);
   997     void storePtr(ImmWord imm, const Address &address);
   998     void storePtr(ImmPtr imm, const Address &address);
   999     void storePtr(ImmGCPtr imm, const Address &address);
  1000     void storePtr(Register src, const Address &address);
  1001     void storePtr(const Register &src, const AbsoluteAddress &dest);
  1002     void storeDouble(FloatRegister src, Address addr) {
  1003         ma_sd(src, addr);
  1005     void storeDouble(FloatRegister src, BaseIndex addr) {
  1006         MOZ_ASSERT(addr.offset == 0);
  1007         ma_sd(src, addr);
  1009     void moveDouble(FloatRegister src, FloatRegister dest) {
  1010         as_movd(dest, src);
  1013     void storeFloat32(FloatRegister src, Address addr) {
  1014         ma_ss(src, addr);
  1016     void storeFloat32(FloatRegister src, BaseIndex addr) {
  1017         MOZ_ASSERT(addr.offset == 0);
  1018         ma_ss(src, addr);
  1021     void zeroDouble(FloatRegister reg) {
  1022         moveToDoubleLo(zero, reg);
  1023         moveToDoubleHi(zero, reg);
  1026     void clampIntToUint8(Register reg) {
  1027         // look at (reg >> 8) if it is 0, then src shouldn't be clamped
  1028         // if it is <0, then we want to clamp to 0,
  1029         // otherwise, we wish to clamp to 255
  1030         Label done;
  1031         ma_move(ScratchRegister, reg);
  1032         as_sra(ScratchRegister, ScratchRegister, 8);
  1033         ma_b(ScratchRegister, ScratchRegister, &done, Assembler::Zero, ShortJump);
  1035             Label negative;
  1036             ma_b(ScratchRegister, ScratchRegister, &negative, Assembler::Signed, ShortJump);
  1038                 ma_li(reg, Imm32(255));
  1039                 ma_b(&done, ShortJump);
  1041             bind(&negative);
  1043                 ma_move(reg, zero);
  1046         bind(&done);
  1049     void subPtr(Imm32 imm, const Register dest);
  1050     void addPtr(Imm32 imm, const Register dest);
  1051     void addPtr(Imm32 imm, const Address &dest);
  1052     void addPtr(ImmWord imm, const Register dest) {
  1053         addPtr(Imm32(imm.value), dest);
  1055     void addPtr(ImmPtr imm, const Register dest) {
  1056         addPtr(ImmWord(uintptr_t(imm.value)), dest);
  1059     void breakpoint();
  1061     void branchDouble(DoubleCondition cond, const FloatRegister &lhs, const FloatRegister &rhs,
  1062                       Label *label);
  1064     void branchFloat(DoubleCondition cond, const FloatRegister &lhs, const FloatRegister &rhs,
  1065                      Label *label);
  1067     void checkStackAlignment();
  1069     void alignPointerUp(Register src, Register dest, uint32_t alignment);
  1071     void rshiftPtr(Imm32 imm, Register dest) {
  1072         ma_srl(dest, dest, imm);
  1074     void lshiftPtr(Imm32 imm, Register dest) {
  1075         ma_sll(dest, dest, imm);
  1078     // If source is a double, load it into dest. If source is int32,
  1079     // convert it to double. Else, branch to failure.
  1080     void ensureDouble(const ValueOperand &source, FloatRegister dest, Label *failure);
  1082     // Setup a call to C/C++ code, given the number of general arguments it
  1083     // takes. Note that this only supports cdecl.
  1084     //
  1085     // In order for alignment to work correctly, the MacroAssembler must have a
  1086     // consistent view of the stack displacement. It is okay to call "push"
  1087     // manually, however, if the stack alignment were to change, the macro
  1088     // assembler should be notified before starting a call.
  1089     void setupAlignedABICall(uint32_t args);
  1091     // Sets up an ABI call for when the alignment is not known. This may need a
  1092     // scratch register.
  1093     void setupUnalignedABICall(uint32_t args, const Register &scratch);
  1095     // Arguments must be assigned in a left-to-right order. This process may
  1096     // temporarily use more stack, in which case sp-relative addresses will be
  1097     // automatically adjusted. It is extremely important that sp-relative
  1098     // addresses are computed *after* setupABICall(). Furthermore, no
  1099     // operations should be emitted while setting arguments.
  1100     void passABIArg(const MoveOperand &from, MoveOp::Type type);
  1101     void passABIArg(const Register &reg);
  1102     void passABIArg(const FloatRegister &reg, MoveOp::Type type);
  1103     void passABIArg(const ValueOperand &regs);
  1105   protected:
  1106     bool buildOOLFakeExitFrame(void *fakeReturnAddr);
  1108   private:
  1109     void callWithABIPre(uint32_t *stackAdjust);
  1110     void callWithABIPost(uint32_t stackAdjust, MoveOp::Type result);
  1112   public:
  1113     // Emits a call to a C/C++ function, resolving all argument moves.
  1114     void callWithABI(void *fun, MoveOp::Type result = MoveOp::GENERAL);
  1115     void callWithABI(AsmJSImmPtr imm, MoveOp::Type result = MoveOp::GENERAL);
  1116     void callWithABI(const Address &fun, MoveOp::Type result = MoveOp::GENERAL);
  1118     CodeOffsetLabel labelForPatch() {
  1119         return CodeOffsetLabel(nextOffset().getOffset());
  1122     void memIntToValue(Address Source, Address Dest) {
  1123         MOZ_ASSUME_UNREACHABLE("NYI");
  1126     void lea(Operand addr, Register dest) {
  1127         MOZ_ASSUME_UNREACHABLE("NYI");
  1130     void abiret() {
  1131         MOZ_ASSUME_UNREACHABLE("NYI");
  1134     void ma_storeImm(Imm32 imm, const Address &addr) {
  1135         ma_sw(imm, addr);
  1138     BufferOffset ma_BoundsCheck(Register bounded) {
  1139         BufferOffset bo = m_buffer.nextOffset();
  1140         ma_liPatchable(bounded, Imm32(0));
  1141         return bo;
  1144     void moveFloat32(FloatRegister src, FloatRegister dest) {
  1145         as_movs(dest, src);
  1148     void branchPtrInNurseryRange(Register ptr, Register temp, Label *label);
  1149 };
  1151 typedef MacroAssemblerMIPSCompat MacroAssemblerSpecific;
  1153 } // namespace jit
  1154 } // namespace js
  1156 #endif /* jit_mips_MacroAssembler_mips_h */

mercurial