1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2020 SiFive 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #include <linux/bits.h> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun /* The bit field of immediate value in I-type instruction */ 9*4882a593Smuzhiyun #define I_IMM_SIGN_OPOFF 31 10*4882a593Smuzhiyun #define I_IMM_11_0_OPOFF 20 11*4882a593Smuzhiyun #define I_IMM_SIGN_OFF 12 12*4882a593Smuzhiyun #define I_IMM_11_0_OFF 0 13*4882a593Smuzhiyun #define I_IMM_11_0_MASK GENMASK(11, 0) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* The bit field of immediate value in J-type instruction */ 16*4882a593Smuzhiyun #define J_IMM_SIGN_OPOFF 31 17*4882a593Smuzhiyun #define J_IMM_10_1_OPOFF 21 18*4882a593Smuzhiyun #define J_IMM_11_OPOFF 20 19*4882a593Smuzhiyun #define J_IMM_19_12_OPOFF 12 20*4882a593Smuzhiyun #define J_IMM_SIGN_OFF 20 21*4882a593Smuzhiyun #define J_IMM_10_1_OFF 1 22*4882a593Smuzhiyun #define J_IMM_11_OFF 11 23*4882a593Smuzhiyun #define J_IMM_19_12_OFF 12 24*4882a593Smuzhiyun #define J_IMM_10_1_MASK GENMASK(9, 0) 25*4882a593Smuzhiyun #define J_IMM_11_MASK GENMASK(0, 0) 26*4882a593Smuzhiyun #define J_IMM_19_12_MASK GENMASK(7, 0) 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun /* The bit field of immediate value in B-type instruction */ 29*4882a593Smuzhiyun #define B_IMM_SIGN_OPOFF 31 30*4882a593Smuzhiyun #define B_IMM_10_5_OPOFF 25 31*4882a593Smuzhiyun #define B_IMM_4_1_OPOFF 8 32*4882a593Smuzhiyun #define B_IMM_11_OPOFF 7 33*4882a593Smuzhiyun #define B_IMM_SIGN_OFF 12 34*4882a593Smuzhiyun #define B_IMM_10_5_OFF 5 35*4882a593Smuzhiyun #define B_IMM_4_1_OFF 1 36*4882a593Smuzhiyun #define B_IMM_11_OFF 11 37*4882a593Smuzhiyun #define B_IMM_10_5_MASK GENMASK(5, 0) 38*4882a593Smuzhiyun #define B_IMM_4_1_MASK GENMASK(3, 0) 39*4882a593Smuzhiyun #define B_IMM_11_MASK GENMASK(0, 0) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* The register offset in RVG instruction */ 42*4882a593Smuzhiyun #define RVG_RS1_OPOFF 15 43*4882a593Smuzhiyun #define RVG_RS2_OPOFF 20 44*4882a593Smuzhiyun #define RVG_RD_OPOFF 7 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun /* The bit field of immediate value in RVC J instruction */ 47*4882a593Smuzhiyun #define RVC_J_IMM_SIGN_OPOFF 12 48*4882a593Smuzhiyun #define RVC_J_IMM_4_OPOFF 11 49*4882a593Smuzhiyun #define RVC_J_IMM_9_8_OPOFF 9 50*4882a593Smuzhiyun #define RVC_J_IMM_10_OPOFF 8 51*4882a593Smuzhiyun #define RVC_J_IMM_6_OPOFF 7 52*4882a593Smuzhiyun #define RVC_J_IMM_7_OPOFF 6 53*4882a593Smuzhiyun #define RVC_J_IMM_3_1_OPOFF 3 54*4882a593Smuzhiyun #define RVC_J_IMM_5_OPOFF 2 55*4882a593Smuzhiyun #define RVC_J_IMM_SIGN_OFF 11 56*4882a593Smuzhiyun #define RVC_J_IMM_4_OFF 4 57*4882a593Smuzhiyun #define RVC_J_IMM_9_8_OFF 8 58*4882a593Smuzhiyun #define RVC_J_IMM_10_OFF 10 59*4882a593Smuzhiyun #define RVC_J_IMM_6_OFF 6 60*4882a593Smuzhiyun #define RVC_J_IMM_7_OFF 7 61*4882a593Smuzhiyun #define RVC_J_IMM_3_1_OFF 1 62*4882a593Smuzhiyun #define RVC_J_IMM_5_OFF 5 63*4882a593Smuzhiyun #define RVC_J_IMM_4_MASK GENMASK(0, 0) 64*4882a593Smuzhiyun #define RVC_J_IMM_9_8_MASK GENMASK(1, 0) 65*4882a593Smuzhiyun #define RVC_J_IMM_10_MASK GENMASK(0, 0) 66*4882a593Smuzhiyun #define RVC_J_IMM_6_MASK GENMASK(0, 0) 67*4882a593Smuzhiyun #define RVC_J_IMM_7_MASK GENMASK(0, 0) 68*4882a593Smuzhiyun #define RVC_J_IMM_3_1_MASK GENMASK(2, 0) 69*4882a593Smuzhiyun #define RVC_J_IMM_5_MASK GENMASK(0, 0) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /* The bit field of immediate value in RVC B instruction */ 72*4882a593Smuzhiyun #define RVC_B_IMM_SIGN_OPOFF 12 73*4882a593Smuzhiyun #define RVC_B_IMM_4_3_OPOFF 10 74*4882a593Smuzhiyun #define RVC_B_IMM_7_6_OPOFF 5 75*4882a593Smuzhiyun #define RVC_B_IMM_2_1_OPOFF 3 76*4882a593Smuzhiyun #define RVC_B_IMM_5_OPOFF 2 77*4882a593Smuzhiyun #define RVC_B_IMM_SIGN_OFF 8 78*4882a593Smuzhiyun #define RVC_B_IMM_4_3_OFF 3 79*4882a593Smuzhiyun #define RVC_B_IMM_7_6_OFF 6 80*4882a593Smuzhiyun #define RVC_B_IMM_2_1_OFF 1 81*4882a593Smuzhiyun #define RVC_B_IMM_5_OFF 5 82*4882a593Smuzhiyun #define RVC_B_IMM_4_3_MASK GENMASK(1, 0) 83*4882a593Smuzhiyun #define RVC_B_IMM_7_6_MASK GENMASK(1, 0) 84*4882a593Smuzhiyun #define RVC_B_IMM_2_1_MASK GENMASK(1, 0) 85*4882a593Smuzhiyun #define RVC_B_IMM_5_MASK GENMASK(0, 0) 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /* The register offset in RVC op=C0 instruction */ 88*4882a593Smuzhiyun #define RVC_C0_RS1_OPOFF 7 89*4882a593Smuzhiyun #define RVC_C0_RS2_OPOFF 2 90*4882a593Smuzhiyun #define RVC_C0_RD_OPOFF 2 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /* The register offset in RVC op=C1 instruction */ 93*4882a593Smuzhiyun #define RVC_C1_RS1_OPOFF 7 94*4882a593Smuzhiyun #define RVC_C1_RS2_OPOFF 2 95*4882a593Smuzhiyun #define RVC_C1_RD_OPOFF 7 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /* The register offset in RVC op=C2 instruction */ 98*4882a593Smuzhiyun #define RVC_C2_RS1_OPOFF 7 99*4882a593Smuzhiyun #define RVC_C2_RS2_OPOFF 2 100*4882a593Smuzhiyun #define RVC_C2_RD_OPOFF 7 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* parts of opcode for RVG*/ 103*4882a593Smuzhiyun #define OPCODE_BRANCH 0x63 104*4882a593Smuzhiyun #define OPCODE_JALR 0x67 105*4882a593Smuzhiyun #define OPCODE_JAL 0x6f 106*4882a593Smuzhiyun #define OPCODE_SYSTEM 0x73 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /* parts of opcode for RVC*/ 109*4882a593Smuzhiyun #define OPCODE_C_0 0x0 110*4882a593Smuzhiyun #define OPCODE_C_1 0x1 111*4882a593Smuzhiyun #define OPCODE_C_2 0x2 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /* parts of funct3 code for I, M, A extension*/ 114*4882a593Smuzhiyun #define FUNCT3_JALR 0x0 115*4882a593Smuzhiyun #define FUNCT3_BEQ 0x0 116*4882a593Smuzhiyun #define FUNCT3_BNE 0x1000 117*4882a593Smuzhiyun #define FUNCT3_BLT 0x4000 118*4882a593Smuzhiyun #define FUNCT3_BGE 0x5000 119*4882a593Smuzhiyun #define FUNCT3_BLTU 0x6000 120*4882a593Smuzhiyun #define FUNCT3_BGEU 0x7000 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun /* parts of funct3 code for C extension*/ 123*4882a593Smuzhiyun #define FUNCT3_C_BEQZ 0xc000 124*4882a593Smuzhiyun #define FUNCT3_C_BNEZ 0xe000 125*4882a593Smuzhiyun #define FUNCT3_C_J 0xa000 126*4882a593Smuzhiyun #define FUNCT3_C_JAL 0x2000 127*4882a593Smuzhiyun #define FUNCT4_C_JR 0x8000 128*4882a593Smuzhiyun #define FUNCT4_C_JALR 0xf000 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun #define FUNCT12_SRET 0x10200000 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun #define MATCH_JALR (FUNCT3_JALR | OPCODE_JALR) 133*4882a593Smuzhiyun #define MATCH_JAL (OPCODE_JAL) 134*4882a593Smuzhiyun #define MATCH_BEQ (FUNCT3_BEQ | OPCODE_BRANCH) 135*4882a593Smuzhiyun #define MATCH_BNE (FUNCT3_BNE | OPCODE_BRANCH) 136*4882a593Smuzhiyun #define MATCH_BLT (FUNCT3_BLT | OPCODE_BRANCH) 137*4882a593Smuzhiyun #define MATCH_BGE (FUNCT3_BGE | OPCODE_BRANCH) 138*4882a593Smuzhiyun #define MATCH_BLTU (FUNCT3_BLTU | OPCODE_BRANCH) 139*4882a593Smuzhiyun #define MATCH_BGEU (FUNCT3_BGEU | OPCODE_BRANCH) 140*4882a593Smuzhiyun #define MATCH_SRET (FUNCT12_SRET | OPCODE_SYSTEM) 141*4882a593Smuzhiyun #define MATCH_C_BEQZ (FUNCT3_C_BEQZ | OPCODE_C_1) 142*4882a593Smuzhiyun #define MATCH_C_BNEZ (FUNCT3_C_BNEZ | OPCODE_C_1) 143*4882a593Smuzhiyun #define MATCH_C_J (FUNCT3_C_J | OPCODE_C_1) 144*4882a593Smuzhiyun #define MATCH_C_JAL (FUNCT3_C_JAL | OPCODE_C_1) 145*4882a593Smuzhiyun #define MATCH_C_JR (FUNCT4_C_JR | OPCODE_C_2) 146*4882a593Smuzhiyun #define MATCH_C_JALR (FUNCT4_C_JALR | OPCODE_C_2) 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun #define MASK_JALR 0x707f 149*4882a593Smuzhiyun #define MASK_JAL 0x7f 150*4882a593Smuzhiyun #define MASK_C_JALR 0xf07f 151*4882a593Smuzhiyun #define MASK_C_JR 0xf07f 152*4882a593Smuzhiyun #define MASK_C_JAL 0xe003 153*4882a593Smuzhiyun #define MASK_C_J 0xe003 154*4882a593Smuzhiyun #define MASK_BEQ 0x707f 155*4882a593Smuzhiyun #define MASK_BNE 0x707f 156*4882a593Smuzhiyun #define MASK_BLT 0x707f 157*4882a593Smuzhiyun #define MASK_BGE 0x707f 158*4882a593Smuzhiyun #define MASK_BLTU 0x707f 159*4882a593Smuzhiyun #define MASK_BGEU 0x707f 160*4882a593Smuzhiyun #define MASK_C_BEQZ 0xe003 161*4882a593Smuzhiyun #define MASK_C_BNEZ 0xe003 162*4882a593Smuzhiyun #define MASK_SRET 0xffffffff 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun #define __INSN_LENGTH_MASK _UL(0x3) 165*4882a593Smuzhiyun #define __INSN_LENGTH_GE_32 _UL(0x3) 166*4882a593Smuzhiyun #define __INSN_OPCODE_MASK _UL(0x7F) 167*4882a593Smuzhiyun #define __INSN_BRANCH_OPCODE _UL(OPCODE_BRANCH) 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun /* Define a series of is_XXX_insn functions to check if the value INSN 170*4882a593Smuzhiyun * is an instance of instruction XXX. 171*4882a593Smuzhiyun */ 172*4882a593Smuzhiyun #define DECLARE_INSN(INSN_NAME, INSN_MATCH, INSN_MASK) \ 173*4882a593Smuzhiyun static inline bool is_ ## INSN_NAME ## _insn(long insn) \ 174*4882a593Smuzhiyun { \ 175*4882a593Smuzhiyun return (insn & (INSN_MASK)) == (INSN_MATCH); \ 176*4882a593Smuzhiyun } 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun #define RV_IMM_SIGN(x) (-(((x) >> 31) & 1)) 179*4882a593Smuzhiyun #define RVC_IMM_SIGN(x) (-(((x) >> 12) & 1)) 180*4882a593Smuzhiyun #define RV_X(X, s, mask) (((X) >> (s)) & (mask)) 181*4882a593Smuzhiyun #define RVC_X(X, s, mask) RV_X(X, s, mask) 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun #define EXTRACT_JTYPE_IMM(x) \ 184*4882a593Smuzhiyun ({typeof(x) x_ = (x); \ 185*4882a593Smuzhiyun (RV_X(x_, J_IMM_10_1_OPOFF, J_IMM_10_1_MASK) << J_IMM_10_1_OFF) | \ 186*4882a593Smuzhiyun (RV_X(x_, J_IMM_11_OPOFF, J_IMM_11_MASK) << J_IMM_11_OFF) | \ 187*4882a593Smuzhiyun (RV_X(x_, J_IMM_19_12_OPOFF, J_IMM_19_12_MASK) << J_IMM_19_12_OFF) | \ 188*4882a593Smuzhiyun (RV_IMM_SIGN(x_) << J_IMM_SIGN_OFF); }) 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun #define EXTRACT_ITYPE_IMM(x) \ 191*4882a593Smuzhiyun ({typeof(x) x_ = (x); \ 192*4882a593Smuzhiyun (RV_X(x_, I_IMM_11_0_OPOFF, I_IMM_11_0_MASK)) | \ 193*4882a593Smuzhiyun (RV_IMM_SIGN(x_) << I_IMM_SIGN_OFF); }) 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun #define EXTRACT_BTYPE_IMM(x) \ 196*4882a593Smuzhiyun ({typeof(x) x_ = (x); \ 197*4882a593Smuzhiyun (RV_X(x_, B_IMM_4_1_OPOFF, B_IMM_4_1_MASK) << B_IMM_4_1_OFF) | \ 198*4882a593Smuzhiyun (RV_X(x_, B_IMM_10_5_OPOFF, B_IMM_10_5_MASK) << B_IMM_10_5_OFF) | \ 199*4882a593Smuzhiyun (RV_X(x_, B_IMM_11_OPOFF, B_IMM_11_MASK) << B_IMM_11_OFF) | \ 200*4882a593Smuzhiyun (RV_IMM_SIGN(x_) << B_IMM_SIGN_OFF); }) 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun #define EXTRACT_RVC_J_IMM(x) \ 203*4882a593Smuzhiyun ({typeof(x) x_ = (x); \ 204*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_MASK) << RVC_J_IMM_3_1_OFF) | \ 205*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_4_OPOFF, RVC_J_IMM_4_MASK) << RVC_J_IMM_4_OFF) | \ 206*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_5_OPOFF, RVC_J_IMM_5_MASK) << RVC_J_IMM_5_OFF) | \ 207*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_6_OPOFF, RVC_J_IMM_6_MASK) << RVC_J_IMM_6_OFF) | \ 208*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_7_OPOFF, RVC_J_IMM_7_MASK) << RVC_J_IMM_7_OFF) | \ 209*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_9_8_OPOFF, RVC_J_IMM_9_8_MASK) << RVC_J_IMM_9_8_OFF) | \ 210*4882a593Smuzhiyun (RVC_X(x_, RVC_J_IMM_10_OPOFF, RVC_J_IMM_10_MASK) << RVC_J_IMM_10_OFF) | \ 211*4882a593Smuzhiyun (RVC_IMM_SIGN(x_) << RVC_J_IMM_SIGN_OFF); }) 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun #define EXTRACT_RVC_B_IMM(x) \ 214*4882a593Smuzhiyun ({typeof(x) x_ = (x); \ 215*4882a593Smuzhiyun (RVC_X(x_, RVC_B_IMM_2_1_OPOFF, RVC_B_IMM_2_1_MASK) << RVC_B_IMM_2_1_OFF) | \ 216*4882a593Smuzhiyun (RVC_X(x_, RVC_B_IMM_4_3_OPOFF, RVC_B_IMM_4_3_MASK) << RVC_B_IMM_4_3_OFF) | \ 217*4882a593Smuzhiyun (RVC_X(x_, RVC_B_IMM_5_OPOFF, RVC_B_IMM_5_MASK) << RVC_B_IMM_5_OFF) | \ 218*4882a593Smuzhiyun (RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \ 219*4882a593Smuzhiyun (RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); }) 220