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 10 #define LOONGARCH_INSN_NOP 0x03400000 11 12 enum reg0i15_op { 13 break_op = 0x54, 14 }; 15 16 enum reg0i26_op { 17 b_op = 0x14, 18 bl_op = 0x15, 19 }; 20 21 enum reg1i21_op { 22 beqz_op = 0x10, 23 bnez_op = 0x11, 24 bceqz_op = 0x12, /* bits[9:8] = 0x00 */ 25 bcnez_op = 0x12, /* bits[9:8] = 0x01 */ 26 }; 27 28 enum reg2_op { 29 ertn_op = 0x1920e, 30 }; 31 32 enum reg2i12_op { 33 addid_op = 0x0b, 34 andi_op = 0x0d, 35 ldd_op = 0xa3, 36 std_op = 0xa7, 37 }; 38 39 enum reg2i14_op { 40 ldptrd_op = 0x26, 41 stptrd_op = 0x27, 42 }; 43 44 enum reg2i16_op { 45 jirl_op = 0x13, 46 beq_op = 0x16, 47 bne_op = 0x17, 48 blt_op = 0x18, 49 bge_op = 0x19, 50 bltu_op = 0x1a, 51 bgeu_op = 0x1b, 52 }; 53 54 enum reg3_op { 55 amswapw_op = 0x70c0, 56 }; 57 58 struct reg0i15_format { 59 unsigned int immediate : 15; 60 unsigned int opcode : 17; 61 }; 62 63 struct reg0i26_format { 64 unsigned int immediate_h : 10; 65 unsigned int immediate_l : 16; 66 unsigned int opcode : 6; 67 }; 68 69 struct reg1i21_format { 70 unsigned int immediate_h : 5; 71 unsigned int rj : 5; 72 unsigned int immediate_l : 16; 73 unsigned int opcode : 6; 74 }; 75 76 struct reg2_format { 77 unsigned int rd : 5; 78 unsigned int rj : 5; 79 unsigned int opcode : 22; 80 }; 81 82 struct reg2i12_format { 83 unsigned int rd : 5; 84 unsigned int rj : 5; 85 unsigned int immediate : 12; 86 unsigned int opcode : 10; 87 }; 88 89 struct reg2i14_format { 90 unsigned int rd : 5; 91 unsigned int rj : 5; 92 unsigned int immediate : 14; 93 unsigned int opcode : 8; 94 }; 95 96 struct reg2i16_format { 97 unsigned int rd : 5; 98 unsigned int rj : 5; 99 unsigned int immediate : 16; 100 unsigned int opcode : 6; 101 }; 102 103 struct reg3_format { 104 unsigned int rd : 5; 105 unsigned int rj : 5; 106 unsigned int rk : 5; 107 unsigned int opcode : 17; 108 }; 109 110 union loongarch_instruction { 111 unsigned int word; 112 struct reg0i15_format reg0i15_format; 113 struct reg0i26_format reg0i26_format; 114 struct reg1i21_format reg1i21_format; 115 struct reg2_format reg2_format; 116 struct reg2i12_format reg2i12_format; 117 struct reg2i14_format reg2i14_format; 118 struct reg2i16_format reg2i16_format; 119 struct reg3_format reg3_format; 120 }; 121 122 #define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction) 123 124 enum loongarch_gpr { 125 LOONGARCH_GPR_ZERO = 0, 126 LOONGARCH_GPR_RA = 1, 127 LOONGARCH_GPR_TP = 2, 128 LOONGARCH_GPR_SP = 3, 129 LOONGARCH_GPR_A0 = 4, /* Reused as V0 for return value */ 130 LOONGARCH_GPR_A1, /* Reused as V1 for return value */ 131 LOONGARCH_GPR_A2, 132 LOONGARCH_GPR_A3, 133 LOONGARCH_GPR_A4, 134 LOONGARCH_GPR_A5, 135 LOONGARCH_GPR_A6, 136 LOONGARCH_GPR_A7, 137 LOONGARCH_GPR_T0 = 12, 138 LOONGARCH_GPR_T1, 139 LOONGARCH_GPR_T2, 140 LOONGARCH_GPR_T3, 141 LOONGARCH_GPR_T4, 142 LOONGARCH_GPR_T5, 143 LOONGARCH_GPR_T6, 144 LOONGARCH_GPR_T7, 145 LOONGARCH_GPR_T8, 146 LOONGARCH_GPR_FP = 22, 147 LOONGARCH_GPR_S0 = 23, 148 LOONGARCH_GPR_S1, 149 LOONGARCH_GPR_S2, 150 LOONGARCH_GPR_S3, 151 LOONGARCH_GPR_S4, 152 LOONGARCH_GPR_S5, 153 LOONGARCH_GPR_S6, 154 LOONGARCH_GPR_S7, 155 LOONGARCH_GPR_S8, 156 LOONGARCH_GPR_MAX 157 }; 158 159 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP) \ 160 static inline void emit_##NAME(union loongarch_instruction *insn, \ 161 enum loongarch_gpr rj, \ 162 enum loongarch_gpr rd, \ 163 int offset) \ 164 { \ 165 insn->reg2i16_format.opcode = OP; \ 166 insn->reg2i16_format.immediate = offset; \ 167 insn->reg2i16_format.rj = rj; \ 168 insn->reg2i16_format.rd = rd; \ 169 } 170 171 DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op) 172 173 #endif /* _ASM_INST_H */ 174