1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #ifndef _ASM_INST_H 6 #define _ASM_INST_H 7 8 #include <linux/bitops.h> 9 #include <linux/types.h> 10 #include <asm/asm.h> 11 #include <asm/ptrace.h> 12 13 #define INSN_NOP 0x03400000 14 #define INSN_BREAK 0x002a0000 15 #define INSN_HVCL 0x002b8000 16 17 #define ADDR_IMMMASK_LU52ID 0xFFF0000000000000 18 #define ADDR_IMMMASK_LU32ID 0x000FFFFF00000000 19 #define ADDR_IMMMASK_LU12IW 0x00000000FFFFF000 20 #define ADDR_IMMMASK_ORI 0x0000000000000FFF 21 #define ADDR_IMMMASK_ADDU16ID 0x00000000FFFF0000 22 23 #define ADDR_IMMSHIFT_LU52ID 52 24 #define ADDR_IMMSBIDX_LU52ID 11 25 #define ADDR_IMMSHIFT_LU32ID 32 26 #define ADDR_IMMSBIDX_LU32ID 19 27 #define ADDR_IMMSHIFT_LU12IW 12 28 #define ADDR_IMMSBIDX_LU12IW 19 29 #define ADDR_IMMSHIFT_ORI 0 30 #define ADDR_IMMSBIDX_ORI 63 31 #define ADDR_IMMSHIFT_ADDU16ID 16 32 #define ADDR_IMMSBIDX_ADDU16ID 15 33 34 #define ADDR_IMM(addr, INSN) \ 35 (sign_extend64(((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIFT_##INSN), ADDR_IMMSBIDX_##INSN)) 36 37 enum reg0i15_op { 38 break_op = 0x54, 39 dbar_op = 0x70e4, 40 }; 41 42 enum reg0i26_op { 43 b_op = 0x14, 44 bl_op = 0x15, 45 }; 46 47 enum reg1i20_op { 48 lu12iw_op = 0x0a, 49 lu32id_op = 0x0b, 50 pcaddi_op = 0x0c, 51 pcalau12i_op = 0x0d, 52 pcaddu12i_op = 0x0e, 53 pcaddu18i_op = 0x0f, 54 }; 55 56 enum reg1i21_op { 57 beqz_op = 0x10, 58 bnez_op = 0x11, 59 bceqz_op = 0x12, /* bits[9:8] = 0x00 */ 60 bcnez_op = 0x12, /* bits[9:8] = 0x01 */ 61 }; 62 63 enum reg2_op { 64 revb2h_op = 0x0c, 65 revb4h_op = 0x0d, 66 revb2w_op = 0x0e, 67 revbd_op = 0x0f, 68 revh2w_op = 0x10, 69 revhd_op = 0x11, 70 extwh_op = 0x16, 71 extwb_op = 0x17, 72 cpucfg_op = 0x1b, 73 iocsrrdb_op = 0x19200, 74 iocsrrdh_op = 0x19201, 75 iocsrrdw_op = 0x19202, 76 iocsrrdd_op = 0x19203, 77 iocsrwrb_op = 0x19204, 78 iocsrwrh_op = 0x19205, 79 iocsrwrw_op = 0x19206, 80 iocsrwrd_op = 0x19207, 81 llacqw_op = 0xe15e0, 82 screlw_op = 0xe15e1, 83 llacqd_op = 0xe15e2, 84 screld_op = 0xe15e3, 85 }; 86 87 enum reg2i5_op { 88 slliw_op = 0x81, 89 srliw_op = 0x89, 90 sraiw_op = 0x91, 91 }; 92 93 enum reg2i6_op { 94 sllid_op = 0x41, 95 srlid_op = 0x45, 96 sraid_op = 0x49, 97 }; 98 99 enum reg2i12_op { 100 sltui_op = 0x09, 101 addiw_op = 0x0a, 102 addid_op = 0x0b, 103 lu52id_op = 0x0c, 104 andi_op = 0x0d, 105 ori_op = 0x0e, 106 xori_op = 0x0f, 107 ldb_op = 0xa0, 108 ldh_op = 0xa1, 109 ldw_op = 0xa2, 110 ldd_op = 0xa3, 111 stb_op = 0xa4, 112 sth_op = 0xa5, 113 stw_op = 0xa6, 114 std_op = 0xa7, 115 ldbu_op = 0xa8, 116 ldhu_op = 0xa9, 117 ldwu_op = 0xaa, 118 flds_op = 0xac, 119 fsts_op = 0xad, 120 fldd_op = 0xae, 121 fstd_op = 0xaf, 122 }; 123 124 enum reg2i14_op { 125 llw_op = 0x20, 126 scw_op = 0x21, 127 lld_op = 0x22, 128 scd_op = 0x23, 129 ldptrw_op = 0x24, 130 stptrw_op = 0x25, 131 ldptrd_op = 0x26, 132 stptrd_op = 0x27, 133 }; 134 135 enum reg2i16_op { 136 jirl_op = 0x13, 137 beq_op = 0x16, 138 bne_op = 0x17, 139 blt_op = 0x18, 140 bge_op = 0x19, 141 bltu_op = 0x1a, 142 bgeu_op = 0x1b, 143 }; 144 145 enum reg2bstrd_op { 146 bstrinsd_op = 0x2, 147 bstrpickd_op = 0x3, 148 }; 149 150 enum reg3_op { 151 asrtle_op = 0x02, 152 asrtgt_op = 0x03, 153 addw_op = 0x20, 154 addd_op = 0x21, 155 subw_op = 0x22, 156 subd_op = 0x23, 157 maskeqz_op = 0x26, 158 masknez_op = 0x27, 159 nor_op = 0x28, 160 and_op = 0x29, 161 or_op = 0x2a, 162 xor_op = 0x2b, 163 orn_op = 0x2c, 164 andn_op = 0x2d, 165 sllw_op = 0x2e, 166 srlw_op = 0x2f, 167 sraw_op = 0x30, 168 slld_op = 0x31, 169 srld_op = 0x32, 170 srad_op = 0x33, 171 mulw_op = 0x38, 172 mulhw_op = 0x39, 173 mulhwu_op = 0x3a, 174 muld_op = 0x3b, 175 mulhd_op = 0x3c, 176 mulhdu_op = 0x3d, 177 divw_op = 0x40, 178 modw_op = 0x41, 179 divwu_op = 0x42, 180 modwu_op = 0x43, 181 divd_op = 0x44, 182 modd_op = 0x45, 183 divdu_op = 0x46, 184 moddu_op = 0x47, 185 ldxb_op = 0x7000, 186 ldxh_op = 0x7008, 187 ldxw_op = 0x7010, 188 ldxd_op = 0x7018, 189 stxb_op = 0x7020, 190 stxh_op = 0x7028, 191 stxw_op = 0x7030, 192 stxd_op = 0x7038, 193 ldxbu_op = 0x7040, 194 ldxhu_op = 0x7048, 195 ldxwu_op = 0x7050, 196 fldxs_op = 0x7060, 197 fldxd_op = 0x7068, 198 fstxs_op = 0x7070, 199 fstxd_op = 0x7078, 200 scq_op = 0x70ae, 201 amswapb_op = 0x70b8, 202 amswaph_op = 0x70b9, 203 amaddb_op = 0x70ba, 204 amaddh_op = 0x70bb, 205 amswapdbb_op = 0x70bc, 206 amswapdbh_op = 0x70bd, 207 amadddbb_op = 0x70be, 208 amadddbh_op = 0x70bf, 209 amswapw_op = 0x70c0, 210 amswapd_op = 0x70c1, 211 amaddw_op = 0x70c2, 212 amaddd_op = 0x70c3, 213 amandw_op = 0x70c4, 214 amandd_op = 0x70c5, 215 amorw_op = 0x70c6, 216 amord_op = 0x70c7, 217 amxorw_op = 0x70c8, 218 amxord_op = 0x70c9, 219 ammaxw_op = 0x70ca, 220 ammaxd_op = 0x70cb, 221 amminw_op = 0x70cc, 222 ammind_op = 0x70cd, 223 ammaxwu_op = 0x70ce, 224 ammaxdu_op = 0x70cf, 225 amminwu_op = 0x70d0, 226 ammindu_op = 0x70d1, 227 amswapdbw_op = 0x70d2, 228 amswapdbd_op = 0x70d3, 229 amadddbw_op = 0x70d4, 230 amadddbd_op = 0x70d5, 231 amanddbw_op = 0x70d6, 232 amanddbd_op = 0x70d7, 233 amordbw_op = 0x70d8, 234 amordbd_op = 0x70d9, 235 amxordbw_op = 0x70da, 236 amxordbd_op = 0x70db, 237 ammaxdbw_op = 0x70dc, 238 ammaxdbd_op = 0x70dd, 239 ammindbw_op = 0x70de, 240 ammindbd_op = 0x70df, 241 ammaxdbwu_op = 0x70e0, 242 ammaxdbdu_op = 0x70e1, 243 ammindbwu_op = 0x70e2, 244 ammindbdu_op = 0x70e3, 245 fldgts_op = 0x70e8, 246 fldgtd_op = 0x70e9, 247 fldles_op = 0x70ea, 248 fldled_op = 0x70eb, 249 fstgts_op = 0x70ec, 250 fstgtd_op = 0x70ed, 251 fstles_op = 0x70ee, 252 fstled_op = 0x70ef, 253 ldgtb_op = 0x70f0, 254 ldgth_op = 0x70f1, 255 ldgtw_op = 0x70f2, 256 ldgtd_op = 0x70f3, 257 ldleb_op = 0x70f4, 258 ldleh_op = 0x70f5, 259 ldlew_op = 0x70f6, 260 ldled_op = 0x70f7, 261 stgtb_op = 0x70f8, 262 stgth_op = 0x70f9, 263 stgtw_op = 0x70fa, 264 stgtd_op = 0x70fb, 265 stleb_op = 0x70fc, 266 stleh_op = 0x70fd, 267 stlew_op = 0x70fe, 268 stled_op = 0x70ff, 269 }; 270 271 enum reg3sa2_op { 272 alslw_op = 0x02, 273 alslwu_op = 0x03, 274 alsld_op = 0x16, 275 }; 276 277 struct reg0i15_format { 278 unsigned int immediate : 15; 279 unsigned int opcode : 17; 280 }; 281 282 struct reg0i26_format { 283 unsigned int immediate_h : 10; 284 unsigned int immediate_l : 16; 285 unsigned int opcode : 6; 286 }; 287 288 struct reg1i20_format { 289 unsigned int rd : 5; 290 unsigned int immediate : 20; 291 unsigned int opcode : 7; 292 }; 293 294 struct reg1i21_format { 295 unsigned int immediate_h : 5; 296 unsigned int rj : 5; 297 unsigned int immediate_l : 16; 298 unsigned int opcode : 6; 299 }; 300 301 struct reg2_format { 302 unsigned int rd : 5; 303 unsigned int rj : 5; 304 unsigned int opcode : 22; 305 }; 306 307 struct reg2i5_format { 308 unsigned int rd : 5; 309 unsigned int rj : 5; 310 unsigned int immediate : 5; 311 unsigned int opcode : 17; 312 }; 313 314 struct reg2i6_format { 315 unsigned int rd : 5; 316 unsigned int rj : 5; 317 unsigned int immediate : 6; 318 unsigned int opcode : 16; 319 }; 320 321 struct reg2i12_format { 322 unsigned int rd : 5; 323 unsigned int rj : 5; 324 unsigned int immediate : 12; 325 unsigned int opcode : 10; 326 }; 327 328 struct reg2i14_format { 329 unsigned int rd : 5; 330 unsigned int rj : 5; 331 unsigned int immediate : 14; 332 unsigned int opcode : 8; 333 }; 334 335 struct reg2i16_format { 336 unsigned int rd : 5; 337 unsigned int rj : 5; 338 unsigned int immediate : 16; 339 unsigned int opcode : 6; 340 }; 341 342 struct reg2bstrd_format { 343 unsigned int rd : 5; 344 unsigned int rj : 5; 345 unsigned int lsbd : 6; 346 unsigned int msbd : 6; 347 unsigned int opcode : 10; 348 }; 349 350 struct reg2csr_format { 351 unsigned int rd : 5; 352 unsigned int rj : 5; 353 unsigned int csr : 14; 354 unsigned int opcode : 8; 355 }; 356 357 struct reg3_format { 358 unsigned int rd : 5; 359 unsigned int rj : 5; 360 unsigned int rk : 5; 361 unsigned int opcode : 17; 362 }; 363 364 struct reg3sa2_format { 365 unsigned int rd : 5; 366 unsigned int rj : 5; 367 unsigned int rk : 5; 368 unsigned int immediate : 2; 369 unsigned int opcode : 15; 370 }; 371 372 union loongarch_instruction { 373 unsigned int word; 374 struct reg0i15_format reg0i15_format; 375 struct reg0i26_format reg0i26_format; 376 struct reg1i20_format reg1i20_format; 377 struct reg1i21_format reg1i21_format; 378 struct reg2_format reg2_format; 379 struct reg2i5_format reg2i5_format; 380 struct reg2i6_format reg2i6_format; 381 struct reg2i12_format reg2i12_format; 382 struct reg2i14_format reg2i14_format; 383 struct reg2i16_format reg2i16_format; 384 struct reg2bstrd_format reg2bstrd_format; 385 struct reg2csr_format reg2csr_format; 386 struct reg3_format reg3_format; 387 struct reg3sa2_format reg3sa2_format; 388 }; 389 390 #define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction) 391 392 enum loongarch_gpr { 393 LOONGARCH_GPR_ZERO = 0, 394 LOONGARCH_GPR_RA = 1, 395 LOONGARCH_GPR_TP = 2, 396 LOONGARCH_GPR_SP = 3, 397 LOONGARCH_GPR_A0 = 4, /* Reused as V0 for return value */ 398 LOONGARCH_GPR_A1, /* Reused as V1 for return value */ 399 LOONGARCH_GPR_A2, 400 LOONGARCH_GPR_A3, 401 LOONGARCH_GPR_A4, 402 LOONGARCH_GPR_A5, 403 LOONGARCH_GPR_A6, 404 LOONGARCH_GPR_A7, 405 LOONGARCH_GPR_T0 = 12, 406 LOONGARCH_GPR_T1, 407 LOONGARCH_GPR_T2, 408 LOONGARCH_GPR_T3, 409 LOONGARCH_GPR_T4, 410 LOONGARCH_GPR_T5, 411 LOONGARCH_GPR_T6, 412 LOONGARCH_GPR_T7, 413 LOONGARCH_GPR_T8, 414 LOONGARCH_GPR_U0 = 21, /* Kernel per-CPU base register ($r21) */ 415 LOONGARCH_GPR_FP = 22, 416 LOONGARCH_GPR_S0 = 23, 417 LOONGARCH_GPR_S1, 418 LOONGARCH_GPR_S2, 419 LOONGARCH_GPR_S3, 420 LOONGARCH_GPR_S4, 421 LOONGARCH_GPR_S5, 422 LOONGARCH_GPR_S6, 423 LOONGARCH_GPR_S7, 424 LOONGARCH_GPR_S8, 425 LOONGARCH_GPR_MAX 426 }; 427 428 #define is_imm12_negative(val) is_imm_negative(val, 12) 429 430 static inline bool is_imm_negative(unsigned long val, unsigned int bit) 431 { 432 return val & (1UL << (bit - 1)); 433 } 434 435 static inline bool is_break_ins(union loongarch_instruction *ip) 436 { 437 return ip->reg0i15_format.opcode == break_op; 438 } 439 440 static inline bool is_pc_ins(union loongarch_instruction *ip) 441 { 442 return ip->reg1i20_format.opcode >= pcaddi_op && 443 ip->reg1i20_format.opcode <= pcaddu18i_op; 444 } 445 446 static inline bool is_branch_ins(union loongarch_instruction *ip) 447 { 448 return ip->reg1i21_format.opcode >= beqz_op && 449 ip->reg1i21_format.opcode <= bgeu_op; 450 } 451 452 static inline bool is_ra_save_ins(union loongarch_instruction *ip) 453 { 454 const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? stw_op : std_op; 455 456 /* st.w / st.d $ra, $sp, offset */ 457 return ip->reg2i12_format.opcode == opcode && 458 ip->reg2i12_format.rj == LOONGARCH_GPR_SP && 459 ip->reg2i12_format.rd == LOONGARCH_GPR_RA && 460 !is_imm12_negative(ip->reg2i12_format.immediate); 461 } 462 463 static inline bool is_stack_alloc_ins(union loongarch_instruction *ip) 464 { 465 const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? addiw_op : addid_op; 466 467 /* addi.w / addi.d $sp, $sp, -imm */ 468 return ip->reg2i12_format.opcode == opcode && 469 ip->reg2i12_format.rj == LOONGARCH_GPR_SP && 470 ip->reg2i12_format.rd == LOONGARCH_GPR_SP && 471 is_imm12_negative(ip->reg2i12_format.immediate); 472 } 473 474 static inline bool is_self_loop_ins(union loongarch_instruction *ip, struct pt_regs *regs) 475 { 476 switch (ip->reg0i26_format.opcode) { 477 case b_op: 478 case bl_op: 479 if (ip->reg0i26_format.immediate_l == 0 480 && ip->reg0i26_format.immediate_h == 0) 481 return true; 482 } 483 484 switch (ip->reg1i21_format.opcode) { 485 case beqz_op: 486 case bnez_op: 487 case bceqz_op: 488 if (ip->reg1i21_format.immediate_l == 0 489 && ip->reg1i21_format.immediate_h == 0) 490 return true; 491 } 492 493 switch (ip->reg2i16_format.opcode) { 494 case beq_op: 495 case bne_op: 496 case blt_op: 497 case bge_op: 498 case bltu_op: 499 case bgeu_op: 500 if (ip->reg2i16_format.immediate == 0) 501 return true; 502 break; 503 case jirl_op: 504 if (regs->regs[ip->reg2i16_format.rj] + 505 ((unsigned long)ip->reg2i16_format.immediate << 2) == (unsigned long)ip) 506 return true; 507 } 508 509 return false; 510 } 511 512 void simu_pc(struct pt_regs *regs, union loongarch_instruction insn); 513 void simu_branch(struct pt_regs *regs, union loongarch_instruction insn); 514 515 bool insns_not_supported(union loongarch_instruction insn); 516 bool insns_need_simulation(union loongarch_instruction insn); 517 void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs); 518 519 int larch_insn_read(void *addr, u32 *insnp); 520 int larch_insn_write(void *addr, u32 insn); 521 int larch_insn_patch_text(void *addr, u32 insn); 522 int larch_insn_text_copy(void *dst, void *src, size_t len); 523 524 u32 larch_insn_gen_nop(void); 525 u32 larch_insn_gen_b(unsigned long pc, unsigned long dest); 526 u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest); 527 528 u32 larch_insn_gen_break(int imm); 529 530 u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk); 531 u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj); 532 533 u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm); 534 u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); 535 u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); 536 u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); 537 u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); 538 u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); 539 540 static inline bool signed_imm_check(long val, unsigned int bit) 541 { 542 return -(1L << (bit - 1)) <= val && val < (1L << (bit - 1)); 543 } 544 545 static inline bool unsigned_imm_check(unsigned long val, unsigned int bit) 546 { 547 return val < (1UL << bit); 548 } 549 550 #define DEF_EMIT_REG0I15_FORMAT(NAME, OP) \ 551 static inline void emit_##NAME(union loongarch_instruction *insn, \ 552 int imm) \ 553 { \ 554 insn->reg0i15_format.opcode = OP; \ 555 insn->reg0i15_format.immediate = imm; \ 556 } 557 558 DEF_EMIT_REG0I15_FORMAT(break, break_op) 559 DEF_EMIT_REG0I15_FORMAT(dbar, dbar_op) 560 561 /* like emit_break(imm) but returns a constant expression */ 562 #define __emit_break(imm) ((u32)((imm) | (break_op << 15))) 563 564 #define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \ 565 static inline void emit_##NAME(union loongarch_instruction *insn, \ 566 int offset) \ 567 { \ 568 unsigned int immediate_l, immediate_h; \ 569 \ 570 immediate_l = offset & 0xffff; \ 571 offset >>= 16; \ 572 immediate_h = offset & 0x3ff; \ 573 \ 574 insn->reg0i26_format.opcode = OP; \ 575 insn->reg0i26_format.immediate_l = immediate_l; \ 576 insn->reg0i26_format.immediate_h = immediate_h; \ 577 } 578 579 DEF_EMIT_REG0I26_FORMAT(b, b_op) 580 DEF_EMIT_REG0I26_FORMAT(bl, bl_op) 581 582 #define DEF_EMIT_REG1I20_FORMAT(NAME, OP) \ 583 static inline void emit_##NAME(union loongarch_instruction *insn, \ 584 enum loongarch_gpr rd, int imm) \ 585 { \ 586 insn->reg1i20_format.opcode = OP; \ 587 insn->reg1i20_format.immediate = imm; \ 588 insn->reg1i20_format.rd = rd; \ 589 } 590 591 DEF_EMIT_REG1I20_FORMAT(lu12iw, lu12iw_op) 592 DEF_EMIT_REG1I20_FORMAT(lu32id, lu32id_op) 593 DEF_EMIT_REG1I20_FORMAT(pcaddu18i, pcaddu18i_op) 594 595 #define DEF_EMIT_REG2_FORMAT(NAME, OP) \ 596 static inline void emit_##NAME(union loongarch_instruction *insn, \ 597 enum loongarch_gpr rd, \ 598 enum loongarch_gpr rj) \ 599 { \ 600 insn->reg2_format.opcode = OP; \ 601 insn->reg2_format.rd = rd; \ 602 insn->reg2_format.rj = rj; \ 603 } 604 605 DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op) 606 DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op) 607 DEF_EMIT_REG2_FORMAT(revbd, revbd_op) 608 DEF_EMIT_REG2_FORMAT(extwh, extwh_op) 609 DEF_EMIT_REG2_FORMAT(extwb, extwb_op) 610 611 #define DEF_EMIT_REG2I5_FORMAT(NAME, OP) \ 612 static inline void emit_##NAME(union loongarch_instruction *insn, \ 613 enum loongarch_gpr rd, \ 614 enum loongarch_gpr rj, \ 615 int imm) \ 616 { \ 617 insn->reg2i5_format.opcode = OP; \ 618 insn->reg2i5_format.immediate = imm; \ 619 insn->reg2i5_format.rd = rd; \ 620 insn->reg2i5_format.rj = rj; \ 621 } 622 623 DEF_EMIT_REG2I5_FORMAT(slliw, slliw_op) 624 DEF_EMIT_REG2I5_FORMAT(srliw, srliw_op) 625 DEF_EMIT_REG2I5_FORMAT(sraiw, sraiw_op) 626 627 #define DEF_EMIT_REG2I6_FORMAT(NAME, OP) \ 628 static inline void emit_##NAME(union loongarch_instruction *insn, \ 629 enum loongarch_gpr rd, \ 630 enum loongarch_gpr rj, \ 631 int imm) \ 632 { \ 633 insn->reg2i6_format.opcode = OP; \ 634 insn->reg2i6_format.immediate = imm; \ 635 insn->reg2i6_format.rd = rd; \ 636 insn->reg2i6_format.rj = rj; \ 637 } 638 639 DEF_EMIT_REG2I6_FORMAT(sllid, sllid_op) 640 DEF_EMIT_REG2I6_FORMAT(srlid, srlid_op) 641 DEF_EMIT_REG2I6_FORMAT(sraid, sraid_op) 642 643 #define DEF_EMIT_REG2I12_FORMAT(NAME, OP) \ 644 static inline void emit_##NAME(union loongarch_instruction *insn, \ 645 enum loongarch_gpr rd, \ 646 enum loongarch_gpr rj, \ 647 int imm) \ 648 { \ 649 insn->reg2i12_format.opcode = OP; \ 650 insn->reg2i12_format.immediate = imm; \ 651 insn->reg2i12_format.rd = rd; \ 652 insn->reg2i12_format.rj = rj; \ 653 } 654 655 DEF_EMIT_REG2I12_FORMAT(sltui, sltui_op) 656 DEF_EMIT_REG2I12_FORMAT(addiw, addiw_op) 657 DEF_EMIT_REG2I12_FORMAT(addid, addid_op) 658 DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op) 659 DEF_EMIT_REG2I12_FORMAT(andi, andi_op) 660 DEF_EMIT_REG2I12_FORMAT(ori, ori_op) 661 DEF_EMIT_REG2I12_FORMAT(xori, xori_op) 662 DEF_EMIT_REG2I12_FORMAT(ldb, ldb_op) 663 DEF_EMIT_REG2I12_FORMAT(ldh, ldh_op) 664 DEF_EMIT_REG2I12_FORMAT(ldw, ldw_op) 665 DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op) 666 DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op) 667 DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op) 668 DEF_EMIT_REG2I12_FORMAT(ldd, ldd_op) 669 DEF_EMIT_REG2I12_FORMAT(stb, stb_op) 670 DEF_EMIT_REG2I12_FORMAT(sth, sth_op) 671 DEF_EMIT_REG2I12_FORMAT(stw, stw_op) 672 DEF_EMIT_REG2I12_FORMAT(std, std_op) 673 674 #define DEF_EMIT_REG2I14_FORMAT(NAME, OP) \ 675 static inline void emit_##NAME(union loongarch_instruction *insn, \ 676 enum loongarch_gpr rd, \ 677 enum loongarch_gpr rj, \ 678 int imm) \ 679 { \ 680 insn->reg2i14_format.opcode = OP; \ 681 insn->reg2i14_format.immediate = imm; \ 682 insn->reg2i14_format.rd = rd; \ 683 insn->reg2i14_format.rj = rj; \ 684 } 685 686 DEF_EMIT_REG2I14_FORMAT(llw, llw_op) 687 DEF_EMIT_REG2I14_FORMAT(scw, scw_op) 688 DEF_EMIT_REG2I14_FORMAT(lld, lld_op) 689 DEF_EMIT_REG2I14_FORMAT(scd, scd_op) 690 DEF_EMIT_REG2I14_FORMAT(ldptrw, ldptrw_op) 691 DEF_EMIT_REG2I14_FORMAT(stptrw, stptrw_op) 692 DEF_EMIT_REG2I14_FORMAT(ldptrd, ldptrd_op) 693 DEF_EMIT_REG2I14_FORMAT(stptrd, stptrd_op) 694 695 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP) \ 696 static inline void emit_##NAME(union loongarch_instruction *insn, \ 697 enum loongarch_gpr rj, \ 698 enum loongarch_gpr rd, \ 699 int offset) \ 700 { \ 701 insn->reg2i16_format.opcode = OP; \ 702 insn->reg2i16_format.immediate = offset; \ 703 insn->reg2i16_format.rj = rj; \ 704 insn->reg2i16_format.rd = rd; \ 705 } 706 707 DEF_EMIT_REG2I16_FORMAT(beq, beq_op) 708 DEF_EMIT_REG2I16_FORMAT(bne, bne_op) 709 DEF_EMIT_REG2I16_FORMAT(blt, blt_op) 710 DEF_EMIT_REG2I16_FORMAT(bge, bge_op) 711 DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op) 712 DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op) 713 714 static inline void emit_jirl(union loongarch_instruction *insn, 715 enum loongarch_gpr rd, 716 enum loongarch_gpr rj, 717 int offset) 718 { 719 insn->reg2i16_format.opcode = jirl_op; 720 insn->reg2i16_format.immediate = offset; 721 insn->reg2i16_format.rd = rd; 722 insn->reg2i16_format.rj = rj; 723 } 724 725 #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP) \ 726 static inline void emit_##NAME(union loongarch_instruction *insn, \ 727 enum loongarch_gpr rd, \ 728 enum loongarch_gpr rj, \ 729 int msbd, \ 730 int lsbd) \ 731 { \ 732 insn->reg2bstrd_format.opcode = OP; \ 733 insn->reg2bstrd_format.msbd = msbd; \ 734 insn->reg2bstrd_format.lsbd = lsbd; \ 735 insn->reg2bstrd_format.rj = rj; \ 736 insn->reg2bstrd_format.rd = rd; \ 737 } 738 739 DEF_EMIT_REG2BSTRD_FORMAT(bstrpickd, bstrpickd_op) 740 741 #define DEF_EMIT_REG3_FORMAT(NAME, OP) \ 742 static inline void emit_##NAME(union loongarch_instruction *insn, \ 743 enum loongarch_gpr rd, \ 744 enum loongarch_gpr rj, \ 745 enum loongarch_gpr rk) \ 746 { \ 747 insn->reg3_format.opcode = OP; \ 748 insn->reg3_format.rd = rd; \ 749 insn->reg3_format.rj = rj; \ 750 insn->reg3_format.rk = rk; \ 751 } 752 753 DEF_EMIT_REG3_FORMAT(addw, addw_op) 754 DEF_EMIT_REG3_FORMAT(addd, addd_op) 755 DEF_EMIT_REG3_FORMAT(subd, subd_op) 756 DEF_EMIT_REG3_FORMAT(muld, muld_op) 757 DEF_EMIT_REG3_FORMAT(divd, divd_op) 758 DEF_EMIT_REG3_FORMAT(modd, modd_op) 759 DEF_EMIT_REG3_FORMAT(divdu, divdu_op) 760 DEF_EMIT_REG3_FORMAT(moddu, moddu_op) 761 DEF_EMIT_REG3_FORMAT(maskeqz, maskeqz_op) 762 DEF_EMIT_REG3_FORMAT(masknez, masknez_op) 763 DEF_EMIT_REG3_FORMAT(and, and_op) 764 DEF_EMIT_REG3_FORMAT(or, or_op) 765 DEF_EMIT_REG3_FORMAT(xor, xor_op) 766 DEF_EMIT_REG3_FORMAT(sllw, sllw_op) 767 DEF_EMIT_REG3_FORMAT(slld, slld_op) 768 DEF_EMIT_REG3_FORMAT(srlw, srlw_op) 769 DEF_EMIT_REG3_FORMAT(srld, srld_op) 770 DEF_EMIT_REG3_FORMAT(sraw, sraw_op) 771 DEF_EMIT_REG3_FORMAT(srad, srad_op) 772 DEF_EMIT_REG3_FORMAT(ldxb, ldxb_op) 773 DEF_EMIT_REG3_FORMAT(ldxh, ldxh_op) 774 DEF_EMIT_REG3_FORMAT(ldxw, ldxw_op) 775 DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op) 776 DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op) 777 DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op) 778 DEF_EMIT_REG3_FORMAT(ldxd, ldxd_op) 779 DEF_EMIT_REG3_FORMAT(stxb, stxb_op) 780 DEF_EMIT_REG3_FORMAT(stxh, stxh_op) 781 DEF_EMIT_REG3_FORMAT(stxw, stxw_op) 782 DEF_EMIT_REG3_FORMAT(stxd, stxd_op) 783 DEF_EMIT_REG3_FORMAT(amaddb, amaddb_op) 784 DEF_EMIT_REG3_FORMAT(amaddh, amaddh_op) 785 DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op) 786 DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op) 787 DEF_EMIT_REG3_FORMAT(amandw, amandw_op) 788 DEF_EMIT_REG3_FORMAT(amandd, amandd_op) 789 DEF_EMIT_REG3_FORMAT(amorw, amorw_op) 790 DEF_EMIT_REG3_FORMAT(amord, amord_op) 791 DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op) 792 DEF_EMIT_REG3_FORMAT(amxord, amxord_op) 793 DEF_EMIT_REG3_FORMAT(amswapb, amswapb_op) 794 DEF_EMIT_REG3_FORMAT(amswaph, amswaph_op) 795 DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op) 796 DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op) 797 DEF_EMIT_REG3_FORMAT(amswapdbb, amswapdbb_op) 798 DEF_EMIT_REG3_FORMAT(amswapdbh, amswapdbh_op) 799 DEF_EMIT_REG3_FORMAT(amadddbb, amadddbb_op) 800 DEF_EMIT_REG3_FORMAT(amadddbh, amadddbh_op) 801 DEF_EMIT_REG3_FORMAT(amadddbw, amadddbw_op) 802 DEF_EMIT_REG3_FORMAT(amadddbd, amadddbd_op) 803 DEF_EMIT_REG3_FORMAT(amanddbw, amanddbw_op) 804 DEF_EMIT_REG3_FORMAT(amanddbd, amanddbd_op) 805 DEF_EMIT_REG3_FORMAT(amordbw, amordbw_op) 806 DEF_EMIT_REG3_FORMAT(amordbd, amordbd_op) 807 DEF_EMIT_REG3_FORMAT(amxordbw, amxordbw_op) 808 DEF_EMIT_REG3_FORMAT(amxordbd, amxordbd_op) 809 DEF_EMIT_REG3_FORMAT(amswapdbw, amswapdbw_op) 810 DEF_EMIT_REG3_FORMAT(amswapdbd, amswapdbd_op) 811 812 #define DEF_EMIT_REG3SA2_FORMAT(NAME, OP) \ 813 static inline void emit_##NAME(union loongarch_instruction *insn, \ 814 enum loongarch_gpr rd, \ 815 enum loongarch_gpr rj, \ 816 enum loongarch_gpr rk, \ 817 int imm) \ 818 { \ 819 insn->reg3sa2_format.opcode = OP; \ 820 insn->reg3sa2_format.immediate = imm; \ 821 insn->reg3sa2_format.rd = rd; \ 822 insn->reg3sa2_format.rj = rj; \ 823 insn->reg3sa2_format.rk = rk; \ 824 } 825 826 DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op) 827 828 struct pt_regs; 829 830 void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned int *pc); 831 unsigned long unaligned_read(void __user *addr, void *value, unsigned long n, bool sign); 832 unsigned long unaligned_write(void __user *addr, unsigned long value, unsigned long n); 833 834 #endif /* _ASM_INST_H */ 835