base-assembler-riscv.h (10565B)
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // All Rights Reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the distribution. 14 // 15 // - Neither the name of Sun Microsystems or the names of contributors may 16 // be used to endorse or promote products derived from this software without 17 // specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // The original source code covered by the above license above has been 32 // modified significantly by Google Inc. 33 // Copyright 2021 the V8 project authors. All rights reserved. 34 35 #ifndef jit_riscv64_extension_Base_assembler_riscv_h 36 #define jit_riscv64_extension_Base_assembler_riscv_h 37 38 #include <stdio.h> 39 40 #include "jit/Label.h" 41 #include "jit/riscv64/Architecture-riscv64.h" 42 #include "jit/riscv64/constant/Constant-riscv64.h" 43 #include "jit/riscv64/Register-riscv64.h" 44 #include "jit/shared/IonAssemblerBuffer.h" 45 46 #define xlen (uint8_t(sizeof(void*) * 8)) 47 48 #define kBitsPerByte 8UL 49 // Check number width. 50 inline constexpr bool is_intn(int64_t x, unsigned n) { 51 MOZ_ASSERT((0 < n) && (n < 64)); 52 int64_t limit = static_cast<int64_t>(1) << (n - 1); 53 return (-limit <= x) && (x < limit); 54 } 55 56 inline constexpr bool is_uintn(int64_t x, unsigned n) { 57 MOZ_ASSERT((0 < n) && (n < (sizeof(x) * kBitsPerByte))); 58 return !(x >> n); 59 } 60 #undef kBitsPerByte 61 // clang-format off 62 #define INT_1_TO_63_LIST(V) \ 63 V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) V(9) V(10) \ 64 V(11) V(12) V(13) V(14) V(15) V(16) V(17) V(18) V(19) V(20) \ 65 V(21) V(22) V(23) V(24) V(25) V(26) V(27) V(28) V(29) V(30) \ 66 V(31) V(32) V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \ 67 V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) V(49) V(50) \ 68 V(51) V(52) V(53) V(54) V(55) V(56) V(57) V(58) V(59) V(60) \ 69 V(61) V(62) V(63) 70 // clang-format on 71 72 #define DECLARE_IS_INT_N(N) \ 73 inline constexpr bool is_int##N(int64_t x) { return is_intn(x, N); } 74 75 #define DECLARE_IS_UINT_N(N) \ 76 template <class T> \ 77 inline constexpr bool is_uint##N(T x) { \ 78 return is_uintn(x, N); \ 79 } 80 INT_1_TO_63_LIST(DECLARE_IS_INT_N) 81 INT_1_TO_63_LIST(DECLARE_IS_UINT_N) 82 83 #undef DECLARE_IS_INT_N 84 #undef INT_1_TO_63_LIST 85 86 namespace js { 87 namespace jit { 88 89 typedef FloatRegister FPURegister; 90 #define zero_reg zero 91 92 #if defined(DEBUG) 93 // Only useful when defined(DEBUG). See op.getBoolOption("riscv-debug") in 94 // js/src/shell/js.cpp. 95 # define DEBUG_PRINTF(...) \ 96 if (FLAG_riscv_debug) { \ 97 std::printf(__VA_ARGS__); \ 98 } 99 #else 100 # define DEBUG_PRINTF(...) \ 101 do { \ 102 } while (0) 103 #endif /* defined(DEBUG) */ 104 105 int ToNumber(Register reg); 106 Register ToRegister(uint32_t num); 107 108 class AssemblerRiscvBase { 109 protected: 110 virtual int32_t branchOffsetHelper(Label* L, OffsetSize bits) = 0; 111 112 virtual BufferOffset emit(Instr x) = 0; 113 virtual BufferOffset emit(ShortInstr x) = 0; 114 virtual BufferOffset emit(uint64_t x) = 0; 115 virtual uint32_t currentOffset() = 0; 116 // Instruction generation. 117 118 // ----- Top-level instruction formats match those in the ISA manual 119 // (R, I, S, B, U, J). These match the formats defined in LLVM's 120 // RISCVInstrFormats.td. 121 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd, 122 Register rs1, Register rs2); 123 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, 124 FPURegister rd, FPURegister rs1, FPURegister rs2); 125 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd, 126 FPURegister rs1, Register rs2); 127 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, 128 FPURegister rd, Register rs1, Register rs2); 129 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, 130 FPURegister rd, FPURegister rs1, Register rs2); 131 void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd, 132 FPURegister rs1, FPURegister rs2); 133 void GenInstrR4(uint8_t funct2, BaseOpcode opcode, Register rd, Register rs1, 134 Register rs2, Register rs3, FPURoundingMode frm); 135 void GenInstrR4(uint8_t funct2, BaseOpcode opcode, FPURegister rd, 136 FPURegister rs1, FPURegister rs2, FPURegister rs3, 137 FPURoundingMode frm); 138 void GenInstrRAtomic(uint8_t funct5, bool aq, bool rl, uint8_t funct3, 139 Register rd, Register rs1, Register rs2); 140 void GenInstrRFrm(uint8_t funct7, BaseOpcode opcode, Register rd, 141 Register rs1, Register rs2, FPURoundingMode frm); 142 BufferOffset GenInstrI(uint8_t funct3, BaseOpcode opcode, Register rd, 143 Register rs1, int16_t imm12); 144 BufferOffset GenInstrI(uint8_t funct3, BaseOpcode opcode, FPURegister rd, 145 Register rs1, int16_t imm12); 146 void GenInstrIShift(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, 147 Register rd, Register rs1, uint8_t shamt); 148 void GenInstrIShiftW(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, 149 Register rd, Register rs1, uint8_t shamt); 150 void GenInstrS(uint8_t funct3, BaseOpcode opcode, Register rs1, Register rs2, 151 int16_t imm12); 152 void GenInstrS(uint8_t funct3, BaseOpcode opcode, Register rs1, 153 FPURegister rs2, int16_t imm12); 154 void GenInstrB(uint8_t funct3, BaseOpcode opcode, Register rs1, Register rs2, 155 int16_t imm12); 156 void GenInstrU(BaseOpcode opcode, Register rd, int32_t imm20); 157 void GenInstrJ(BaseOpcode opcode, Register rd, int32_t imm20); 158 void GenInstrCR(uint8_t funct4, BaseOpcode opcode, Register rd, Register rs2); 159 void GenInstrCA(uint8_t funct6, BaseOpcode opcode, Register rd, uint8_t funct, 160 Register rs2); 161 void GenInstrCI(uint8_t funct3, BaseOpcode opcode, Register rd, int8_t imm6); 162 void GenInstrCIU(uint8_t funct3, BaseOpcode opcode, Register rd, 163 uint8_t uimm6); 164 void GenInstrCIU(uint8_t funct3, BaseOpcode opcode, FPURegister rd, 165 uint8_t uimm6); 166 void GenInstrCIW(uint8_t funct3, BaseOpcode opcode, Register rd, 167 uint8_t uimm8); 168 void GenInstrCSS(uint8_t funct3, BaseOpcode opcode, FPURegister rs2, 169 uint8_t uimm6); 170 void GenInstrCSS(uint8_t funct3, BaseOpcode opcode, Register rs2, 171 uint8_t uimm6); 172 void GenInstrCL(uint8_t funct3, BaseOpcode opcode, Register rd, Register rs1, 173 uint8_t uimm5); 174 void GenInstrCL(uint8_t funct3, BaseOpcode opcode, FPURegister rd, 175 Register rs1, uint8_t uimm5); 176 void GenInstrCS(uint8_t funct3, BaseOpcode opcode, Register rs2, Register rs1, 177 uint8_t uimm5); 178 void GenInstrCS(uint8_t funct3, BaseOpcode opcode, FPURegister rs2, 179 Register rs1, uint8_t uimm5); 180 void GenInstrCJ(uint8_t funct3, BaseOpcode opcode, uint16_t uint11); 181 void GenInstrCB(uint8_t funct3, BaseOpcode opcode, Register rs1, 182 uint8_t uimm8); 183 void GenInstrCBA(uint8_t funct3, uint8_t funct2, BaseOpcode opcode, 184 Register rs1, int8_t imm6); 185 186 // ----- Instruction class templates match those in LLVM's RISCVInstrInfo.td 187 void GenInstrBranchCC_rri(uint8_t funct3, Register rs1, Register rs2, 188 int16_t imm12); 189 void GenInstrLoad_ri(uint8_t funct3, Register rd, Register rs1, 190 int16_t imm12); 191 void GenInstrStore_rri(uint8_t funct3, Register rs1, Register rs2, 192 int16_t imm12); 193 void GenInstrALU_ri(uint8_t funct3, Register rd, Register rs1, int16_t imm12); 194 void GenInstrShift_ri(bool arithshift, uint8_t funct3, Register rd, 195 Register rs1, uint8_t shamt); 196 void GenInstrALU_rr(uint8_t funct7, uint8_t funct3, Register rd, Register rs1, 197 Register rs2); 198 void GenInstrCSR_ir(uint8_t funct3, Register rd, ControlStatusReg csr, 199 Register rs1); 200 void GenInstrCSR_ii(uint8_t funct3, Register rd, ControlStatusReg csr, 201 uint8_t rs1); 202 void GenInstrShiftW_ri(bool arithshift, uint8_t funct3, Register rd, 203 Register rs1, uint8_t shamt); 204 void GenInstrALUW_rr(uint8_t funct7, uint8_t funct3, Register rd, 205 Register rs1, Register rs2); 206 void GenInstrPriv(uint8_t funct7, Register rs1, Register rs2); 207 void GenInstrLoadFP_ri(uint8_t funct3, FPURegister rd, Register rs1, 208 int16_t imm12); 209 void GenInstrStoreFP_rri(uint8_t funct3, Register rs1, FPURegister rs2, 210 int16_t imm12); 211 void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd, 212 FPURegister rs1, FPURegister rs2); 213 void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd, 214 Register rs1, Register rs2); 215 void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd, 216 FPURegister rs1, Register rs2); 217 void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, Register rd, 218 FPURegister rs1, Register rs2); 219 void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, Register rd, 220 FPURegister rs1, FPURegister rs2); 221 }; 222 223 } // namespace jit 224 } // namespace js 225 226 #endif // jit_riscv64_extension_Base_assembler_riscv_h