tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MacroAssembler-mips-shared.h (10268B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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/. */
      6 
      7 #ifndef jit_mips_shared_MacroAssembler_mips_shared_h
      8 #define jit_mips_shared_MacroAssembler_mips_shared_h
      9 
     10 #include "jit/AtomicOp.h"
     11 #include "jit/mips64/Assembler-mips64.h"
     12 
     13 namespace js {
     14 namespace jit {
     15 
     16 enum LoadStoreSize {
     17  SizeByte = 8,
     18  SizeHalfWord = 16,
     19  SizeWord = 32,
     20  SizeDouble = 64
     21 };
     22 
     23 enum LoadStoreExtension { ZeroExtend = 0, SignExtend = 1 };
     24 
     25 enum JumpKind { LongJump = 0, ShortJump = 1 };
     26 
     27 enum DelaySlotFill { DontFillDelaySlot = 0, FillDelaySlot = 1 };
     28 
     29 static constexpr Register CallReg = t9;
     30 
     31 class MacroAssemblerMIPSShared : public Assembler {
     32 protected:
     33  // Perform a downcast. Should be removed by Bug 996602.
     34  MacroAssembler& asMasm();
     35  const MacroAssembler& asMasm() const;
     36 
     37  Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
     38  Condition ma_cmp(Register rd, Register lhs, Imm32 imm, Condition c);
     39 
     40  void compareFloatingPoint(FloatFormat fmt, FloatRegister lhs,
     41                            FloatRegister rhs, DoubleCondition c,
     42                            FloatTestKind* testKind, FPConditionBit fcc = FCC0);
     43 
     44 public:
     45  void ma_move(Register rd, Register rs);
     46 
     47  void ma_li(Register dest, ImmGCPtr ptr);
     48 
     49  void ma_li(Register dest, Imm32 imm);
     50  void ma_liPatchable(Register dest, Imm32 imm);
     51 
     52  // Shift operations
     53  void ma_sll(Register rd, Register rt, Imm32 shift);
     54  void ma_srl(Register rd, Register rt, Imm32 shift);
     55  void ma_sra(Register rd, Register rt, Imm32 shift);
     56  void ma_ror(Register rd, Register rt, Imm32 shift);
     57  void ma_rol(Register rd, Register rt, Imm32 shift);
     58 
     59  void ma_sll(Register rd, Register rt, Register shift);
     60  void ma_srl(Register rd, Register rt, Register shift);
     61  void ma_sra(Register rd, Register rt, Register shift);
     62  void ma_ror(Register rd, Register rt, Register shift);
     63  void ma_rol(Register rd, Register rt, Register shift);
     64 
     65  // Negate
     66  void ma_negu(Register rd, Register rs);
     67 
     68  void ma_not(Register rd, Register rs);
     69 
     70  // Bit extract/insert
     71  void ma_ext(Register rt, Register rs, uint16_t pos, uint16_t size);
     72  void ma_ins(Register rt, Register rs, uint16_t pos, uint16_t size);
     73 
     74  // Sign extend
     75  void ma_seb(Register rd, Register rt);
     76  void ma_seh(Register rd, Register rt);
     77 
     78  // and
     79  void ma_and(Register rd, Register rs);
     80  void ma_and(Register rd, Imm32 imm);
     81  void ma_and(Register rd, Register rs, Imm32 imm);
     82 
     83  // or
     84  void ma_or(Register rd, Register rs);
     85  void ma_or(Register rd, Imm32 imm);
     86  void ma_or(Register rd, Register rs, Imm32 imm);
     87 
     88  // xor
     89  void ma_xor(Register rd, Register rs);
     90  void ma_xor(Register rd, Imm32 imm);
     91  void ma_xor(Register rd, Register rs, Imm32 imm);
     92 
     93  // word swap byte within halfwords
     94  void ma_wsbh(Register rd, Register rt);
     95 
     96  void ma_ctz(Register rd, Register rs);
     97 
     98  // load
     99  FaultingCodeOffset ma_load(Register dest, const BaseIndex& src,
    100                             LoadStoreSize size = SizeWord,
    101                             LoadStoreExtension extension = SignExtend);
    102  void ma_load_unaligned(Register dest, const BaseIndex& src,
    103                         LoadStoreSize size = SizeWord,
    104                         LoadStoreExtension extension = SignExtend);
    105  void ma_load_unaligned(Register dest, const Address& address,
    106                         LoadStoreSize size = SizeWord,
    107                         LoadStoreExtension extension = SignExtend);
    108  void ma_load_unaligned(const wasm::MemoryAccessDesc& access, Register dest,
    109                         const BaseIndex& src, Register temp,
    110                         LoadStoreSize size, LoadStoreExtension extension);
    111 
    112  // store
    113  FaultingCodeOffset ma_store(Register data, const BaseIndex& dest,
    114                              LoadStoreSize size = SizeWord,
    115                              LoadStoreExtension extension = SignExtend);
    116  void ma_store(Imm32 imm, const BaseIndex& dest, LoadStoreSize size = SizeWord,
    117                LoadStoreExtension extension = SignExtend);
    118  void ma_store_unaligned(Register data, const Address& dest,
    119                          LoadStoreSize size = SizeWord);
    120  void ma_store_unaligned(Register data, const BaseIndex& dest,
    121                          LoadStoreSize size = SizeWord);
    122  void ma_store_unaligned(const wasm::MemoryAccessDesc& access, Register data,
    123                          const BaseIndex& dest, Register temp,
    124                          LoadStoreSize size, LoadStoreExtension extension);
    125 
    126  // arithmetic based ops
    127  // add
    128  void ma_addu(Register rd, Register rs, Imm32 imm);
    129  void ma_addu(Register rd, Register rs);
    130  void ma_addu(Register rd, Imm32 imm);
    131  void ma_add32TestCarry(Condition cond, Register rd, Register rs, Register rt,
    132                         Label* overflow);
    133  void ma_add32TestCarry(Condition cond, Register rd, Register rs, Imm32 imm,
    134                         Label* overflow);
    135 
    136  // subtract
    137  void ma_subu(Register rd, Register rs, Imm32 imm);
    138  void ma_subu(Register rd, Register rs);
    139  void ma_subu(Register rd, Imm32 imm);
    140  void ma_sub32TestOverflow(Register rd, Register rs, Imm32 imm,
    141                            Label* overflow);
    142 
    143  // multiplies.  For now, there are only few that we care about.
    144  void ma_mul(Register rd, Register rs, Imm32 imm);
    145  void ma_mul32TestOverflow(Register rd, Register rs, Register rt,
    146                            Label* overflow);
    147  void ma_mul32TestOverflow(Register rd, Register rs, Imm32 imm,
    148                            Label* overflow);
    149 
    150  // fast mod, uses scratch registers, and thus needs to be in the assembler
    151  // implicitly assumes that we can overwrite dest at the beginning of the
    152  // sequence
    153  void ma_mod_mask(Register src, Register dest, Register hold, Register remain,
    154                   int32_t shift, Label* negZero = nullptr);
    155 
    156  // branches when done from within mips-specific code
    157  void ma_b(Register lhs, Register rhs, Label* l, Condition c,
    158            JumpKind jumpKind = LongJump);
    159  void ma_b(Register lhs, Imm32 imm, Label* l, Condition c,
    160            JumpKind jumpKind = LongJump);
    161  void ma_b(Register lhs, ImmPtr imm, Label* l, Condition c,
    162            JumpKind jumpKind = LongJump);
    163  void ma_b(Register lhs, ImmGCPtr imm, Label* l, Condition c,
    164            JumpKind jumpKind = LongJump) {
    165    UseScratchRegisterScope temps(*this);
    166    Register scratch = temps.Acquire();
    167    MOZ_ASSERT(lhs != scratch);
    168    ma_li(scratch, imm);
    169    ma_b(lhs, scratch, l, c, jumpKind);
    170  }
    171 
    172  void ma_b(Label* l, JumpKind jumpKind = LongJump);
    173 
    174  // fp instructions
    175  void ma_lis(FloatRegister dest, float value);
    176 
    177  FaultingCodeOffset ma_sd(FloatRegister src, BaseIndex address);
    178  FaultingCodeOffset ma_ss(FloatRegister src, BaseIndex address);
    179 
    180  FaultingCodeOffset ma_ld(FloatRegister dest, const BaseIndex& src);
    181  FaultingCodeOffset ma_ls(FloatRegister dest, const BaseIndex& src);
    182 
    183  // FP branches
    184  void ma_bc1s(FloatRegister lhs, FloatRegister rhs, Label* label,
    185               DoubleCondition c, JumpKind jumpKind = LongJump,
    186               FPConditionBit fcc = FCC0);
    187  void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label,
    188               DoubleCondition c, JumpKind jumpKind = LongJump,
    189               FPConditionBit fcc = FCC0);
    190 
    191  void ma_call(ImmPtr dest);
    192 
    193  void ma_jump(ImmPtr dest);
    194 
    195  void ma_cmp_set(Register dst, Register lhs, Register rhs, Condition c);
    196  void ma_cmp_set(Register dst, Register lhs, Imm32 imm, Condition c);
    197  // void ma_cmp_set(Register dst, Address address, Imm32 imm, Condition c);
    198  void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs,
    199                         DoubleCondition c);
    200  void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs,
    201                          DoubleCondition c);
    202 
    203  void moveToFloat32(Register src, FloatRegister dest) { as_mtc1(src, dest); }
    204  void moveFromFloat32(FloatRegister src, Register dest) { as_mfc1(dest, src); }
    205 
    206  void minMax32(Register lhs, Register rhs, Register dest, bool isMax);
    207  void minMax32(Register lhs, Imm32 rhs, Register dest, bool isMax);
    208 
    209  void minMaxPtr(Register lhs, Register rhs, Register dest, bool isMax);
    210  void minMaxPtr(Register lhs, ImmWord rhs, Register dest, bool isMax);
    211 
    212  // Evaluate srcDest = minmax<isMax>{Float32,Double}(srcDest, other).
    213  // Handle NaN specially if handleNaN is true.
    214  void minMaxDouble(FloatRegister srcDest, FloatRegister other, bool handleNaN,
    215                    bool isMax);
    216  void minMaxFloat32(FloatRegister srcDest, FloatRegister other, bool handleNaN,
    217                     bool isMax);
    218 
    219  FaultingCodeOffset loadDouble(const Address& addr, FloatRegister dest);
    220  FaultingCodeOffset loadDouble(const BaseIndex& src, FloatRegister dest);
    221 
    222  FaultingCodeOffset loadFloat32(const Address& addr, FloatRegister dest);
    223  FaultingCodeOffset loadFloat32(const BaseIndex& src, FloatRegister dest);
    224 
    225  FaultingCodeOffset loadFloat16(const Address& addr, FloatRegister dest,
    226                                 Register) {
    227    MOZ_CRASH("Not supported for this target");
    228  }
    229  FaultingCodeOffset loadFloat16(const BaseIndex& src, FloatRegister dest,
    230                                 Register) {
    231    MOZ_CRASH("Not supported for this target");
    232  }
    233 
    234  void outOfLineWasmTruncateToInt32Check(
    235      FloatRegister input, Register output, MIRType fromType, TruncFlags flags,
    236      Label* rejoin, const wasm::TrapSiteDesc& trapSiteDesc);
    237  void outOfLineWasmTruncateToInt64Check(
    238      FloatRegister input, Register64 output, MIRType fromType,
    239      TruncFlags flags, Label* rejoin, const wasm::TrapSiteDesc& trapSiteDesc);
    240 
    241 protected:
    242  void wasmLoadImpl(const wasm::MemoryAccessDesc& access, Register memoryBase,
    243                    Register ptr, Register ptrScratch, AnyRegister output,
    244                    Register tmp);
    245  void wasmStoreImpl(const wasm::MemoryAccessDesc& access, AnyRegister value,
    246                     Register memoryBase, Register ptr, Register ptrScratch,
    247                     Register tmp);
    248 };
    249 
    250 }  // namespace jit
    251 }  // namespace js
    252 
    253 #endif /* jit_mips_shared_MacroAssembler_mips_shared_h */