tor-browser

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

base-riscv-i.h (10258B)


      1 // Copyright 2022 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 #ifndef jit_riscv64_extension_Base_riscv_i_h_
      5 #define jit_riscv64_extension_Base_riscv_i_h_
      6 #include "mozilla/Assertions.h"
      7 
      8 #include <stdint.h>
      9 
     10 #include "jit/riscv64/constant/Constant-riscv64.h"
     11 #include "jit/riscv64/extension/base-assembler-riscv.h"
     12 namespace js {
     13 namespace jit {
     14 
     15 class AssemblerRISCVI : public AssemblerRiscvBase {
     16 public:
     17  void lui(Register rd, int32_t imm20);
     18  void auipc(Register rd, int32_t imm20);
     19 
     20  // Jumps
     21  CodeOffset jal(Register rd, int32_t imm20);
     22  BufferOffset jalr(Register rd, Register rs1, int16_t imm12);
     23 
     24  // Branches
     25  void beq(Register rs1, Register rs2, int16_t imm12);
     26  void bne(Register rs1, Register rs2, int16_t imm12);
     27  void blt(Register rs1, Register rs2, int16_t imm12);
     28  void bge(Register rs1, Register rs2, int16_t imm12);
     29  void bltu(Register rs1, Register rs2, int16_t imm12);
     30  void bgeu(Register rs1, Register rs2, int16_t imm12);
     31  // Loads
     32  void lb(Register rd, Register rs1, int16_t imm12);
     33  void lh(Register rd, Register rs1, int16_t imm12);
     34  void lw(Register rd, Register rs1, int16_t imm12);
     35  void lbu(Register rd, Register rs1, int16_t imm12);
     36  void lhu(Register rd, Register rs1, int16_t imm12);
     37 
     38  // Stores
     39  void sb(Register source, Register base, int16_t imm12);
     40  void sh(Register source, Register base, int16_t imm12);
     41  void sw(Register source, Register base, int16_t imm12);
     42 
     43  // Arithmetic with immediate
     44  void addi(Register rd, Register rs1, int16_t imm12);
     45  void slti(Register rd, Register rs1, int16_t imm12);
     46  void sltiu(Register rd, Register rs1, int16_t imm12);
     47  void xori(Register rd, Register rs1, int16_t imm12);
     48  void ori(Register rd, Register rs1, int16_t imm12);
     49  void andi(Register rd, Register rs1, int16_t imm12);
     50  void slli(Register rd, Register rs1, uint8_t shamt);
     51  void srli(Register rd, Register rs1, uint8_t shamt);
     52  void srai(Register rd, Register rs1, uint8_t shamt);
     53 
     54  // Arithmetic
     55  void add(Register rd, Register rs1, Register rs2);
     56  void sub(Register rd, Register rs1, Register rs2);
     57  void sll(Register rd, Register rs1, Register rs2);
     58  void slt(Register rd, Register rs1, Register rs2);
     59  void sltu(Register rd, Register rs1, Register rs2);
     60  void xor_(Register rd, Register rs1, Register rs2);
     61  void srl(Register rd, Register rs1, Register rs2);
     62  void sra(Register rd, Register rs1, Register rs2);
     63  void or_(Register rd, Register rs1, Register rs2);
     64  void and_(Register rd, Register rs1, Register rs2);
     65 
     66  // Other pseudo instructions that are not part of RISCV pseudo assemly
     67  void nor(Register rd, Register rs, Register rt) {
     68    or_(rd, rs, rt);
     69    not_(rd, rd);
     70  }
     71 
     72  // Memory fences
     73  void fence(uint8_t pred, uint8_t succ);
     74  void fence_tso();
     75 
     76  // Environment call / break
     77  void ecall();
     78  void ebreak();
     79 
     80  void sync() { fence(0b1111, 0b1111); }
     81 
     82  // This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
     83  // instruction (i.e., it should always trap, if your implementation has
     84  // invalid instruction traps).
     85  void unimp();
     86 
     87  static int JumpOffset(Instr instr);
     88  static int AuipcOffset(Instr instr);
     89  static int JalrOffset(Instr instr);
     90  static int LoadOffset(Instr instr);
     91  static int BranchOffset(Instr instr);
     92  static int BrachlongOffset(Instr auipc, Instr instr_I);
     93  static inline Instr SetBranchOffset(int32_t pos, int32_t target_pos,
     94                                      Instr instr) {
     95    int32_t imm = target_pos - pos;
     96    MOZ_ASSERT((imm & 1) == 0);
     97    MOZ_ASSERT(is_intn(imm, kBranchOffsetBits));
     98 
     99    instr &= ~kBImm12Mask;
    100    int32_t imm12 = ((imm & 0x800) >> 4) |   // bit  11
    101                    ((imm & 0x1e) << 7) |    // bits 4-1
    102                    ((imm & 0x7e0) << 20) |  // bits 10-5
    103                    ((imm & 0x1000) << 19);  // bit 12
    104 
    105    return instr | (imm12 & kBImm12Mask);
    106  }
    107 
    108  static inline Instr SetJalOffset(int32_t pos, int32_t target_pos,
    109                                   Instr instr) {
    110    MOZ_ASSERT(IsJal(instr));
    111    int32_t imm = target_pos - pos;
    112    MOZ_ASSERT((imm & 1) == 0);
    113    MOZ_ASSERT(is_intn(imm, kJumpOffsetBits));
    114 
    115    instr &= ~kImm20Mask;
    116    int32_t imm20 = (imm & 0xff000) |          // bits 19-12
    117                    ((imm & 0x800) << 9) |     // bit  11
    118                    ((imm & 0x7fe) << 20) |    // bits 10-1
    119                    ((imm & 0x100000) << 11);  // bit  20
    120 
    121    return instr | (imm20 & kImm20Mask);
    122  }
    123 
    124  static inline Instr SetJalrOffset(int32_t offset, Instr instr) {
    125    MOZ_ASSERT(IsJalr(instr));
    126    MOZ_ASSERT(is_int12(offset));
    127    instr &= ~kImm12Mask;
    128    int32_t imm12 = offset << kImm12Shift;
    129    MOZ_ASSERT(IsJalr(instr | (imm12 & kImm12Mask)));
    130    MOZ_ASSERT(JalrOffset(instr | (imm12 & kImm12Mask)) == offset);
    131    return instr | (imm12 & kImm12Mask);
    132  }
    133 
    134  static inline Instr SetLoadOffset(int32_t offset, Instr instr) {
    135 #if JS_CODEGEN_RISCV64
    136    MOZ_ASSERT(IsLd(instr));
    137 #elif JS_CODEGEN_RISCV32
    138    MOZ_ASSERT(IsLw(instr));
    139 #endif
    140    MOZ_ASSERT(is_int12(offset));
    141    instr &= ~kImm12Mask;
    142    int32_t imm12 = offset << kImm12Shift;
    143    return instr | (imm12 & kImm12Mask);
    144  }
    145 
    146  static inline Instr SetAuipcOffset(int32_t offset, Instr instr) {
    147    MOZ_ASSERT(IsAuipc(instr));
    148    MOZ_ASSERT(is_int20(offset));
    149    instr = (instr & ~kImm31_12Mask) | ((offset & kImm19_0Mask) << 12);
    150    return instr;
    151  }
    152 
    153  // Check if an instruction is a branch of some kind.
    154  static bool IsBranch(Instr instr);
    155  static bool IsNop(Instr instr);
    156  static bool IsJump(Instr instr);
    157  static bool IsJal(Instr instr);
    158  static bool IsJalr(Instr instr);
    159  static bool IsLui(Instr instr);
    160  static bool IsAuipc(Instr instr);
    161  static bool IsAddi(Instr instr);
    162  static bool IsOri(Instr instr);
    163  static bool IsSlli(Instr instr);
    164  static bool IsLw(Instr instr);
    165 
    166  inline int32_t branchOffset(Label* L) {
    167    return branchOffsetHelper(L, OffsetSize::kOffset13);
    168  }
    169  inline int32_t jumpOffset(Label* L) {
    170    return branchOffsetHelper(L, OffsetSize::kOffset21);
    171  }
    172 
    173  // Branches
    174  void beq(Register rs1, Register rs2, Label* L) {
    175    beq(rs1, rs2, branchOffset(L));
    176  }
    177  void bne(Register rs1, Register rs2, Label* L) {
    178    bne(rs1, rs2, branchOffset(L));
    179  }
    180  void blt(Register rs1, Register rs2, Label* L) {
    181    blt(rs1, rs2, branchOffset(L));
    182  }
    183  void bge(Register rs1, Register rs2, Label* L) {
    184    bge(rs1, rs2, branchOffset(L));
    185  }
    186  void bltu(Register rs1, Register rs2, Label* L) {
    187    bltu(rs1, rs2, branchOffset(L));
    188  }
    189  void bgeu(Register rs1, Register rs2, Label* L) {
    190    bgeu(rs1, rs2, branchOffset(L));
    191  }
    192 
    193  void beqz(Register rs, int16_t imm13) { beq(rs, zero_reg, imm13); }
    194  void beqz(Register rs1, Label* L) { beqz(rs1, branchOffset(L)); }
    195  void bnez(Register rs, int16_t imm13) { bne(rs, zero_reg, imm13); }
    196  void bnez(Register rs1, Label* L) { bnez(rs1, branchOffset(L)); }
    197  void blez(Register rs, int16_t imm13) { bge(zero_reg, rs, imm13); }
    198  void blez(Register rs1, Label* L) { blez(rs1, branchOffset(L)); }
    199  void bgez(Register rs, int16_t imm13) { bge(rs, zero_reg, imm13); }
    200  void bgez(Register rs1, Label* L) { bgez(rs1, branchOffset(L)); }
    201  void bltz(Register rs, int16_t imm13) { blt(rs, zero_reg, imm13); }
    202  void bltz(Register rs1, Label* L) { bltz(rs1, branchOffset(L)); }
    203  void bgtz(Register rs, int16_t imm13) { blt(zero_reg, rs, imm13); }
    204 
    205  void bgtz(Register rs1, Label* L) { bgtz(rs1, branchOffset(L)); }
    206  void bgt(Register rs1, Register rs2, int16_t imm13) { blt(rs2, rs1, imm13); }
    207  void bgt(Register rs1, Register rs2, Label* L) {
    208    bgt(rs1, rs2, branchOffset(L));
    209  }
    210  void ble(Register rs1, Register rs2, int16_t imm13) { bge(rs2, rs1, imm13); }
    211  void ble(Register rs1, Register rs2, Label* L) {
    212    ble(rs1, rs2, branchOffset(L));
    213  }
    214  void bgtu(Register rs1, Register rs2, int16_t imm13) {
    215    bltu(rs2, rs1, imm13);
    216  }
    217  void bgtu(Register rs1, Register rs2, Label* L) {
    218    bgtu(rs1, rs2, branchOffset(L));
    219  }
    220  void bleu(Register rs1, Register rs2, int16_t imm13) {
    221    bgeu(rs2, rs1, imm13);
    222  }
    223  void bleu(Register rs1, Register rs2, Label* L) {
    224    bleu(rs1, rs2, branchOffset(L));
    225  }
    226 
    227  CodeOffset j(int32_t imm21) { return jal(zero_reg, imm21); }
    228  CodeOffset j(Label* L) { return j(jumpOffset(L)); }
    229  CodeOffset b(Label* L) { return j(L); }
    230  CodeOffset jal(int32_t imm21) { return jal(ra, imm21); }
    231  CodeOffset jal(Label* L) { return jal(jumpOffset(L)); }
    232  void jr(Register rs) { jalr(zero_reg, rs, 0); }
    233  void jr(Register rs, int32_t imm12) { jalr(zero_reg, rs, imm12); }
    234  void jalr(Register rs, int32_t imm12) { jalr(ra, rs, imm12); }
    235  void jalr(Register rs) { jalr(ra, rs, 0); }
    236  void call(int32_t offset) {
    237    auipc(ra, (offset >> 12) + ((offset & 0x800) >> 11));
    238    jalr(ra, ra, offset << 20 >> 20);
    239  }
    240 
    241  void mv(Register rd, Register rs) { addi(rd, rs, 0); }
    242  void not_(Register rd, Register rs) { xori(rd, rs, -1); }
    243  void neg(Register rd, Register rs) { sub(rd, zero_reg, rs); }
    244  void seqz(Register rd, Register rs) { sltiu(rd, rs, 1); }
    245  void snez(Register rd, Register rs) { sltu(rd, zero_reg, rs); }
    246  void sltz(Register rd, Register rs) { slt(rd, rs, zero_reg); }
    247  void sgtz(Register rd, Register rs) { slt(rd, zero_reg, rs); }
    248 
    249 #if JS_CODEGEN_RISCV64
    250  void lwu(Register rd, Register rs1, int16_t imm12);
    251  void ld(Register rd, Register rs1, int16_t imm12);
    252  void sd(Register source, Register base, int16_t imm12);
    253  void addiw(Register rd, Register rs1, int16_t imm12);
    254  void slliw(Register rd, Register rs1, uint8_t shamt);
    255  void srliw(Register rd, Register rs1, uint8_t shamt);
    256  void sraiw(Register rd, Register rs1, uint8_t shamt);
    257  void addw(Register rd, Register rs1, Register rs2);
    258  void subw(Register rd, Register rs1, Register rs2);
    259  void sllw(Register rd, Register rs1, Register rs2);
    260  void srlw(Register rd, Register rs1, Register rs2);
    261  void sraw(Register rd, Register rs1, Register rs2);
    262  void negw(Register rd, Register rs) { subw(rd, zero_reg, rs); }
    263  void sext_w(Register rd, Register rs) { addiw(rd, rs, 0); }
    264 
    265  static bool IsAddiw(Instr instr);
    266  static bool IsLd(Instr instr);
    267 #endif
    268 };
    269 
    270 }  // namespace jit
    271 }  // namespace js
    272 
    273 #endif  // jit_riscv64_extension_Base_riscv_I_h_