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 struct reg0i15_format { 55 unsigned int immediate : 15; 56 unsigned int opcode : 17; 57 }; 58 59 struct reg0i26_format { 60 unsigned int immediate_h : 10; 61 unsigned int immediate_l : 16; 62 unsigned int opcode : 6; 63 }; 64 65 struct reg1i21_format { 66 unsigned int immediate_h : 5; 67 unsigned int rj : 5; 68 unsigned int immediate_l : 16; 69 unsigned int opcode : 6; 70 }; 71 72 struct reg2_format { 73 unsigned int rd : 5; 74 unsigned int rj : 5; 75 unsigned int opcode : 22; 76 }; 77 78 struct reg2i12_format { 79 unsigned int rd : 5; 80 unsigned int rj : 5; 81 unsigned int immediate : 12; 82 unsigned int opcode : 10; 83 }; 84 85 struct reg2i14_format { 86 unsigned int rd : 5; 87 unsigned int rj : 5; 88 unsigned int immediate : 14; 89 unsigned int opcode : 8; 90 }; 91 92 struct reg2i16_format { 93 unsigned int rd : 5; 94 unsigned int rj : 5; 95 unsigned int immediate : 16; 96 unsigned int opcode : 6; 97 }; 98 99 union loongarch_instruction { 100 unsigned int word; 101 struct reg0i15_format reg0i15_format; 102 struct reg0i26_format reg0i26_format; 103 struct reg1i21_format reg1i21_format; 104 struct reg2_format reg2_format; 105 struct reg2i12_format reg2i12_format; 106 struct reg2i14_format reg2i14_format; 107 struct reg2i16_format reg2i16_format; 108 }; 109 110 #define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction) 111 112 enum loongarch_gpr { 113 LOONGARCH_GPR_ZERO = 0, 114 LOONGARCH_GPR_RA = 1, 115 LOONGARCH_GPR_TP = 2, 116 LOONGARCH_GPR_SP = 3, 117 LOONGARCH_GPR_A0 = 4, /* Reused as V0 for return value */ 118 LOONGARCH_GPR_A1, /* Reused as V1 for return value */ 119 LOONGARCH_GPR_A2, 120 LOONGARCH_GPR_A3, 121 LOONGARCH_GPR_A4, 122 LOONGARCH_GPR_A5, 123 LOONGARCH_GPR_A6, 124 LOONGARCH_GPR_A7, 125 LOONGARCH_GPR_T0 = 12, 126 LOONGARCH_GPR_T1, 127 LOONGARCH_GPR_T2, 128 LOONGARCH_GPR_T3, 129 LOONGARCH_GPR_T4, 130 LOONGARCH_GPR_T5, 131 LOONGARCH_GPR_T6, 132 LOONGARCH_GPR_T7, 133 LOONGARCH_GPR_T8, 134 LOONGARCH_GPR_FP = 22, 135 LOONGARCH_GPR_S0 = 23, 136 LOONGARCH_GPR_S1, 137 LOONGARCH_GPR_S2, 138 LOONGARCH_GPR_S3, 139 LOONGARCH_GPR_S4, 140 LOONGARCH_GPR_S5, 141 LOONGARCH_GPR_S6, 142 LOONGARCH_GPR_S7, 143 LOONGARCH_GPR_S8, 144 LOONGARCH_GPR_MAX 145 }; 146 147 #define DEF_EMIT_REG2I16_FORMAT(NAME, OP) \ 148 static inline void emit_##NAME(union loongarch_instruction *insn, \ 149 enum loongarch_gpr rj, \ 150 enum loongarch_gpr rd, \ 151 int offset) \ 152 { \ 153 insn->reg2i16_format.opcode = OP; \ 154 insn->reg2i16_format.immediate = offset; \ 155 insn->reg2i16_format.rj = rj; \ 156 insn->reg2i16_format.rd = rd; \ 157 } 158 159 DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op) 160 161 #endif /* _ASM_INST_H */ 162