assembler_floating_point.cpp
1 #include <biscuit/assert.hpp> 2 #include <biscuit/assembler.hpp> 3 4 #include <algorithm> 5 #include <array> 6 #include <cstring> 7 #include <iterator> 8 9 #include "assembler_util.hpp" 10 11 // Various floating-point-based extension instructions. 12 13 namespace biscuit { 14 15 // RV32F Extension Instructions 16 17 void Assembler::FADD_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 18 EmitRType(m_buffer, 0b0000000, rs2, rs1, rmode, rd, 0b1010011); 19 } 20 void Assembler::FCLASS_S(GPR rd, FPR rs1) noexcept { 21 EmitRType(m_buffer, 0b1110000, f0, rs1, 0b001, rd, 0b1010011); 22 } 23 void Assembler::FCVT_S_W(FPR rd, GPR rs1, RMode rmode) noexcept { 24 EmitRType(m_buffer, 0b1101000, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 25 } 26 void Assembler::FCVT_S_WU(FPR rd, GPR rs1, RMode rmode) noexcept { 27 EmitRType(m_buffer, 0b1101000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 28 } 29 void Assembler::FCVT_W_S(GPR rd, FPR rs1, RMode rmode) noexcept { 30 EmitRType(m_buffer, 0b1100000, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 31 } 32 void Assembler::FCVT_WU_S(GPR rd, FPR rs1, RMode rmode) noexcept { 33 EmitRType(m_buffer, 0b1100000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 34 } 35 void Assembler::FDIV_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 36 EmitRType(m_buffer, 0b0001100, rs2, rs1, rmode, rd, 0b1010011); 37 } 38 void Assembler::FEQ_S(GPR rd, FPR rs1, FPR rs2) noexcept { 39 EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b010, rd, 0b1010011); 40 } 41 void Assembler::FLE_S(GPR rd, FPR rs1, FPR rs2) noexcept { 42 EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b000, rd, 0b1010011); 43 } 44 void Assembler::FLT_S(GPR rd, FPR rs1, FPR rs2) noexcept { 45 EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b001, rd, 0b1010011); 46 } 47 void Assembler::FLW(FPR rd, int32_t offset, GPR rs) noexcept { 48 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 49 EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b010, rd, 0b0000111); 50 } 51 void Assembler::FMADD_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 52 EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1000011); 53 } 54 void Assembler::FMAX_S(FPR rd, FPR rs1, FPR rs2) noexcept { 55 EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b001, rd, 0b1010011); 56 } 57 void Assembler::FMIN_S(FPR rd, FPR rs1, FPR rs2) noexcept { 58 EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b000, rd, 0b1010011); 59 } 60 void Assembler::FMSUB_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 61 EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1000111); 62 } 63 void Assembler::FMUL_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 64 EmitRType(m_buffer, 0b0001000, rs2, rs1, rmode, rd, 0b1010011); 65 } 66 void Assembler::FMV_W_X(FPR rd, GPR rs1) noexcept { 67 EmitRType(m_buffer, 0b1111000, f0, rs1, 0b000, rd, 0b1010011); 68 } 69 void Assembler::FMV_X_W(GPR rd, FPR rs1) noexcept { 70 EmitRType(m_buffer, 0b1110000, f0, rs1, 0b000, rd, 0b1010011); 71 } 72 void Assembler::FNMADD_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 73 EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1001111); 74 } 75 void Assembler::FNMSUB_S(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 76 EmitR4Type(m_buffer, rs3, 0b00, rs2, rs1, rmode, rd, 0b1001011); 77 } 78 void Assembler::FSGNJ_S(FPR rd, FPR rs1, FPR rs2) noexcept { 79 EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b000, rd, 0b1010011); 80 } 81 void Assembler::FSGNJN_S(FPR rd, FPR rs1, FPR rs2) noexcept { 82 EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b001, rd, 0b1010011); 83 } 84 void Assembler::FSGNJX_S(FPR rd, FPR rs1, FPR rs2) noexcept { 85 EmitRType(m_buffer, 0b0010000, rs2, rs1, 0b010, rd, 0b1010011); 86 } 87 void Assembler::FSQRT_S(FPR rd, FPR rs1, RMode rmode) noexcept { 88 EmitRType(m_buffer, 0b0101100, f0, rs1, rmode, rd, 0b1010011); 89 } 90 void Assembler::FSUB_S(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 91 EmitRType(m_buffer, 0b0000100, rs2, rs1, rmode, rd, 0b1010011); 92 } 93 void Assembler::FSW(FPR rs2, int32_t offset, GPR rs1) noexcept { 94 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 95 EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b010, 0b0100111); 96 } 97 98 void Assembler::FABS_S(FPR rd, FPR rs) noexcept { 99 FSGNJX_S(rd, rs, rs); 100 } 101 void Assembler::FMV_S(FPR rd, FPR rs) noexcept { 102 FSGNJ_S(rd, rs, rs); 103 } 104 void Assembler::FNEG_S(FPR rd, FPR rs) noexcept { 105 FSGNJN_S(rd, rs, rs); 106 } 107 108 // RV64F Extension Instructions 109 110 void Assembler::FCVT_L_S(GPR rd, FPR rs1, RMode rmode) noexcept { 111 BISCUIT_ASSERT(IsRV64(m_features)); 112 EmitRType(m_buffer, 0b1100000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 113 } 114 void Assembler::FCVT_LU_S(GPR rd, FPR rs1, RMode rmode) noexcept { 115 BISCUIT_ASSERT(IsRV64(m_features)); 116 EmitRType(m_buffer, 0b1100000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 117 } 118 void Assembler::FCVT_S_L(FPR rd, GPR rs1, RMode rmode) noexcept { 119 BISCUIT_ASSERT(IsRV64(m_features)); 120 EmitRType(m_buffer, 0b1101000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 121 } 122 void Assembler::FCVT_S_LU(FPR rd, GPR rs1, RMode rmode) noexcept { 123 BISCUIT_ASSERT(IsRV64(m_features)); 124 EmitRType(m_buffer, 0b1101000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 125 } 126 127 // RV32D Extension Instructions 128 129 void Assembler::FADD_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 130 EmitRType(m_buffer, 0b0000001, rs2, rs1, rmode, rd, 0b1010011); 131 } 132 void Assembler::FCLASS_D(GPR rd, FPR rs1) noexcept { 133 EmitRType(m_buffer, 0b1110001, f0, rs1, 0b001, rd, 0b1010011); 134 } 135 void Assembler::FCVT_D_W(FPR rd, GPR rs1, RMode rmode) noexcept { 136 EmitRType(m_buffer, 0b1101001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 137 } 138 void Assembler::FCVT_D_WU(FPR rd, GPR rs1, RMode rmode) noexcept { 139 EmitRType(m_buffer, 0b1101001, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 140 } 141 void Assembler::FCVT_W_D(GPR rd, FPR rs1, RMode rmode) noexcept { 142 EmitRType(m_buffer, 0b1100001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 143 } 144 void Assembler::FCVT_WU_D(GPR rd, FPR rs1, RMode rmode) noexcept { 145 EmitRType(m_buffer, 0b1100001, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 146 } 147 void Assembler::FCVT_D_S(FPR rd, FPR rs1, RMode rmode) noexcept { 148 EmitRType(m_buffer, 0b0100001, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 149 } 150 void Assembler::FCVT_S_D(FPR rd, FPR rs1, RMode rmode) noexcept { 151 EmitRType(m_buffer, 0b0100000, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 152 } 153 void Assembler::FDIV_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 154 EmitRType(m_buffer, 0b0001101, rs2, rs1, rmode, rd, 0b1010011); 155 } 156 void Assembler::FEQ_D(GPR rd, FPR rs1, FPR rs2) noexcept { 157 EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b010, rd, 0b1010011); 158 } 159 void Assembler::FLE_D(GPR rd, FPR rs1, FPR rs2) noexcept { 160 EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b000, rd, 0b1010011); 161 } 162 void Assembler::FLT_D(GPR rd, FPR rs1, FPR rs2) noexcept { 163 EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b001, rd, 0b1010011); 164 } 165 void Assembler::FLD(FPR rd, int32_t offset, GPR rs) noexcept { 166 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 167 EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b011, rd, 0b0000111); 168 } 169 void Assembler::FMADD_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 170 EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1000011); 171 } 172 void Assembler::FMAX_D(FPR rd, FPR rs1, FPR rs2) noexcept { 173 EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b001, rd, 0b1010011); 174 } 175 void Assembler::FMIN_D(FPR rd, FPR rs1, FPR rs2) noexcept { 176 EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b000, rd, 0b1010011); 177 } 178 void Assembler::FMSUB_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 179 EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1000111); 180 } 181 void Assembler::FMUL_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 182 EmitRType(m_buffer, 0b0001001, rs2, rs1, rmode, rd, 0b1010011); 183 } 184 void Assembler::FNMADD_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 185 EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1001111); 186 } 187 void Assembler::FNMSUB_D(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 188 EmitR4Type(m_buffer, rs3, 0b01, rs2, rs1, rmode, rd, 0b1001011); 189 } 190 void Assembler::FSGNJ_D(FPR rd, FPR rs1, FPR rs2) noexcept { 191 EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b000, rd, 0b1010011); 192 } 193 void Assembler::FSGNJN_D(FPR rd, FPR rs1, FPR rs2) noexcept { 194 EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b001, rd, 0b1010011); 195 } 196 void Assembler::FSGNJX_D(FPR rd, FPR rs1, FPR rs2) noexcept { 197 EmitRType(m_buffer, 0b0010001, rs2, rs1, 0b010, rd, 0b1010011); 198 } 199 void Assembler::FSQRT_D(FPR rd, FPR rs1, RMode rmode) noexcept { 200 EmitRType(m_buffer, 0b0101101, f0, rs1, rmode, rd, 0b1010011); 201 } 202 void Assembler::FSUB_D(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 203 EmitRType(m_buffer, 0b0000101, rs2, rs1, rmode, rd, 0b1010011); 204 } 205 void Assembler::FSD(FPR rs2, int32_t offset, GPR rs1) noexcept { 206 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 207 EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b011, 0b0100111); 208 } 209 210 void Assembler::FABS_D(FPR rd, FPR rs) noexcept { 211 FSGNJX_D(rd, rs, rs); 212 } 213 void Assembler::FMV_D(FPR rd, FPR rs) noexcept { 214 FSGNJ_D(rd, rs, rs); 215 } 216 void Assembler::FNEG_D(FPR rd, FPR rs) noexcept { 217 FSGNJN_D(rd, rs, rs); 218 } 219 220 // RV64D Extension Instructions 221 222 void Assembler::FCVT_L_D(GPR rd, FPR rs1, RMode rmode) noexcept { 223 BISCUIT_ASSERT(IsRV64(m_features)); 224 EmitRType(m_buffer, 0b1100001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 225 } 226 void Assembler::FCVT_LU_D(GPR rd, FPR rs1, RMode rmode) noexcept { 227 BISCUIT_ASSERT(IsRV64(m_features)); 228 EmitRType(m_buffer, 0b1100001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 229 } 230 void Assembler::FCVT_D_L(FPR rd, GPR rs1, RMode rmode) noexcept { 231 BISCUIT_ASSERT(IsRV64(m_features)); 232 EmitRType(m_buffer, 0b1101001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 233 } 234 void Assembler::FCVT_D_LU(FPR rd, GPR rs1, RMode rmode) noexcept { 235 BISCUIT_ASSERT(IsRV64(m_features)); 236 EmitRType(m_buffer, 0b1101001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 237 } 238 void Assembler::FMV_D_X(FPR rd, GPR rs1) noexcept { 239 BISCUIT_ASSERT(IsRV64OrRV128(m_features)); 240 EmitRType(m_buffer, 0b1111001, f0, rs1, 0b000, rd, 0b1010011); 241 } 242 void Assembler::FMV_X_D(GPR rd, FPR rs1) noexcept { 243 BISCUIT_ASSERT(IsRV64OrRV128(m_features)); 244 EmitRType(m_buffer, 0b1110001, f0, rs1, 0b000, rd, 0b1010011); 245 } 246 247 // RV32Q Extension Instructions 248 249 void Assembler::FADD_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 250 EmitRType(m_buffer, 0b0000011, rs2, rs1, rmode, rd, 0b1010011); 251 } 252 void Assembler::FCLASS_Q(GPR rd, FPR rs1) noexcept { 253 EmitRType(m_buffer, 0b1110011, f0, rs1, 0b001, rd, 0b1010011); 254 } 255 void Assembler::FCVT_Q_W(FPR rd, GPR rs1, RMode rmode) noexcept { 256 EmitRType(m_buffer, 0b1101011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 257 } 258 void Assembler::FCVT_Q_WU(FPR rd, GPR rs1, RMode rmode) noexcept { 259 EmitRType(m_buffer, 0b1101011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 260 } 261 void Assembler::FCVT_W_Q(GPR rd, FPR rs1, RMode rmode) noexcept { 262 EmitRType(m_buffer, 0b1100011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 263 } 264 void Assembler::FCVT_WU_Q(GPR rd, FPR rs1, RMode rmode) noexcept { 265 EmitRType(m_buffer, 0b1100011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 266 } 267 void Assembler::FCVT_Q_D(FPR rd, FPR rs1, RMode rmode) noexcept { 268 EmitRType(m_buffer, 0b0100011, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 269 } 270 void Assembler::FCVT_D_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 271 EmitRType(m_buffer, 0b0100001, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 272 } 273 void Assembler::FCVT_Q_S(FPR rd, FPR rs1, RMode rmode) noexcept { 274 EmitRType(m_buffer, 0b0100011, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 275 } 276 void Assembler::FCVT_S_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 277 EmitRType(m_buffer, 0b0100000, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 278 } 279 void Assembler::FDIV_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 280 EmitRType(m_buffer, 0b0001111, rs2, rs1, rmode, rd, 0b1010011); 281 } 282 void Assembler::FEQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept { 283 EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b010, rd, 0b1010011); 284 } 285 void Assembler::FLE_Q(GPR rd, FPR rs1, FPR rs2) noexcept { 286 EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b000, rd, 0b1010011); 287 } 288 void Assembler::FLT_Q(GPR rd, FPR rs1, FPR rs2) noexcept { 289 EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b001, rd, 0b1010011); 290 } 291 void Assembler::FLQ(FPR rd, int32_t offset, GPR rs) noexcept { 292 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 293 EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b100, rd, 0b0000111); 294 } 295 void Assembler::FMADD_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 296 EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1000011); 297 } 298 void Assembler::FMAX_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 299 EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b001, rd, 0b1010011); 300 } 301 void Assembler::FMIN_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 302 EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b000, rd, 0b1010011); 303 } 304 void Assembler::FMSUB_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 305 EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1000111); 306 } 307 void Assembler::FMUL_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 308 EmitRType(m_buffer, 0b0001011, rs2, rs1, rmode, rd, 0b1010011); 309 } 310 void Assembler::FNMADD_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 311 EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1001111); 312 } 313 void Assembler::FNMSUB_Q(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 314 EmitR4Type(m_buffer, rs3, 0b11, rs2, rs1, rmode, rd, 0b1001011); 315 } 316 void Assembler::FSGNJ_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 317 EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b000, rd, 0b1010011); 318 } 319 void Assembler::FSGNJN_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 320 EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b001, rd, 0b1010011); 321 } 322 void Assembler::FSGNJX_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 323 EmitRType(m_buffer, 0b0010011, rs2, rs1, 0b010, rd, 0b1010011); 324 } 325 void Assembler::FSQRT_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 326 EmitRType(m_buffer, 0b0101111, f0, rs1, rmode, rd, 0b1010011); 327 } 328 void Assembler::FSUB_Q(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 329 EmitRType(m_buffer, 0b0000111, rs2, rs1, rmode, rd, 0b1010011); 330 } 331 void Assembler::FSQ(FPR rs2, int32_t offset, GPR rs1) noexcept { 332 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 333 EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b100, 0b0100111); 334 } 335 336 void Assembler::FABS_Q(FPR rd, FPR rs) noexcept { 337 FSGNJX_Q(rd, rs, rs); 338 } 339 void Assembler::FMV_Q(FPR rd, FPR rs) noexcept { 340 FSGNJ_Q(rd, rs, rs); 341 } 342 void Assembler::FNEG_Q(FPR rd, FPR rs) noexcept { 343 FSGNJN_Q(rd, rs, rs); 344 } 345 346 // RV64Q Extension Instructions 347 348 void Assembler::FCVT_L_Q(GPR rd, FPR rs1, RMode rmode) noexcept { 349 BISCUIT_ASSERT(IsRV64(m_features)); 350 EmitRType(m_buffer, 0b1100011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 351 } 352 void Assembler::FCVT_LU_Q(GPR rd, FPR rs1, RMode rmode) noexcept { 353 BISCUIT_ASSERT(IsRV64(m_features)); 354 EmitRType(m_buffer, 0b1100011, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 355 } 356 void Assembler::FCVT_Q_L(FPR rd, GPR rs1, RMode rmode) noexcept { 357 BISCUIT_ASSERT(IsRV64(m_features)); 358 EmitRType(m_buffer, 0b1101011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 359 } 360 void Assembler::FCVT_Q_LU(FPR rd, GPR rs1, RMode rmode) noexcept { 361 BISCUIT_ASSERT(IsRV64(m_features)); 362 EmitRType(m_buffer, 0b1101011, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 363 } 364 365 // RV32Zfh Extension Instructions 366 367 void Assembler::FADD_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 368 EmitRType(m_buffer, 0b0000010, rs2, rs1, rmode, rd, 0b1010011); 369 } 370 void Assembler::FCLASS_H(GPR rd, FPR rs1) noexcept { 371 EmitRType(m_buffer, 0b1110010, f0, rs1, 0b001, rd, 0b1010011); 372 } 373 void Assembler::FCVT_D_H(FPR rd, FPR rs1, RMode rmode) noexcept { 374 EmitRType(m_buffer, 0b0100001, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 375 } 376 void Assembler::FCVT_H_D(FPR rd, FPR rs1, RMode rmode) noexcept { 377 EmitRType(m_buffer, 0b0100010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 378 } 379 void Assembler::FCVT_H_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 380 EmitRType(m_buffer, 0b0100010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 381 } 382 void Assembler::FCVT_H_S(FPR rd, FPR rs1, RMode rmode) noexcept { 383 EmitRType(m_buffer, 0b0100010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 384 } 385 void Assembler::FCVT_H_W(FPR rd, GPR rs1, RMode rmode) noexcept { 386 EmitRType(m_buffer, 0b1101010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 387 } 388 void Assembler::FCVT_H_WU(FPR rd, GPR rs1, RMode rmode) noexcept { 389 EmitRType(m_buffer, 0b1101010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 390 } 391 void Assembler::FCVT_Q_H(FPR rd, FPR rs1, RMode rmode) noexcept { 392 EmitRType(m_buffer, 0b0100011, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 393 } 394 void Assembler::FCVT_S_H(FPR rd, FPR rs1, RMode rmode) noexcept { 395 EmitRType(m_buffer, 0b0100000, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 396 } 397 void Assembler::FCVT_W_H(GPR rd, FPR rs1, RMode rmode) noexcept { 398 EmitRType(m_buffer, 0b1100010, f0, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 399 } 400 void Assembler::FCVT_WU_H(GPR rd, FPR rs1, RMode rmode) noexcept { 401 EmitRType(m_buffer, 0b1100010, f1, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 402 } 403 void Assembler::FDIV_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 404 EmitRType(m_buffer, 0b0001110, rs2, rs1, rmode, rd, 0b1010011); 405 } 406 void Assembler::FEQ_H(GPR rd, FPR rs1, FPR rs2) noexcept { 407 EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b010, rd, 0b1010011); 408 } 409 void Assembler::FLE_H(GPR rd, FPR rs1, FPR rs2) noexcept { 410 EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b000, rd, 0b1010011); 411 } 412 void Assembler::FLH(FPR rd, int32_t offset, GPR rs) noexcept { 413 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 414 EmitIType(m_buffer, static_cast<uint32_t>(offset), rs, 0b001, rd, 0b0000111); 415 } 416 void Assembler::FLT_H(GPR rd, FPR rs1, FPR rs2) noexcept { 417 EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b001, rd, 0b1010011); 418 } 419 void Assembler::FMADD_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 420 EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1000011); 421 } 422 void Assembler::FMAX_H(FPR rd, FPR rs1, FPR rs2) noexcept { 423 EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b001, rd, 0b1010011); 424 } 425 void Assembler::FMIN_H(FPR rd, FPR rs1, FPR rs2) noexcept { 426 EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b000, rd, 0b1010011); 427 } 428 void Assembler::FMSUB_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 429 EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1000111); 430 } 431 void Assembler::FMUL_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 432 EmitRType(m_buffer, 0b0001010, rs2, rs1, rmode, rd, 0b1010011); 433 } 434 void Assembler::FMV_H_X(FPR rd, GPR rs1) noexcept { 435 EmitRType(m_buffer, 0b1111010, f0, rs1, 0b000, rd, 0b1010011); 436 } 437 void Assembler::FMV_X_H(GPR rd, FPR rs1) noexcept { 438 EmitRType(m_buffer, 0b1110010, f0, rs1, 0b000, rd, 0b1010011); 439 } 440 void Assembler::FNMADD_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 441 EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1001111); 442 } 443 void Assembler::FNMSUB_H(FPR rd, FPR rs1, FPR rs2, FPR rs3, RMode rmode) noexcept { 444 EmitR4Type(m_buffer, rs3, 0b10, rs2, rs1, rmode, rd, 0b1001011); 445 } 446 void Assembler::FSGNJ_H(FPR rd, FPR rs1, FPR rs2) noexcept { 447 EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b000, rd, 0b1010011); 448 } 449 void Assembler::FSGNJN_H(FPR rd, FPR rs1, FPR rs2) noexcept { 450 EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b001, rd, 0b1010011); 451 } 452 void Assembler::FSGNJX_H(FPR rd, FPR rs1, FPR rs2) noexcept { 453 EmitRType(m_buffer, 0b0010010, rs2, rs1, 0b010, rd, 0b1010011); 454 } 455 void Assembler::FSH(FPR rs2, int32_t offset, GPR rs1) noexcept { 456 BISCUIT_ASSERT(IsValidSigned12BitImm(offset)); 457 EmitSType(m_buffer, static_cast<uint32_t>(offset), rs2, rs1, 0b001, 0b0100111); 458 } 459 void Assembler::FSQRT_H(FPR rd, FPR rs1, RMode rmode) noexcept { 460 EmitRType(m_buffer, 0b0101110, f0, rs1, rmode, rd, 0b1010011); 461 } 462 void Assembler::FSUB_H(FPR rd, FPR rs1, FPR rs2, RMode rmode) noexcept { 463 EmitRType(m_buffer, 0b0000110, rs2, rs1, rmode, rd, 0b1010011); 464 } 465 466 // RV64Zfh Extension Instructions 467 468 void Assembler::FCVT_L_H(GPR rd, FPR rs1, RMode rmode) noexcept { 469 EmitRType(m_buffer, 0b1100010, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 470 } 471 void Assembler::FCVT_LU_H(GPR rd, FPR rs1, RMode rmode) noexcept { 472 EmitRType(m_buffer, 0b1100010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 473 } 474 void Assembler::FCVT_H_L(FPR rd, GPR rs1, RMode rmode) noexcept { 475 EmitRType(m_buffer, 0b1101010, f2, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 476 } 477 void Assembler::FCVT_H_LU(FPR rd, GPR rs1, RMode rmode) noexcept { 478 EmitRType(m_buffer, 0b1101010, f3, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 479 } 480 481 // Zfa Extension Instructions 482 483 static void FLIImpl(CodeBuffer& buffer, uint32_t funct7, FPR rd, double value) noexcept { 484 static constexpr std::array fli_table{ 485 0xBFF0000000000000ULL, // -1.0 486 0x0010000000000000ULL, // Minimum positive normal 487 0x3EF0000000000000ULL, // 1.0 * 2^-16 488 0x3F00000000000000ULL, // 1.0 * 2^-15 489 0x3F70000000000000ULL, // 1.0 * 2^-8 490 0x3F80000000000000ULL, // 1.0 * 2^-7 491 0x3FB0000000000000ULL, // 1.0 * 2^-4 492 0x3FC0000000000000ULL, // 1.0 * 2^-3 493 0x3FD0000000000000ULL, // 0.25 494 0x3FD4000000000000ULL, // 0.3125 495 0x3FD8000000000000ULL, // 0.375 496 0x3FDC000000000000ULL, // 0.4375 497 0x3FE0000000000000ULL, // 0.5 498 0x3FE4000000000000ULL, // 0.625 499 0x3FE8000000000000ULL, // 0.75 500 0x3FEC000000000000ULL, // 0.875 501 0x3FF0000000000000ULL, // 1.0 502 0x3FF4000000000000ULL, // 1.25 503 0x3FF8000000000000ULL, // 1.5 504 0x3FFC000000000000ULL, // 1.75 505 0x4000000000000000ULL, // 2.0 506 0x4004000000000000ULL, // 2.5 507 0x4008000000000000ULL, // 3 508 0x4010000000000000ULL, // 4 509 0x4020000000000000ULL, // 8 510 0x4030000000000000ULL, // 16 511 0x4060000000000000ULL, // 2^7 512 0x4070000000000000ULL, // 2^8 513 0x40E0000000000000ULL, // 2^15 514 0x40F0000000000000ULL, // 2^16 515 0x7FF0000000000000ULL, // +inf 516 0x7FF8000000000000ULL, // Canonical NaN 517 }; 518 519 uint64_t ivalue{}; 520 std::memcpy(&ivalue, &value, sizeof(uint64_t)); 521 522 const auto iter = std::find_if(fli_table.cbegin(), fli_table.cend(), [ivalue](uint64_t entry) { 523 return entry == ivalue; 524 }); 525 BISCUIT_ASSERT(iter != fli_table.cend()); 526 527 const auto index = static_cast<uint32_t>(std::distance(fli_table.cbegin(), iter)); 528 EmitRType(buffer, funct7, f1, GPR{index}, 0b000, rd, 0b1010011); 529 } 530 531 void Assembler::FLI_D(FPR rd, double value) noexcept { 532 FLIImpl(m_buffer, 0b1111001, rd, value); 533 } 534 void Assembler::FLI_H(FPR rd, double value) noexcept { 535 FLIImpl(m_buffer, 0b1111010, rd, value); 536 } 537 void Assembler::FLI_S(FPR rd, double value) noexcept { 538 FLIImpl(m_buffer, 0b1111000, rd, value); 539 } 540 541 void Assembler::FMINM_D(FPR rd, FPR rs1, FPR rs2) noexcept { 542 EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b010, rd, 0b1010011); 543 } 544 void Assembler::FMINM_H(FPR rd, FPR rs1, FPR rs2) noexcept { 545 EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b010, rd, 0b1010011); 546 } 547 void Assembler::FMINM_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 548 EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b010, rd, 0b1010011); 549 } 550 void Assembler::FMINM_S(FPR rd, FPR rs1, FPR rs2) noexcept { 551 EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b010, rd, 0b1010011); 552 } 553 554 void Assembler::FMAXM_D(FPR rd, FPR rs1, FPR rs2) noexcept { 555 EmitRType(m_buffer, 0b0010101, rs2, rs1, 0b011, rd, 0b1010011); 556 } 557 void Assembler::FMAXM_H(FPR rd, FPR rs1, FPR rs2) noexcept { 558 EmitRType(m_buffer, 0b0010110, rs2, rs1, 0b011, rd, 0b1010011); 559 } 560 void Assembler::FMAXM_Q(FPR rd, FPR rs1, FPR rs2) noexcept { 561 EmitRType(m_buffer, 0b0010111, rs2, rs1, 0b011, rd, 0b1010011); 562 } 563 void Assembler::FMAXM_S(FPR rd, FPR rs1, FPR rs2) noexcept { 564 EmitRType(m_buffer, 0b0010100, rs2, rs1, 0b011, rd, 0b1010011); 565 } 566 567 void Assembler::FROUND_D(FPR rd, FPR rs1, RMode rmode) noexcept { 568 EmitRType(m_buffer, 0b0100001, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 569 } 570 void Assembler::FROUND_H(FPR rd, FPR rs1, RMode rmode) noexcept { 571 EmitRType(m_buffer, 0b0100010, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 572 } 573 void Assembler::FROUND_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 574 EmitRType(m_buffer, 0b0100011, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 575 } 576 void Assembler::FROUND_S(FPR rd, FPR rs1, RMode rmode) noexcept { 577 EmitRType(m_buffer, 0b0100000, f4, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 578 } 579 580 void Assembler::FROUNDNX_D(FPR rd, FPR rs1, RMode rmode) noexcept { 581 EmitRType(m_buffer, 0b0100001, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 582 } 583 void Assembler::FROUNDNX_H(FPR rd, FPR rs1, RMode rmode) noexcept { 584 EmitRType(m_buffer, 0b0100010, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 585 } 586 void Assembler::FROUNDNX_Q(FPR rd, FPR rs1, RMode rmode) noexcept { 587 EmitRType(m_buffer, 0b0100011, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 588 } 589 void Assembler::FROUNDNX_S(FPR rd, FPR rs1, RMode rmode) noexcept { 590 EmitRType(m_buffer, 0b0100000, f5, rs1, static_cast<uint32_t>(rmode), rd, 0b1010011); 591 } 592 593 void Assembler::FCVTMOD_W_D(GPR rd, FPR rs1) noexcept { 594 EmitRType(m_buffer, 0b1100001, f8, rs1, static_cast<uint32_t>(RMode::RTZ), rd, 0b1010011); 595 } 596 597 void Assembler::FMVH_X_D(GPR rd, FPR rs1) noexcept { 598 EmitRType(m_buffer, 0b1110001, f1, rs1, 0b000, rd, 0b1010011); 599 } 600 void Assembler::FMVH_X_Q(GPR rd, FPR rs1) noexcept { 601 EmitRType(m_buffer, 0b1110011, f1, rs1, 0b000, rd, 0b1010011); 602 } 603 void Assembler::FMVP_D_X(FPR rd, GPR rs1, GPR rs2) noexcept { 604 EmitRType(m_buffer, 0b1011001, rs2, rs1, 0b000, rd, 0b1010011); 605 } 606 void Assembler::FMVP_Q_X(FPR rd, GPR rs1, GPR rs2) noexcept { 607 EmitRType(m_buffer, 0b1011011, rs2, rs1, 0b000, rd, 0b1010011); 608 } 609 610 void Assembler::FLEQ_D(GPR rd, FPR rs1, FPR rs2) noexcept { 611 EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b100, rd, 0b1010011); 612 } 613 void Assembler::FLTQ_D(GPR rd, FPR rs1, FPR rs2) noexcept { 614 EmitRType(m_buffer, 0b1010001, rs2, rs1, 0b101, rd, 0b1010011); 615 } 616 617 void Assembler::FLEQ_H(GPR rd, FPR rs1, FPR rs2) noexcept { 618 EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b100, rd, 0b1010011); 619 } 620 void Assembler::FLTQ_H(GPR rd, FPR rs1, FPR rs2) noexcept { 621 EmitRType(m_buffer, 0b1010010, rs2, rs1, 0b101, rd, 0b1010011); 622 } 623 624 void Assembler::FLEQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept { 625 EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b100, rd, 0b1010011); 626 } 627 void Assembler::FLTQ_Q(GPR rd, FPR rs1, FPR rs2) noexcept { 628 EmitRType(m_buffer, 0b1010011, rs2, rs1, 0b101, rd, 0b1010011); 629 } 630 631 void Assembler::FLEQ_S(GPR rd, FPR rs1, FPR rs2) noexcept { 632 EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b100, rd, 0b1010011); 633 } 634 void Assembler::FLTQ_S(GPR rd, FPR rs1, FPR rs2) noexcept { 635 EmitRType(m_buffer, 0b1010000, rs2, rs1, 0b101, rd, 0b1010011); 636 } 637 638 // Zfbfmin, Zvfbfmin, Zvfbfwma Extension Instructions 639 640 void Assembler::FCVT_BF16_S(FPR rd, FPR rs, RMode rmode) noexcept { 641 EmitRType(m_buffer, 0b0100010, f8, rs, static_cast<uint32_t>(rmode), rd, 0b1010011); 642 } 643 644 void Assembler::FCVT_S_BF16(FPR rd, FPR rs, RMode rmode) noexcept { 645 EmitRType(m_buffer, 0b0100000, f6, rs, static_cast<uint32_t>(rmode), rd, 0b1010011); 646 } 647 648 } // namespace biscuit