diff options
Diffstat (limited to 'js/src/jit/mips-shared/MacroAssembler-mips-shared.h')
-rw-r--r-- | js/src/jit/mips-shared/MacroAssembler-mips-shared.h | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h new file mode 100644 index 000000000..c9bd4a4d9 --- /dev/null +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h @@ -0,0 +1,262 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_mips_shared_MacroAssembler_mips_shared_h +#define jit_mips_shared_MacroAssembler_mips_shared_h + +#if defined(JS_CODEGEN_MIPS32) +# include "jit/mips32/Assembler-mips32.h" +#elif defined(JS_CODEGEN_MIPS64) +# include "jit/mips64/Assembler-mips64.h" +#endif + +#include "jit/AtomicOp.h" + +namespace js { +namespace jit { + +enum LoadStoreSize +{ + SizeByte = 8, + SizeHalfWord = 16, + SizeWord = 32, + SizeDouble = 64 +}; + +enum LoadStoreExtension +{ + ZeroExtend = 0, + SignExtend = 1 +}; + +enum JumpKind +{ + LongJump = 0, + ShortJump = 1 +}; + +enum DelaySlotFill +{ + DontFillDelaySlot = 0, + FillDelaySlot = 1 +}; + +static Register CallReg = t9; + +class MacroAssemblerMIPSShared : public Assembler +{ + protected: + // Perform a downcast. Should be removed by Bug 996602. + MacroAssembler& asMasm(); + const MacroAssembler& asMasm() const; + + Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c); + + void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs, + DoubleCondition c, FloatTestKind* testKind, + FPConditionBit fcc = FCC0); + + public: + void ma_move(Register rd, Register rs); + + void ma_li(Register dest, ImmGCPtr ptr); + + void ma_li(Register dest, Imm32 imm); + + // Shift operations + void ma_sll(Register rd, Register rt, Imm32 shift); + void ma_srl(Register rd, Register rt, Imm32 shift); + void ma_sra(Register rd, Register rt, Imm32 shift); + void ma_ror(Register rd, Register rt, Imm32 shift); + void ma_rol(Register rd, Register rt, Imm32 shift); + + void ma_sll(Register rd, Register rt, Register shift); + void ma_srl(Register rd, Register rt, Register shift); + void ma_sra(Register rd, Register rt, Register shift); + void ma_ror(Register rd, Register rt, Register shift); + void ma_rol(Register rd, Register rt, Register shift); + + // Negate + void ma_negu(Register rd, Register rs); + + void ma_not(Register rd, Register rs); + + // and + void ma_and(Register rd, Register rs); + void ma_and(Register rd, Imm32 imm); + void ma_and(Register rd, Register rs, Imm32 imm); + + // or + void ma_or(Register rd, Register rs); + void ma_or(Register rd, Imm32 imm); + void ma_or(Register rd, Register rs, Imm32 imm); + + // xor + void ma_xor(Register rd, Register rs); + void ma_xor(Register rd, Imm32 imm); + void ma_xor(Register rd, Register rs, Imm32 imm); + + void ma_ctz(Register rd, Register rs); + + // load + void ma_load(Register dest, const BaseIndex& src, LoadStoreSize size = SizeWord, + LoadStoreExtension extension = SignExtend); + void ma_load_unaligned(Register dest, const BaseIndex& src, Register temp, + LoadStoreSize size, LoadStoreExtension extension); + + // store + void ma_store(Register data, const BaseIndex& dest, LoadStoreSize size = SizeWord, + LoadStoreExtension extension = SignExtend); + void ma_store(Imm32 imm, const BaseIndex& dest, LoadStoreSize size = SizeWord, + LoadStoreExtension extension = SignExtend); + void ma_store_unaligned(Register data, const BaseIndex& dest, Register temp, + LoadStoreSize size, LoadStoreExtension extension); + + // arithmetic based ops + // add + void ma_addu(Register rd, Register rs, Imm32 imm); + void ma_addu(Register rd, Register rs); + void ma_addu(Register rd, Imm32 imm); + template <typename L> + void ma_addTestCarry(Register rd, Register rs, Register rt, L overflow); + template <typename L> + void ma_addTestCarry(Register rd, Register rs, Imm32 imm, L overflow); + + // subtract + void ma_subu(Register rd, Register rs, Imm32 imm); + void ma_subu(Register rd, Register rs); + void ma_subu(Register rd, Imm32 imm); + void ma_subTestOverflow(Register rd, Register rs, Imm32 imm, Label* overflow); + + // multiplies. For now, there are only few that we care about. + void ma_mul(Register rd, Register rs, Imm32 imm); + void ma_mul_branch_overflow(Register rd, Register rs, Register rt, Label* overflow); + void ma_mul_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow); + + // divisions + void ma_div_branch_overflow(Register rd, Register rs, Register rt, Label* overflow); + void ma_div_branch_overflow(Register rd, Register rs, Imm32 imm, Label* overflow); + + // fast mod, uses scratch registers, and thus needs to be in the assembler + // implicitly assumes that we can overwrite dest at the beginning of the sequence + void ma_mod_mask(Register src, Register dest, Register hold, Register remain, + int32_t shift, Label* negZero = nullptr); + + // branches when done from within mips-specific code + void ma_b(Register lhs, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump); + void ma_b(Register lhs, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = LongJump); + void ma_b(Register lhs, ImmPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump); + void ma_b(Register lhs, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump) { + MOZ_ASSERT(lhs != ScratchRegister); + ma_li(ScratchRegister, imm); + ma_b(lhs, ScratchRegister, l, c, jumpKind); + } + template <typename T> + void ma_b(Register lhs, T rhs, wasm::TrapDesc target, Condition c, + JumpKind jumpKind = LongJump); + + void ma_b(Label* l, JumpKind jumpKind = LongJump); + void ma_b(wasm::TrapDesc target, JumpKind jumpKind = LongJump); + + // fp instructions + void ma_lis(FloatRegister dest, float value); + void ma_lis(FloatRegister dest, wasm::RawF32 value); + void ma_liNegZero(FloatRegister dest); + + void ma_sd(FloatRegister fd, BaseIndex address); + void ma_ss(FloatRegister fd, BaseIndex address); + + //FP branches + void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c, + JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0); + void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label, DoubleCondition c, + JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0); + + void ma_call(ImmPtr dest); + + void ma_jump(ImmPtr dest); + + void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c); + void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c); + void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c); + void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c); + + void moveToDoubleLo(Register src, FloatRegister dest) { + as_mtc1(src, dest); + } + void moveFromDoubleLo(FloatRegister src, Register dest) { + as_mfc1(dest, src); + } + + void moveToFloat32(Register src, FloatRegister dest) { + as_mtc1(src, dest); + } + void moveFromFloat32(FloatRegister src, Register dest) { + as_mfc1(dest, src); + } + + // Evaluate srcDest = minmax<isMax>{Float32,Double}(srcDest, other). + // Handle NaN specially if handleNaN is true. + void minMaxDouble(FloatRegister srcDest, FloatRegister other, bool handleNaN, bool isMax); + void minMaxFloat32(FloatRegister srcDest, FloatRegister other, bool handleNaN, bool isMax); + + private: + void atomicEffectOpMIPSr2(int nbytes, AtomicOp op, const Register& value, const Register& addr, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp); + void atomicFetchOpMIPSr2(int nbytes, bool signExtend, AtomicOp op, const Register& value, const Register& addr, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp, + Register output); + void compareExchangeMIPSr2(int nbytes, bool signExtend, const Register& addr, Register oldval, + Register newval, Register flagTemp, Register valueTemp, Register offsetTemp, + Register maskTemp, Register output); + + protected: + void atomicEffectOp(int nbytes, AtomicOp op, const Imm32& value, const Address& address, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp); + void atomicEffectOp(int nbytes, AtomicOp op, const Imm32& value, const BaseIndex& address, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp); + void atomicEffectOp(int nbytes, AtomicOp op, const Register& value, const Address& address, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp); + void atomicEffectOp(int nbytes, AtomicOp op, const Register& value, const BaseIndex& address, + Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp); + + void atomicFetchOp(int nbytes, bool signExtend, AtomicOp op, const Imm32& value, + const Address& address, Register flagTemp, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output); + void atomicFetchOp(int nbytes, bool signExtend, AtomicOp op, const Imm32& value, + const BaseIndex& address, Register flagTemp, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output); + void atomicFetchOp(int nbytes, bool signExtend, AtomicOp op, const Register& value, + const Address& address, Register flagTemp, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output); + void atomicFetchOp(int nbytes, bool signExtend, AtomicOp op, const Register& value, + const BaseIndex& address, Register flagTemp, Register valueTemp, + Register offsetTemp, Register maskTemp, Register output); + + void compareExchange(int nbytes, bool signExtend, const Address& address, Register oldval, + Register newval, Register valueTemp, Register offsetTemp, Register maskTemp, + Register output); + void compareExchange(int nbytes, bool signExtend, const BaseIndex& address, Register oldval, + Register newval, Register valueTemp, Register offsetTemp, Register maskTemp, + Register output); + + void atomicExchange(int nbytes, bool signExtend, const Address& address, Register value, + Register valueTemp, Register offsetTemp, Register maskTemp, + Register output); + void atomicExchange(int nbytes, bool signExtend, const BaseIndex& address, Register value, + Register valueTemp, Register offsetTemp, Register maskTemp, + Register output); + + public: + struct AutoPrepareForPatching { + explicit AutoPrepareForPatching(MacroAssemblerMIPSShared&) {} + }; +}; + +} // namespace jit +} // namespace js + +#endif /* jit_mips_shared_MacroAssembler_mips_shared_h */ |