summaryrefslogtreecommitdiffstats
path: root/js/src/jit/mips-shared/MacroAssembler-mips-shared.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/mips-shared/MacroAssembler-mips-shared.h')
-rw-r--r--js/src/jit/mips-shared/MacroAssembler-mips-shared.h262
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 */