1*1f154020SRobert Mustacchi /* 2*1f154020SRobert Mustacchi * This file and its contents are supplied under the terms of the 3*1f154020SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 4*1f154020SRobert Mustacchi * You may only use this file in accordance with the terms of version 5*1f154020SRobert Mustacchi * 1.0 of the CDDL. 6*1f154020SRobert Mustacchi * 7*1f154020SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 8*1f154020SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 9*1f154020SRobert Mustacchi * http://www.illumos.org/license/CDDL. 10*1f154020SRobert Mustacchi */ 11*1f154020SRobert Mustacchi 12*1f154020SRobert Mustacchi /* 13*1f154020SRobert Mustacchi * Copyright (c) 2018, Joyent, Inc. 14*1f154020SRobert Mustacchi */ 15*1f154020SRobert Mustacchi 16*1f154020SRobert Mustacchi /* 17*1f154020SRobert Mustacchi * RISC-V Instruction set decoder 18*1f154020SRobert Mustacchi */ 19*1f154020SRobert Mustacchi 20*1f154020SRobert Mustacchi #include <libdisasm.h> 21*1f154020SRobert Mustacchi #include <sys/byteorder.h> 22*1f154020SRobert Mustacchi #include <sys/debug.h> 23*1f154020SRobert Mustacchi 24*1f154020SRobert Mustacchi #include "libdisasm_impl.h" 25*1f154020SRobert Mustacchi 26*1f154020SRobert Mustacchi #include <stdio.h> 27*1f154020SRobert Mustacchi 28*1f154020SRobert Mustacchi extern int strcmp(const char *, const char *); 29*1f154020SRobert Mustacchi 30*1f154020SRobert Mustacchi /* 31*1f154020SRobert Mustacchi * Register names based on their ABI name. 32*1f154020SRobert Mustacchi */ 33*1f154020SRobert Mustacchi static const char *dis_riscv_regs[32] = { 34*1f154020SRobert Mustacchi "x0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", 35*1f154020SRobert Mustacchi "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", 36*1f154020SRobert Mustacchi "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", 37*1f154020SRobert Mustacchi "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" 38*1f154020SRobert Mustacchi }; 39*1f154020SRobert Mustacchi 40*1f154020SRobert Mustacchi static const char *dis_riscv_fpregs[32] = { 41*1f154020SRobert Mustacchi "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", 42*1f154020SRobert Mustacchi "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", 43*1f154020SRobert Mustacchi "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", 44*1f154020SRobert Mustacchi "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11", 45*1f154020SRobert Mustacchi }; 46*1f154020SRobert Mustacchi 47*1f154020SRobert Mustacchi static const char *dis_riscv_c_regs[8] = { 48*1f154020SRobert Mustacchi "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5" 49*1f154020SRobert Mustacchi }; 50*1f154020SRobert Mustacchi 51*1f154020SRobert Mustacchi static const char *dis_riscv_c_fpregs[8] = { 52*1f154020SRobert Mustacchi "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5" 53*1f154020SRobert Mustacchi }; 54*1f154020SRobert Mustacchi 55*1f154020SRobert Mustacchi /* 56*1f154020SRobert Mustacchi * RM names have the leading comma in them because the last value represents 57*1f154020SRobert Mustacchi * that the hardware register decides the rounding mode and therefore nothing 58*1f154020SRobert Mustacchi * should be appended to the instruction. 59*1f154020SRobert Mustacchi */ 60*1f154020SRobert Mustacchi static const char *dis_riscv_rm[8] = { 61*1f154020SRobert Mustacchi ",rne", ",rtz", ",rdn", ",rup", ",rmm", ",???", ",???", "" 62*1f154020SRobert Mustacchi }; 63*1f154020SRobert Mustacchi 64*1f154020SRobert Mustacchi typedef struct dis_riscv_csr { 65*1f154020SRobert Mustacchi uint_t drc_val; 66*1f154020SRobert Mustacchi const char *drc_name; 67*1f154020SRobert Mustacchi } dis_riscv_csr_t; 68*1f154020SRobert Mustacchi 69*1f154020SRobert Mustacchi /* 70*1f154020SRobert Mustacchi * The current set of CSR names as per Table 2.2-2.5 from RISC-V Privileged 71*1f154020SRobert Mustacchi * Architectures V1.10. These include all of the ones in the User-Level ISA. 72*1f154020SRobert Mustacchi * These are ordered per the doc. 73*1f154020SRobert Mustacchi */ 74*1f154020SRobert Mustacchi static dis_riscv_csr_t dis_riscv_csr_map[] = { 75*1f154020SRobert Mustacchi /* User Trap */ 76*1f154020SRobert Mustacchi { 0x000, "ustatus" }, { 0x004, "uie" }, { 0x005, "utvec" }, 77*1f154020SRobert Mustacchi /* User Trap Handling */ 78*1f154020SRobert Mustacchi { 0x040, "uscratch" }, { 0x041, "uepc" }, { 0x042, "ucause" }, 79*1f154020SRobert Mustacchi { 0x043, "utval" }, { 0x044, "uip" }, 80*1f154020SRobert Mustacchi /* User Floating-Point CSRs */ 81*1f154020SRobert Mustacchi { 0x001, "fflags" }, { 0x002, "frm" }, { 0x003, "fcsr" }, 82*1f154020SRobert Mustacchi /* User Counters/Timers */ 83*1f154020SRobert Mustacchi { 0xc00, "cycle" }, { 0xc01, "time" }, { 0xc02, "instret" }, 84*1f154020SRobert Mustacchi { 0xc03, "hpmcounter3" }, { 0xc04, "hpmcounter4" }, 85*1f154020SRobert Mustacchi { 0xc05, "hpmcounter5" }, { 0xc06, "hpmcounter6" }, 86*1f154020SRobert Mustacchi { 0xc07, "hpmcounter7" }, { 0xc08, "hpmcounter8" }, 87*1f154020SRobert Mustacchi { 0xc09, "hpmcounter9" }, { 0xc0a, "hpmcounter10" }, 88*1f154020SRobert Mustacchi { 0xc0b, "hpmcounter11" }, { 0xc0c, "hpmcounter12" }, 89*1f154020SRobert Mustacchi { 0xc0d, "hpmcounter13" }, { 0xc0e, "hpmcounter14" }, 90*1f154020SRobert Mustacchi { 0xc0f, "hpmcounter15" }, { 0xc10, "hpmcounter16" }, 91*1f154020SRobert Mustacchi { 0xc11, "hpmcounter17" }, { 0xc12, "hpmcounter18" }, 92*1f154020SRobert Mustacchi { 0xc13, "hpmcounter19" }, { 0xc14, "hpmcounter20" }, 93*1f154020SRobert Mustacchi { 0xc15, "hpmcounter21" }, { 0xc16, "hpmcounter22" }, 94*1f154020SRobert Mustacchi { 0xc17, "hpmcounter23" }, { 0xc18, "hpmcounter24" }, 95*1f154020SRobert Mustacchi { 0xc19, "hpmcounter25" }, { 0xc1a, "hpmcounter26" }, 96*1f154020SRobert Mustacchi { 0xc1b, "hpmcounter27" }, { 0xc1c, "hpmcounter28" }, 97*1f154020SRobert Mustacchi { 0xc1d, "hpmcounter29" }, { 0xc1e, "hpmcounter30" }, 98*1f154020SRobert Mustacchi { 0xc1f, "hpmcounter31" }, 99*1f154020SRobert Mustacchi { 0xc80, "cycleh" }, { 0xc81, "timeh" }, { 0xc82, "instreth" }, 100*1f154020SRobert Mustacchi { 0xc83, "hpmcounter3h" }, { 0xc84, "hpmcounter4h" }, 101*1f154020SRobert Mustacchi { 0xc85, "hpmcounter5h" }, { 0xc86, "hpmcounter6h" }, 102*1f154020SRobert Mustacchi { 0xc87, "hpmcounter7h" }, { 0xc88, "hpmcounter8h" }, 103*1f154020SRobert Mustacchi { 0xc89, "hpmcounter9h" }, { 0xc8a, "hpmcounter10h" }, 104*1f154020SRobert Mustacchi { 0xc8b, "hpmcounter11h" }, { 0xc8c, "hpmcounter12h" }, 105*1f154020SRobert Mustacchi { 0xc8d, "hpmcounter13h" }, { 0xc8e, "hpmcounter14h" }, 106*1f154020SRobert Mustacchi { 0xc8f, "hpmcounter15h" }, { 0xc90, "hpmcounter16h" }, 107*1f154020SRobert Mustacchi { 0xc91, "hpmcounter17h" }, { 0xc92, "hpmcounter18h" }, 108*1f154020SRobert Mustacchi { 0xc93, "hpmcounter19h" }, { 0xc94, "hpmcounter20h" }, 109*1f154020SRobert Mustacchi { 0xc95, "hpmcounter21h" }, { 0xc96, "hpmcounter22h" }, 110*1f154020SRobert Mustacchi { 0xc97, "hpmcounter23h" }, { 0xc98, "hpmcounter24h" }, 111*1f154020SRobert Mustacchi { 0xc99, "hpmcounter25h" }, { 0xc9a, "hpmcounter26h" }, 112*1f154020SRobert Mustacchi { 0xc9b, "hpmcounter27h" }, { 0xc9c, "hpmcounter28h" }, 113*1f154020SRobert Mustacchi { 0xc9d, "hpmcounter29h" }, { 0xc9e, "hpmcounter30h" }, 114*1f154020SRobert Mustacchi { 0xc9f, "hpmcounter31h" }, 115*1f154020SRobert Mustacchi /* Supervisor Trap Status */ 116*1f154020SRobert Mustacchi { 0x100, "sstatus" }, { 0x102, "sedeleg" }, { 0x103, "sideleg" }, 117*1f154020SRobert Mustacchi { 0x104, "sie" }, { 0x105, "stvec" }, { 0x106, "scounteren" }, 118*1f154020SRobert Mustacchi /* Supervisor Trap Handling */ 119*1f154020SRobert Mustacchi { 0x140, "sscratch" }, { 0x141, "sepc" }, { 0x142, "scause" }, 120*1f154020SRobert Mustacchi { 0x143, "stval" }, { 0x144, "sip" }, 121*1f154020SRobert Mustacchi /* Supervisor Protection and Translation */ 122*1f154020SRobert Mustacchi { 0x180, "satp" }, 123*1f154020SRobert Mustacchi /* Machine Information Registers */ 124*1f154020SRobert Mustacchi { 0xf11, "mvendorid" }, { 0xf12, "marchid" }, 125*1f154020SRobert Mustacchi { 0xf13, "mimpid" }, { 0xf14, "mhartid" }, 126*1f154020SRobert Mustacchi /* Machine Trap Setup */ 127*1f154020SRobert Mustacchi { 0x300, "mstatus" }, { 0x301, "misa" }, { 0x302, "medeleg" }, 128*1f154020SRobert Mustacchi { 0x303, "mideleg" }, { 0x304, "mie" }, { 0x305, "mtvec" }, 129*1f154020SRobert Mustacchi { 0x306, "mcounteren" }, 130*1f154020SRobert Mustacchi /* Machine Trap Handling */ 131*1f154020SRobert Mustacchi { 0x340, "mscratch" }, { 0x341, "mepc" }, { 0x342, "mcause" }, 132*1f154020SRobert Mustacchi { 0x343, "mtval" }, { 0x344, "mip" }, 133*1f154020SRobert Mustacchi /* Machine Protection and Translation */ 134*1f154020SRobert Mustacchi { 0x3a0, "pmpcfg0" }, { 0x3a1, "pmpcfg1" }, 135*1f154020SRobert Mustacchi { 0x3a2, "pmpcfg2" }, { 0x3a3, "pmpcfg3" }, 136*1f154020SRobert Mustacchi { 0x3b0, "pmpaddr0" }, { 0x3b1, "pmpaddr1" }, 137*1f154020SRobert Mustacchi { 0x3b2, "pmpaddr2" }, { 0x3b3, "pmpaddr3" }, 138*1f154020SRobert Mustacchi { 0x3b4, "pmpaddr4" }, { 0x3b5, "pmpaddr5" }, 139*1f154020SRobert Mustacchi { 0x3b6, "pmpaddr6" }, { 0x3b7, "pmpaddr7" }, 140*1f154020SRobert Mustacchi { 0x3b8, "pmpaddr8" }, { 0x3b9, "pmpaddr9" }, 141*1f154020SRobert Mustacchi { 0x3ba, "pmpaddr10" }, { 0x3bb, "pmpaddr11" }, 142*1f154020SRobert Mustacchi { 0x3bc, "pmpaddr12" }, { 0x3bd, "pmpaddr13" }, 143*1f154020SRobert Mustacchi { 0x3be, "pmpaddr14" }, { 0x3bf, "pmpaddr15" } 144*1f154020SRobert Mustacchi }; 145*1f154020SRobert Mustacchi 146*1f154020SRobert Mustacchi typedef enum dis_riscv_csr_alias_type { 147*1f154020SRobert Mustacchi DIS_RISCV_CSR_READ, 148*1f154020SRobert Mustacchi DIS_RISCV_CSR_READ_GEN, 149*1f154020SRobert Mustacchi DIS_RISCV_CSR_SWAP, 150*1f154020SRobert Mustacchi DIS_RISCV_CSR_SWAP_IMM, 151*1f154020SRobert Mustacchi DIS_RISCV_CSR_WRITE, 152*1f154020SRobert Mustacchi DIS_RISCV_CSR_WRITE_GEN, 153*1f154020SRobert Mustacchi DIS_RISCV_CSR_WRITE_IMM, 154*1f154020SRobert Mustacchi DIS_RISCV_CSR_WRITE_IMM_GEN 155*1f154020SRobert Mustacchi } dis_riscv_csr_alias_type_t; 156*1f154020SRobert Mustacchi 157*1f154020SRobert Mustacchi typedef struct dis_riscv_csr_alias { 158*1f154020SRobert Mustacchi const char *drca_alias; 159*1f154020SRobert Mustacchi dis_riscv_csr_alias_type_t drca_type; 160*1f154020SRobert Mustacchi const char *drca_base; 161*1f154020SRobert Mustacchi const char *drca_csr; 162*1f154020SRobert Mustacchi int drca_rd; 163*1f154020SRobert Mustacchi int drca_rs; 164*1f154020SRobert Mustacchi } dis_riscv_csr_alias_t; 165*1f154020SRobert Mustacchi 166*1f154020SRobert Mustacchi /* 167*1f154020SRobert Mustacchi * Table of aliases. A NULL or -1 indicates a don't care. 168*1f154020SRobert Mustacchi */ 169*1f154020SRobert Mustacchi static dis_riscv_csr_alias_t dis_riscv_csr_alias[] = { 170*1f154020SRobert Mustacchi { "rdinstret", DIS_RISCV_CSR_READ, "csrrs", "instret", -1, 0 }, 171*1f154020SRobert Mustacchi { "rdinstreth", DIS_RISCV_CSR_READ, "csrrs", "instreth", -1, 0 }, 172*1f154020SRobert Mustacchi { "rdcycle", DIS_RISCV_CSR_READ, "csrrs", "cycle", -1, 0 }, 173*1f154020SRobert Mustacchi { "rdcycleh", DIS_RISCV_CSR_READ, "csrrs", "cycleh", -1, 0 }, 174*1f154020SRobert Mustacchi { "rdtime", DIS_RISCV_CSR_READ, "csrrs", "time", -1, 0 }, 175*1f154020SRobert Mustacchi { "rdtimeh", DIS_RISCV_CSR_READ, "csrrs", "timeh", -1, 0 }, 176*1f154020SRobert Mustacchi { "frcsr", DIS_RISCV_CSR_READ, "csrrs", "fcsr", -1, 0 }, 177*1f154020SRobert Mustacchi { "fscsr", DIS_RISCV_CSR_WRITE, "csrrw", "fcsr", 0, -1 }, 178*1f154020SRobert Mustacchi { "fscsr", DIS_RISCV_CSR_SWAP, "csrrw", "fcsr", -1, -1 }, 179*1f154020SRobert Mustacchi { "frrm", DIS_RISCV_CSR_READ, "csrrs", "frm", -1, 0 }, 180*1f154020SRobert Mustacchi { "fsrm", DIS_RISCV_CSR_WRITE, "csrrw", "frm", 0, -1 }, 181*1f154020SRobert Mustacchi { "fsrm", DIS_RISCV_CSR_SWAP, "csrrw", "frm", -1, -1 }, 182*1f154020SRobert Mustacchi { "fsrmi", DIS_RISCV_CSR_WRITE_IMM, "csrrwi", "frm", 0, -1 }, 183*1f154020SRobert Mustacchi { "fsrmi", DIS_RISCV_CSR_SWAP_IMM, "csrrwi", "frm", -1, -1 }, 184*1f154020SRobert Mustacchi { "frflags", DIS_RISCV_CSR_READ, "csrrs", "fflags", -1, 0 }, 185*1f154020SRobert Mustacchi { "fsflags", DIS_RISCV_CSR_WRITE, "csrrw", "fflags", 0, -1 }, 186*1f154020SRobert Mustacchi { "fsflags", DIS_RISCV_CSR_SWAP, "csrrw", "fflags", -1, -1 }, 187*1f154020SRobert Mustacchi { "fsflagsi", DIS_RISCV_CSR_WRITE_IMM, "csrrwi", "fflags", 0, -1 }, 188*1f154020SRobert Mustacchi { "fsflagsi", DIS_RISCV_CSR_SWAP_IMM, "csrrwi", "fflags", -1, -1 }, 189*1f154020SRobert Mustacchi /* 190*1f154020SRobert Mustacchi * These are the generic aliases that aren't based on the CSR. Keep 191*1f154020SRobert Mustacchi * them last. 192*1f154020SRobert Mustacchi */ 193*1f154020SRobert Mustacchi { "csrr", DIS_RISCV_CSR_READ_GEN, "csrrs", NULL, -1, 0 }, 194*1f154020SRobert Mustacchi { "csrw", DIS_RISCV_CSR_WRITE_GEN, "csrrw", NULL, 0, -1 }, 195*1f154020SRobert Mustacchi { "csrs", DIS_RISCV_CSR_WRITE_GEN, "csrrs", NULL, 0, -1 }, 196*1f154020SRobert Mustacchi { "csrc", DIS_RISCV_CSR_WRITE_GEN, "csrrc", NULL, 0, -1 }, 197*1f154020SRobert Mustacchi { "csrwi", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrwi", NULL, 0, -1 }, 198*1f154020SRobert Mustacchi { "csrsi", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrsi", NULL, 0, -1 }, 199*1f154020SRobert Mustacchi { "csrci", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrci", NULL, 0, -1 }, 200*1f154020SRobert Mustacchi }; 201*1f154020SRobert Mustacchi 202*1f154020SRobert Mustacchi /* 203*1f154020SRobert Mustacchi * Take an n-bit value whose sign bit is indicated by the big sign and convert 204*1f154020SRobert Mustacchi * to a signed type. 205*1f154020SRobert Mustacchi */ 206*1f154020SRobert Mustacchi static uint_t 207*1f154020SRobert Mustacchi dis_riscv_sign_extend(uint_t val, uint_t sbit, const char **sign) 208*1f154020SRobert Mustacchi { 209*1f154020SRobert Mustacchi VERIFY3U(sbit, <=, 31); 210*1f154020SRobert Mustacchi 211*1f154020SRobert Mustacchi if (val >= 1 << sbit) { 212*1f154020SRobert Mustacchi *sign = "-"; 213*1f154020SRobert Mustacchi return ((1 << (sbit + 1)) - val); 214*1f154020SRobert Mustacchi } else { 215*1f154020SRobert Mustacchi *sign = ""; 216*1f154020SRobert Mustacchi return (val); 217*1f154020SRobert Mustacchi } 218*1f154020SRobert Mustacchi } 219*1f154020SRobert Mustacchi 220*1f154020SRobert Mustacchi /* 221*1f154020SRobert Mustacchi * Four byte decode tables. This is derived from the RV32/64G Instruction Set 222*1f154020SRobert Mustacchi * Listings. We describe a table entry based on the opcode and optional opcodes 223*1f154020SRobert Mustacchi * based on the type of instruction that it is and its encoding format. Most 224*1f154020SRobert Mustacchi * sets of instructions have one of several uniform encoding types. 225*1f154020SRobert Mustacchi * 226*1f154020SRobert Mustacchi * 31 25 24 20 19 15 14 12 11 7 6 0 227*1f154020SRobert Mustacchi * | funct7 | r2 | rs1 | funct3 | rd | opcode | R-type 228*1f154020SRobert Mustacchi * | imm[11:0] | rs1 | funct3 | rd | opcode | I-type 229*1f154020SRobert Mustacchi * | imm[11:5] | r2 | rs1 | funct3 | imm[4:0] | opcode | S-type 230*1f154020SRobert Mustacchi * | imm[12|10:5] | r2 | rs1 | funct3 | imm[4:1|11] | opcode | B-type 231*1f154020SRobert Mustacchi * | imm[31:12] | rd | opcode | U-type 232*1f154020SRobert Mustacchi * | imm[10|10:1|11|19:12] | rd | opcode | J-type 233*1f154020SRobert Mustacchi */ 234*1f154020SRobert Mustacchi typedef enum dis_riscv_itype { 235*1f154020SRobert Mustacchi DIS_RISCV_I_R_TYPE, 236*1f154020SRobert Mustacchi DIS_RISCV_I_I_TYPE, 237*1f154020SRobert Mustacchi DIS_RISCV_I_S_TYPE, 238*1f154020SRobert Mustacchi DIS_RISCV_I_B_TYPE, 239*1f154020SRobert Mustacchi DIS_RISCV_I_U_TYPE, 240*1f154020SRobert Mustacchi DIS_RISCV_I_J_TYPE, 241*1f154020SRobert Mustacchi DIS_RISCV_I_R4_TYPE, 242*1f154020SRobert Mustacchi /* 243*1f154020SRobert Mustacchi * This is a variant of the standard R type where the first bit of 244*1f154020SRobert Mustacchi * funct7 is actually used for this shift. 245*1f154020SRobert Mustacchi */ 246*1f154020SRobert Mustacchi DIS_RISCV_I_SHIFT64_TYPE, 247*1f154020SRobert Mustacchi /* 248*1f154020SRobert Mustacchi * This type isn't explicitly defined in the ISA doc; however, it is a 249*1f154020SRobert Mustacchi * standard format that is for all of the Atomic class instructions. 250*1f154020SRobert Mustacchi * This is treated like an R-type, except the funct7 is really a funct5. 251*1f154020SRobert Mustacchi * The load variant is similar; however, rs2 must be zero. 252*1f154020SRobert Mustacchi */ 253*1f154020SRobert Mustacchi DIS_RISCV_I_RV32A_TYPE, 254*1f154020SRobert Mustacchi DIS_RISCV_I_RV32A_LOAD_TYPE, 255*1f154020SRobert Mustacchi /* 256*1f154020SRobert Mustacchi * This is a custom type we've defined where the first value is the 257*1f154020SRobert Mustacchi * instruction mask and the second value is the value of the bits in it. 258*1f154020SRobert Mustacchi * This is used for a few irregular instructions ala FENCE and ECALL. 259*1f154020SRobert Mustacchi */ 260*1f154020SRobert Mustacchi DIS_RISCV_I_MASK_TYPE, 261*1f154020SRobert Mustacchi /* 262*1f154020SRobert Mustacchi * This type is used for FP arguments that use rs2 as an opcode. 263*1f154020SRobert Mustacchi */ 264*1f154020SRobert Mustacchi DIS_RISCV_I_FP_RS2OP_TYPE, 265*1f154020SRobert Mustacchi /* 266*1f154020SRobert Mustacchi * This type uses the opcode and funct7 and uses funct3 as a rounding 267*1f154020SRobert Mustacchi * mode argument. 268*1f154020SRobert Mustacchi */ 269*1f154020SRobert Mustacchi DIS_RISCV_I_FP_RM_TYPE, 270*1f154020SRobert Mustacchi /* 271*1f154020SRobert Mustacchi * This fp type uses the opcode, funct7, funct3, and rs2 as an op type. 272*1f154020SRobert Mustacchi */ 273*1f154020SRobert Mustacchi DIS_RISCV_I_FP_R_RS2_TYPE, 274*1f154020SRobert Mustacchi } dis_riscv_itype_t; 275*1f154020SRobert Mustacchi 276*1f154020SRobert Mustacchi #define DIS_RISCV_OPCODE(x) ((x) & 0x7f) 277*1f154020SRobert Mustacchi #define DIS_RISCV_FUNCT3(x) (((x) >> 12) & 0x7) 278*1f154020SRobert Mustacchi #define DIS_RISCV_FUNCT7(x) (((x) >> 25) & 0x7f) 279*1f154020SRobert Mustacchi #define DIS_RISCV_RD(x) (((x) >> 7) & 0x1f) 280*1f154020SRobert Mustacchi #define DIS_RISCV_RS1(x) (((x) >> 15) & 0x1f) 281*1f154020SRobert Mustacchi #define DIS_RISCV_RS2(x) (((x) >> 20) & 0x1f) 282*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS3(x) (((x) >> 27) & 0x1f) 283*1f154020SRobert Mustacchi #define DIS_RISCV_FUNCT2(x) (((x) >> 25) & 0x03) 284*1f154020SRobert Mustacchi 285*1f154020SRobert Mustacchi /* 286*1f154020SRobert Mustacchi * SHIFT funct7 variant. 287*1f154020SRobert Mustacchi */ 288*1f154020SRobert Mustacchi #define DIS_RISCV_SFUNCT7(x) (((x) >> 26) & 0x3f) 289*1f154020SRobert Mustacchi 290*1f154020SRobert Mustacchi #define DIS_RISCV_UIMM(x) (((x) >> 12) & 0xfffff) 291*1f154020SRobert Mustacchi 292*1f154020SRobert Mustacchi #define DIS_RISCV_IIMM(x) (((x) >> 20) & 0xfff) 293*1f154020SRobert Mustacchi 294*1f154020SRobert Mustacchi #define DIS_RISCV_BIMM_12(x) (((x) >> 19) & 0x1000) 295*1f154020SRobert Mustacchi #define DIS_RISCV_BIMM_11(x) (((x) & 0x80) << 4) 296*1f154020SRobert Mustacchi #define DIS_RISCV_BIMM_10_5(x) (((x) >> 20) & 0x7e0) 297*1f154020SRobert Mustacchi #define DIS_RISCV_BIMM_4_1(x) (((x) >> 7) & 0x1e) 298*1f154020SRobert Mustacchi 299*1f154020SRobert Mustacchi #define DIS_RISCV_SIMM_UP(x) ((((x) >> 25) & 0x7f) << 5) 300*1f154020SRobert Mustacchi #define DIS_RISCV_SIMM_LOW(x) (((x) >> 7) & 0x1f) 301*1f154020SRobert Mustacchi 302*1f154020SRobert Mustacchi #define DIS_RISCV_JIMM_20(x) (((x) & 0x80000000) >> 11) 303*1f154020SRobert Mustacchi #define DIS_RISCV_JIMM_19_12(x) ((x) & 0xff000) 304*1f154020SRobert Mustacchi #define DIS_RISCV_JIMM_11(x) (((x) & 100000) >> 9) 305*1f154020SRobert Mustacchi #define DIS_RISCV_JIMM_10_1(x) (((x) & 0x7fe00000) >> 20) 306*1f154020SRobert Mustacchi 307*1f154020SRobert Mustacchi #define DIS_RISCV_RVA_FUNCT5(x) (((x) >> 27) & 0x1f) 308*1f154020SRobert Mustacchi #define DIS_RISCV_RVA_AQ(x) (((x) >> 26) & 0x1) 309*1f154020SRobert Mustacchi #define DIS_RISCV_RVA_RL(x) (((x) >> 25) & 0x1) 310*1f154020SRobert Mustacchi 311*1f154020SRobert Mustacchi struct dis_riscv_instr; 312*1f154020SRobert Mustacchi typedef void (*dis_riscv_func_t)(dis_handle_t *, uint32_t, 313*1f154020SRobert Mustacchi struct dis_riscv_instr *, char *, size_t); 314*1f154020SRobert Mustacchi 315*1f154020SRobert Mustacchi typedef struct dis_riscv_instr { 316*1f154020SRobert Mustacchi const char *drv_name; 317*1f154020SRobert Mustacchi dis_riscv_itype_t drv_type; 318*1f154020SRobert Mustacchi dis_riscv_func_t drv_print; 319*1f154020SRobert Mustacchi uint_t drv_opcode; 320*1f154020SRobert Mustacchi uint_t drv_funct3; 321*1f154020SRobert Mustacchi uint_t drv_funct7; 322*1f154020SRobert Mustacchi uint_t drv_funct2; 323*1f154020SRobert Mustacchi } dis_riscv_instr_t; 324*1f154020SRobert Mustacchi 325*1f154020SRobert Mustacchi /*ARGSUSED*/ 326*1f154020SRobert Mustacchi static void 327*1f154020SRobert Mustacchi dis_riscv_rtype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 328*1f154020SRobert Mustacchi char *buf, size_t buflen) 329*1f154020SRobert Mustacchi { 330*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, 331*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RD(instr)], 332*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], 333*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS2(instr)]); 334*1f154020SRobert Mustacchi } 335*1f154020SRobert Mustacchi 336*1f154020SRobert Mustacchi static void 337*1f154020SRobert Mustacchi dis_riscv_itype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 338*1f154020SRobert Mustacchi char *buf, size_t buflen) 339*1f154020SRobert Mustacchi { 340*1f154020SRobert Mustacchi const char *s; 341*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); 342*1f154020SRobert Mustacchi 343*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 344*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0%o", 345*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 346*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); 347*1f154020SRobert Mustacchi } else { 348*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0x%x", 349*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 350*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); 351*1f154020SRobert Mustacchi } 352*1f154020SRobert Mustacchi } 353*1f154020SRobert Mustacchi 354*1f154020SRobert Mustacchi static void 355*1f154020SRobert Mustacchi dis_riscv_btype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 356*1f154020SRobert Mustacchi char *buf, size_t buflen) 357*1f154020SRobert Mustacchi { 358*1f154020SRobert Mustacchi const char *s; 359*1f154020SRobert Mustacchi uint_t bimm = DIS_RISCV_BIMM_12(instr) | DIS_RISCV_BIMM_11(instr) | 360*1f154020SRobert Mustacchi DIS_RISCV_BIMM_10_5(instr) | DIS_RISCV_BIMM_4_1(instr); 361*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(bimm, 12, &s); 362*1f154020SRobert Mustacchi 363*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 364*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0%o", 365*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 366*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); 367*1f154020SRobert Mustacchi } else { 368*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0x%x", 369*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 370*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); 371*1f154020SRobert Mustacchi } 372*1f154020SRobert Mustacchi } 373*1f154020SRobert Mustacchi 374*1f154020SRobert Mustacchi static void 375*1f154020SRobert Mustacchi dis_riscv_load(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 376*1f154020SRobert Mustacchi char *buf, size_t buflen) 377*1f154020SRobert Mustacchi { 378*1f154020SRobert Mustacchi const char *s; 379*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); 380*1f154020SRobert Mustacchi 381*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 382*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", 383*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 384*1f154020SRobert Mustacchi s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 385*1f154020SRobert Mustacchi } else { 386*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", 387*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 388*1f154020SRobert Mustacchi s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 389*1f154020SRobert Mustacchi } 390*1f154020SRobert Mustacchi } 391*1f154020SRobert Mustacchi 392*1f154020SRobert Mustacchi static void 393*1f154020SRobert Mustacchi dis_riscv_stype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 394*1f154020SRobert Mustacchi char *buf, size_t buflen) 395*1f154020SRobert Mustacchi { 396*1f154020SRobert Mustacchi const char *s; 397*1f154020SRobert Mustacchi uint_t simm = DIS_RISCV_SIMM_UP(instr) | DIS_RISCV_SIMM_LOW(instr); 398*1f154020SRobert Mustacchi uint_t val = dis_riscv_sign_extend(simm, 11, &s); 399*1f154020SRobert Mustacchi 400*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 401*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", 402*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RS2(instr)], 403*1f154020SRobert Mustacchi s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 404*1f154020SRobert Mustacchi } else { 405*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", 406*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RS2(instr)], 407*1f154020SRobert Mustacchi s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 408*1f154020SRobert Mustacchi } 409*1f154020SRobert Mustacchi } 410*1f154020SRobert Mustacchi 411*1f154020SRobert Mustacchi /*ARGSUSED*/ 412*1f154020SRobert Mustacchi static void 413*1f154020SRobert Mustacchi dis_riscv_utype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 414*1f154020SRobert Mustacchi char *buf, size_t buflen) 415*1f154020SRobert Mustacchi { 416*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0x%x", table->drv_name, 417*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RD(instr)], DIS_RISCV_UIMM(instr)); 418*1f154020SRobert Mustacchi } 419*1f154020SRobert Mustacchi 420*1f154020SRobert Mustacchi static void 421*1f154020SRobert Mustacchi dis_riscv_jtype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 422*1f154020SRobert Mustacchi char *buf, size_t buflen) 423*1f154020SRobert Mustacchi { 424*1f154020SRobert Mustacchi const char *s; 425*1f154020SRobert Mustacchi uint_t jimm = DIS_RISCV_JIMM_20(instr) | DIS_RISCV_JIMM_19_12(instr) | 426*1f154020SRobert Mustacchi DIS_RISCV_JIMM_11(instr) | DIS_RISCV_JIMM_10_1(instr); 427*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(jimm, 20, &s); 428*1f154020SRobert Mustacchi 429*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 430*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o", 431*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 432*1f154020SRobert Mustacchi s, imm); 433*1f154020SRobert Mustacchi } else { 434*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x", 435*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 436*1f154020SRobert Mustacchi s, imm); 437*1f154020SRobert Mustacchi } 438*1f154020SRobert Mustacchi } 439*1f154020SRobert Mustacchi 440*1f154020SRobert Mustacchi /* 441*1f154020SRobert Mustacchi * The shift instructions are a variant on the R-type instructions where RS2 is 442*1f154020SRobert Mustacchi * an immediate to perform the shift by as opposed to a register. 443*1f154020SRobert Mustacchi */ 444*1f154020SRobert Mustacchi static void 445*1f154020SRobert Mustacchi dis_riscv_shift_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 446*1f154020SRobert Mustacchi char *buf, size_t buflen) 447*1f154020SRobert Mustacchi { 448*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 449*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", 450*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 451*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], DIS_RISCV_RS2(instr)); 452*1f154020SRobert Mustacchi } else { 453*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", 454*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 455*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], DIS_RISCV_RS2(instr)); 456*1f154020SRobert Mustacchi } 457*1f154020SRobert Mustacchi } 458*1f154020SRobert Mustacchi 459*1f154020SRobert Mustacchi /* 460*1f154020SRobert Mustacchi * The 64-bit version of shift instructions steals an extra bit from funct7 to 461*1f154020SRobert Mustacchi * construct the shift amount. 462*1f154020SRobert Mustacchi */ 463*1f154020SRobert Mustacchi static void 464*1f154020SRobert Mustacchi dis_riscv_shift_64(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 465*1f154020SRobert Mustacchi char *buf, size_t buflen) 466*1f154020SRobert Mustacchi { 467*1f154020SRobert Mustacchi uint_t shift = DIS_RISCV_RS2(instr) | ((instr & (1UL << 25)) >> 20); 468*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 469*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", 470*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 471*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], shift); 472*1f154020SRobert Mustacchi } else { 473*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", 474*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], 475*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], shift); 476*1f154020SRobert Mustacchi } 477*1f154020SRobert Mustacchi } 478*1f154020SRobert Mustacchi 479*1f154020SRobert Mustacchi /*ARGSUSED*/ 480*1f154020SRobert Mustacchi static void 481*1f154020SRobert Mustacchi dis_riscv_csr(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 482*1f154020SRobert Mustacchi char *buf, size_t buflen) 483*1f154020SRobert Mustacchi { 484*1f154020SRobert Mustacchi uint_t rd, csr, rs, i; 485*1f154020SRobert Mustacchi const char *csrstr = NULL; 486*1f154020SRobert Mustacchi char csrval[32]; 487*1f154020SRobert Mustacchi dis_riscv_csr_alias_t *alias = NULL; 488*1f154020SRobert Mustacchi 489*1f154020SRobert Mustacchi rd = DIS_RISCV_RD(instr); 490*1f154020SRobert Mustacchi rs = DIS_RISCV_RS1(instr); 491*1f154020SRobert Mustacchi csr = DIS_RISCV_IIMM(instr); 492*1f154020SRobert Mustacchi 493*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_map); i++) { 494*1f154020SRobert Mustacchi if (csr == dis_riscv_csr_map[i].drc_val) { 495*1f154020SRobert Mustacchi csrstr = dis_riscv_csr_map[i].drc_name; 496*1f154020SRobert Mustacchi break; 497*1f154020SRobert Mustacchi } 498*1f154020SRobert Mustacchi } 499*1f154020SRobert Mustacchi 500*1f154020SRobert Mustacchi if (csrstr == NULL) { 501*1f154020SRobert Mustacchi (void) dis_snprintf(csrval, sizeof (csrval), "0x%x", csr); 502*1f154020SRobert Mustacchi csrstr = csrval; 503*1f154020SRobert Mustacchi } 504*1f154020SRobert Mustacchi 505*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_alias); i++) { 506*1f154020SRobert Mustacchi dis_riscv_csr_alias_t *a = &dis_riscv_csr_alias[i]; 507*1f154020SRobert Mustacchi if (strcmp(a->drca_base, table->drv_name) != 0) 508*1f154020SRobert Mustacchi continue; 509*1f154020SRobert Mustacchi if (a->drca_csr != NULL && strcmp(a->drca_csr, csrstr) != 0) 510*1f154020SRobert Mustacchi continue; 511*1f154020SRobert Mustacchi if (a->drca_rd != -1 && a->drca_rd != rd) 512*1f154020SRobert Mustacchi continue; 513*1f154020SRobert Mustacchi if (a->drca_rs != -1 && a->drca_rs != rs) 514*1f154020SRobert Mustacchi continue; 515*1f154020SRobert Mustacchi alias = a; 516*1f154020SRobert Mustacchi break; 517*1f154020SRobert Mustacchi } 518*1f154020SRobert Mustacchi 519*1f154020SRobert Mustacchi if (alias == NULL) { 520*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, 521*1f154020SRobert Mustacchi dis_riscv_regs[rd], csrstr, dis_riscv_regs[rs]); 522*1f154020SRobert Mustacchi return; 523*1f154020SRobert Mustacchi } 524*1f154020SRobert Mustacchi 525*1f154020SRobert Mustacchi switch (alias->drca_type) { 526*1f154020SRobert Mustacchi case DIS_RISCV_CSR_READ: 527*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s", alias->drca_alias, 528*1f154020SRobert Mustacchi dis_riscv_regs[rd]); 529*1f154020SRobert Mustacchi break; 530*1f154020SRobert Mustacchi case DIS_RISCV_CSR_READ_GEN: 531*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, 532*1f154020SRobert Mustacchi dis_riscv_regs[rd], csrstr); 533*1f154020SRobert Mustacchi break; 534*1f154020SRobert Mustacchi case DIS_RISCV_CSR_SWAP: 535*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, 536*1f154020SRobert Mustacchi dis_riscv_regs[rd], dis_riscv_regs[rs]); 537*1f154020SRobert Mustacchi break; 538*1f154020SRobert Mustacchi case DIS_RISCV_CSR_WRITE: 539*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s", alias->drca_alias, 540*1f154020SRobert Mustacchi dis_riscv_regs[rs]); 541*1f154020SRobert Mustacchi break; 542*1f154020SRobert Mustacchi case DIS_RISCV_CSR_WRITE_GEN: 543*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, 544*1f154020SRobert Mustacchi csrstr, dis_riscv_regs[rs]); 545*1f154020SRobert Mustacchi break; 546*1f154020SRobert Mustacchi default: 547*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "<unknown>"); 548*1f154020SRobert Mustacchi break; 549*1f154020SRobert Mustacchi } 550*1f154020SRobert Mustacchi } 551*1f154020SRobert Mustacchi 552*1f154020SRobert Mustacchi static void 553*1f154020SRobert Mustacchi dis_riscv_csri(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 554*1f154020SRobert Mustacchi char *buf, size_t buflen) 555*1f154020SRobert Mustacchi { 556*1f154020SRobert Mustacchi uint_t rd, csr, imm, i; 557*1f154020SRobert Mustacchi const char *csrstr = NULL; 558*1f154020SRobert Mustacchi char csrval[32]; 559*1f154020SRobert Mustacchi dis_riscv_csr_alias_t *alias = NULL; 560*1f154020SRobert Mustacchi 561*1f154020SRobert Mustacchi rd = DIS_RISCV_RD(instr); 562*1f154020SRobert Mustacchi imm = DIS_RISCV_RS1(instr); 563*1f154020SRobert Mustacchi csr = DIS_RISCV_IIMM(instr); 564*1f154020SRobert Mustacchi 565*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_map); i++) { 566*1f154020SRobert Mustacchi if (csr == dis_riscv_csr_map[i].drc_val) { 567*1f154020SRobert Mustacchi csrstr = dis_riscv_csr_map[i].drc_name; 568*1f154020SRobert Mustacchi break; 569*1f154020SRobert Mustacchi } 570*1f154020SRobert Mustacchi } 571*1f154020SRobert Mustacchi 572*1f154020SRobert Mustacchi if (csrstr == NULL) { 573*1f154020SRobert Mustacchi (void) dis_snprintf(csrval, sizeof (csrval), "0x%x", csr); 574*1f154020SRobert Mustacchi csrstr = csrval; 575*1f154020SRobert Mustacchi } 576*1f154020SRobert Mustacchi 577*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_alias); i++) { 578*1f154020SRobert Mustacchi dis_riscv_csr_alias_t *a = &dis_riscv_csr_alias[i]; 579*1f154020SRobert Mustacchi if (strcmp(a->drca_base, table->drv_name) != 0) 580*1f154020SRobert Mustacchi continue; 581*1f154020SRobert Mustacchi if (a->drca_csr != NULL && strcmp(a->drca_csr, csrstr) != 0) 582*1f154020SRobert Mustacchi continue; 583*1f154020SRobert Mustacchi if (a->drca_rd != -1 && a->drca_rd != rd) 584*1f154020SRobert Mustacchi continue; 585*1f154020SRobert Mustacchi if (a->drca_rs != -1) 586*1f154020SRobert Mustacchi continue; 587*1f154020SRobert Mustacchi alias = a; 588*1f154020SRobert Mustacchi break; 589*1f154020SRobert Mustacchi } 590*1f154020SRobert Mustacchi 591*1f154020SRobert Mustacchi if (alias == NULL) { 592*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 593*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", 594*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[rd], csrstr, imm); 595*1f154020SRobert Mustacchi } else { 596*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", 597*1f154020SRobert Mustacchi table->drv_name, dis_riscv_regs[rd], csrstr, imm); 598*1f154020SRobert Mustacchi } 599*1f154020SRobert Mustacchi return; 600*1f154020SRobert Mustacchi } 601*1f154020SRobert Mustacchi 602*1f154020SRobert Mustacchi switch (alias->drca_type) { 603*1f154020SRobert Mustacchi case DIS_RISCV_CSR_SWAP_IMM: 604*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 605*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0%o", 606*1f154020SRobert Mustacchi alias->drca_alias, dis_riscv_regs[rd], imm); 607*1f154020SRobert Mustacchi } else { 608*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0x%x", 609*1f154020SRobert Mustacchi alias->drca_alias, dis_riscv_regs[rd], imm); 610*1f154020SRobert Mustacchi } 611*1f154020SRobert Mustacchi break; 612*1f154020SRobert Mustacchi case DIS_RISCV_CSR_WRITE_IMM: 613*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 614*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s 0%o", 615*1f154020SRobert Mustacchi alias->drca_alias, imm); 616*1f154020SRobert Mustacchi } else { 617*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s 0x%x", 618*1f154020SRobert Mustacchi alias->drca_alias, imm); 619*1f154020SRobert Mustacchi } 620*1f154020SRobert Mustacchi break; 621*1f154020SRobert Mustacchi case DIS_RISCV_CSR_WRITE_IMM_GEN: 622*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 623*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0%o", 624*1f154020SRobert Mustacchi alias->drca_alias, csrstr, imm); 625*1f154020SRobert Mustacchi } else { 626*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0x%x", 627*1f154020SRobert Mustacchi alias->drca_alias, csrstr, imm); 628*1f154020SRobert Mustacchi } 629*1f154020SRobert Mustacchi break; 630*1f154020SRobert Mustacchi default: 631*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "<unknown>"); 632*1f154020SRobert Mustacchi break; 633*1f154020SRobert Mustacchi } 634*1f154020SRobert Mustacchi } 635*1f154020SRobert Mustacchi 636*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_PRED(x) (((x) >> 24) & 0xf) 637*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_SUCC(x) (((x) >> 20) & 0xf) 638*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_I 0x8 639*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_O 0x4 640*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_R 0x2 641*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_W 0x1 642*1f154020SRobert Mustacchi #define DIS_RISCV_FENCE_IORW 0xf 643*1f154020SRobert Mustacchi 644*1f154020SRobert Mustacchi /*ARGSUSED*/ 645*1f154020SRobert Mustacchi static void 646*1f154020SRobert Mustacchi dis_riscv_fence(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 647*1f154020SRobert Mustacchi char *buf, size_t buflen) 648*1f154020SRobert Mustacchi { 649*1f154020SRobert Mustacchi uint_t pred, succ; 650*1f154020SRobert Mustacchi 651*1f154020SRobert Mustacchi pred = DIS_RISCV_FENCE_PRED(instr); 652*1f154020SRobert Mustacchi succ = DIS_RISCV_FENCE_SUCC(instr); 653*1f154020SRobert Mustacchi 654*1f154020SRobert Mustacchi /* 655*1f154020SRobert Mustacchi * If both halves are iorw that is aliased to just an empty fence 656*1f154020SRobert Mustacchi * instruction per Chapter 20 - RISC-V Assembly Programmer's Handbook in 657*1f154020SRobert Mustacchi * the RISC-V user spec. 658*1f154020SRobert Mustacchi */ 659*1f154020SRobert Mustacchi if (pred == DIS_RISCV_FENCE_IORW && succ == DIS_RISCV_FENCE_IORW) { 660*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s", table->drv_name); 661*1f154020SRobert Mustacchi return; 662*1f154020SRobert Mustacchi } 663*1f154020SRobert Mustacchi 664*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s%s%s%s, %s%s%s%s", 665*1f154020SRobert Mustacchi table->drv_name, 666*1f154020SRobert Mustacchi pred & DIS_RISCV_FENCE_I ? "i" : "", 667*1f154020SRobert Mustacchi pred & DIS_RISCV_FENCE_O ? "o" : "", 668*1f154020SRobert Mustacchi pred & DIS_RISCV_FENCE_R ? "r" : "", 669*1f154020SRobert Mustacchi pred & DIS_RISCV_FENCE_W ? "w" : "", 670*1f154020SRobert Mustacchi succ & DIS_RISCV_FENCE_I ? "i" : "", 671*1f154020SRobert Mustacchi succ & DIS_RISCV_FENCE_O ? "o" : "", 672*1f154020SRobert Mustacchi succ & DIS_RISCV_FENCE_R ? "r" : "", 673*1f154020SRobert Mustacchi succ & DIS_RISCV_FENCE_W ? "w" : ""); 674*1f154020SRobert Mustacchi } 675*1f154020SRobert Mustacchi 676*1f154020SRobert Mustacchi /*ARGSUSED*/ 677*1f154020SRobert Mustacchi static void 678*1f154020SRobert Mustacchi dis_riscv_name(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 679*1f154020SRobert Mustacchi char *buf, size_t buflen) 680*1f154020SRobert Mustacchi { 681*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s", table->drv_name); 682*1f154020SRobert Mustacchi } 683*1f154020SRobert Mustacchi 684*1f154020SRobert Mustacchi /*ARGSUSED*/ 685*1f154020SRobert Mustacchi static void 686*1f154020SRobert Mustacchi dis_riscv_rs1_rs2(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 687*1f154020SRobert Mustacchi char *buf, size_t buflen) 688*1f154020SRobert Mustacchi { 689*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, 690*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], 691*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS2(instr)]); 692*1f154020SRobert Mustacchi } 693*1f154020SRobert Mustacchi 694*1f154020SRobert Mustacchi /*ARGSUSED*/ 695*1f154020SRobert Mustacchi static void 696*1f154020SRobert Mustacchi dis_riscv_rv32a_load(dis_handle_t *dhp, uint32_t instr, 697*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 698*1f154020SRobert Mustacchi { 699*1f154020SRobert Mustacchi const char *suffix = ""; 700*1f154020SRobert Mustacchi 701*1f154020SRobert Mustacchi if (DIS_RISCV_RVA_AQ(instr) && DIS_RISCV_RVA_RL(instr)) { 702*1f154020SRobert Mustacchi suffix = ".aqrl"; 703*1f154020SRobert Mustacchi } else if (DIS_RISCV_RVA_AQ(instr)) { 704*1f154020SRobert Mustacchi suffix = ".aq"; 705*1f154020SRobert Mustacchi } else if (DIS_RISCV_RVA_RL(instr)) { 706*1f154020SRobert Mustacchi suffix = ".rl"; 707*1f154020SRobert Mustacchi } 708*1f154020SRobert Mustacchi 709*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s%s %s,(%s)", table->drv_name, 710*1f154020SRobert Mustacchi suffix, dis_riscv_regs[DIS_RISCV_RD(instr)], 711*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)]); 712*1f154020SRobert Mustacchi } 713*1f154020SRobert Mustacchi 714*1f154020SRobert Mustacchi /*ARGSUSED*/ 715*1f154020SRobert Mustacchi static void 716*1f154020SRobert Mustacchi dis_riscv_rv32a(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 717*1f154020SRobert Mustacchi char *buf, size_t buflen) 718*1f154020SRobert Mustacchi { 719*1f154020SRobert Mustacchi const char *suffix = ""; 720*1f154020SRobert Mustacchi 721*1f154020SRobert Mustacchi if (DIS_RISCV_RVA_AQ(instr) && DIS_RISCV_RVA_RL(instr)) { 722*1f154020SRobert Mustacchi suffix = ".aqrl"; 723*1f154020SRobert Mustacchi } else if (DIS_RISCV_RVA_AQ(instr)) { 724*1f154020SRobert Mustacchi suffix = ".aq"; 725*1f154020SRobert Mustacchi } else if (DIS_RISCV_RVA_RL(instr)) { 726*1f154020SRobert Mustacchi suffix = ".rl"; 727*1f154020SRobert Mustacchi } 728*1f154020SRobert Mustacchi 729*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s%s %s,%s,(%s)", table->drv_name, 730*1f154020SRobert Mustacchi suffix, dis_riscv_regs[DIS_RISCV_RD(instr)], 731*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS2(instr)], 732*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)]); 733*1f154020SRobert Mustacchi } 734*1f154020SRobert Mustacchi 735*1f154020SRobert Mustacchi static void 736*1f154020SRobert Mustacchi dis_riscv_fp_load(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 737*1f154020SRobert Mustacchi char *buf, size_t buflen) 738*1f154020SRobert Mustacchi { 739*1f154020SRobert Mustacchi const char *s; 740*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); 741*1f154020SRobert Mustacchi 742*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 743*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", 744*1f154020SRobert Mustacchi table->drv_name, dis_riscv_fpregs[DIS_RISCV_RD(instr)], 745*1f154020SRobert Mustacchi s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 746*1f154020SRobert Mustacchi } else { 747*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", 748*1f154020SRobert Mustacchi table->drv_name, dis_riscv_fpregs[DIS_RISCV_RD(instr)], 749*1f154020SRobert Mustacchi s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 750*1f154020SRobert Mustacchi } 751*1f154020SRobert Mustacchi } 752*1f154020SRobert Mustacchi 753*1f154020SRobert Mustacchi static void 754*1f154020SRobert Mustacchi dis_riscv_fp_store(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 755*1f154020SRobert Mustacchi char *buf, size_t buflen) 756*1f154020SRobert Mustacchi { 757*1f154020SRobert Mustacchi const char *s; 758*1f154020SRobert Mustacchi uint_t simm = DIS_RISCV_SIMM_UP(instr) | DIS_RISCV_SIMM_LOW(instr); 759*1f154020SRobert Mustacchi uint_t val = dis_riscv_sign_extend(simm, 11, &s); 760*1f154020SRobert Mustacchi 761*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 762*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", 763*1f154020SRobert Mustacchi table->drv_name, dis_riscv_fpregs[DIS_RISCV_RS2(instr)], 764*1f154020SRobert Mustacchi s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 765*1f154020SRobert Mustacchi } else { 766*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", 767*1f154020SRobert Mustacchi table->drv_name, dis_riscv_fpregs[DIS_RISCV_RS2(instr)], 768*1f154020SRobert Mustacchi s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); 769*1f154020SRobert Mustacchi } 770*1f154020SRobert Mustacchi } 771*1f154020SRobert Mustacchi 772*1f154020SRobert Mustacchi /*ARGSUSED*/ 773*1f154020SRobert Mustacchi static void 774*1f154020SRobert Mustacchi dis_riscv_fp_r(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 775*1f154020SRobert Mustacchi char *buf, size_t buflen) 776*1f154020SRobert Mustacchi { 777*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, 778*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 779*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 780*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS2(instr)]); 781*1f154020SRobert Mustacchi } 782*1f154020SRobert Mustacchi 783*1f154020SRobert Mustacchi /* 784*1f154020SRobert Mustacchi * Variant of fp_r type that goes to integer destination registers. 785*1f154020SRobert Mustacchi */ 786*1f154020SRobert Mustacchi /*ARGSUSED*/ 787*1f154020SRobert Mustacchi static void 788*1f154020SRobert Mustacchi dis_riscv_fp_r_fpi(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 789*1f154020SRobert Mustacchi char *buf, size_t buflen) 790*1f154020SRobert Mustacchi { 791*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, 792*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RD(instr)], 793*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 794*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS2(instr)]); 795*1f154020SRobert Mustacchi } 796*1f154020SRobert Mustacchi 797*1f154020SRobert Mustacchi /*ARGSUSED*/ 798*1f154020SRobert Mustacchi static void 799*1f154020SRobert Mustacchi dis_riscv_fp_r4(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 800*1f154020SRobert Mustacchi char *buf, size_t buflen) 801*1f154020SRobert Mustacchi { 802*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s,%s%s", table->drv_name, 803*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 804*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 805*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS2(instr)], 806*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_FP_RS3(instr)], 807*1f154020SRobert Mustacchi dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); 808*1f154020SRobert Mustacchi } 809*1f154020SRobert Mustacchi 810*1f154020SRobert Mustacchi /*ARGSUSED*/ 811*1f154020SRobert Mustacchi static void 812*1f154020SRobert Mustacchi dis_riscv_fp_rs2_fp(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, 813*1f154020SRobert Mustacchi char *buf, size_t buflen) 814*1f154020SRobert Mustacchi { 815*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, 816*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 817*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 818*1f154020SRobert Mustacchi dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); 819*1f154020SRobert Mustacchi } 820*1f154020SRobert Mustacchi 821*1f154020SRobert Mustacchi /*ARGSUSED*/ 822*1f154020SRobert Mustacchi static void 823*1f154020SRobert Mustacchi dis_riscv_fp_rs2_fp_nr(dis_handle_t *dhp, uint32_t instr, 824*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 825*1f154020SRobert Mustacchi { 826*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, 827*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 828*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)]); 829*1f154020SRobert Mustacchi } 830*1f154020SRobert Mustacchi 831*1f154020SRobert Mustacchi /*ARGSUSED*/ 832*1f154020SRobert Mustacchi static void 833*1f154020SRobert Mustacchi dis_riscv_fp_rs2_fpi(dis_handle_t *dhp, uint32_t instr, 834*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 835*1f154020SRobert Mustacchi { 836*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, 837*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RD(instr)], 838*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 839*1f154020SRobert Mustacchi dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); 840*1f154020SRobert Mustacchi } 841*1f154020SRobert Mustacchi 842*1f154020SRobert Mustacchi /*ARGSUSED*/ 843*1f154020SRobert Mustacchi static void 844*1f154020SRobert Mustacchi dis_riscv_fp_rs2_ifp(dis_handle_t *dhp, uint32_t instr, 845*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 846*1f154020SRobert Mustacchi { 847*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, 848*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 849*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)], 850*1f154020SRobert Mustacchi dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); 851*1f154020SRobert Mustacchi } 852*1f154020SRobert Mustacchi 853*1f154020SRobert Mustacchi /*ARGSUSED*/ 854*1f154020SRobert Mustacchi static void 855*1f154020SRobert Mustacchi dis_riscv_fp_rs2_fpi_nr(dis_handle_t *dhp, uint32_t instr, 856*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 857*1f154020SRobert Mustacchi { 858*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, 859*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RD(instr)], 860*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)]); 861*1f154020SRobert Mustacchi } 862*1f154020SRobert Mustacchi 863*1f154020SRobert Mustacchi /*ARGSUSED*/ 864*1f154020SRobert Mustacchi static void 865*1f154020SRobert Mustacchi dis_riscv_fp_rs2_ifp_nr(dis_handle_t *dhp, uint32_t instr, 866*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 867*1f154020SRobert Mustacchi { 868*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, 869*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 870*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_RS1(instr)]); 871*1f154020SRobert Mustacchi } 872*1f154020SRobert Mustacchi 873*1f154020SRobert Mustacchi 874*1f154020SRobert Mustacchi /*ARGSUSED*/ 875*1f154020SRobert Mustacchi static void 876*1f154020SRobert Mustacchi dis_riscv_fp_rm(dis_handle_t *dhp, uint32_t instr, 877*1f154020SRobert Mustacchi dis_riscv_instr_t *table, char *buf, size_t buflen) 878*1f154020SRobert Mustacchi { 879*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s,%s%s", table->drv_name, 880*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RD(instr)], 881*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS1(instr)], 882*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_RS2(instr)], 883*1f154020SRobert Mustacchi dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); 884*1f154020SRobert Mustacchi } 885*1f154020SRobert Mustacchi 886*1f154020SRobert Mustacchi #define DIS_RISCV_R32(str, op, f3, f7) \ 887*1f154020SRobert Mustacchi { str, DIS_RISCV_I_R_TYPE, dis_riscv_rtype_32, op, f3, f7 } 888*1f154020SRobert Mustacchi #define DIS_RISCV_I32(str, op, f3) \ 889*1f154020SRobert Mustacchi { str, DIS_RISCV_I_I_TYPE, dis_riscv_itype_32, op, f3 } 890*1f154020SRobert Mustacchi #define DIS_RISCV_S32(str, op, f3) \ 891*1f154020SRobert Mustacchi { str, DIS_RISCV_I_S_TYPE, dis_riscv_stype_32, op, f3 } 892*1f154020SRobert Mustacchi #define DIS_RISCV_B32(str, op, f3) \ 893*1f154020SRobert Mustacchi { str, DIS_RISCV_I_B_TYPE, dis_riscv_btype_32, op, f3 } 894*1f154020SRobert Mustacchi #define DIS_RISCV_U32(str, op) \ 895*1f154020SRobert Mustacchi { str, DIS_RISCV_I_U_TYPE, dis_riscv_utype_32, op } 896*1f154020SRobert Mustacchi #define DIS_RISCV_J32(str, op) \ 897*1f154020SRobert Mustacchi { str, DIS_RISCV_I_J_TYPE, dis_riscv_jtype_32, op } 898*1f154020SRobert Mustacchi 899*1f154020SRobert Mustacchi /* 900*1f154020SRobert Mustacchi * These are non-standard types that we've defined because they require 901*1f154020SRobert Mustacchi * different handling. 902*1f154020SRobert Mustacchi */ 903*1f154020SRobert Mustacchi #define DIS_RISCV_SHIFT32(str, op, f3, f7) \ 904*1f154020SRobert Mustacchi { str, DIS_RISCV_I_R_TYPE, dis_riscv_shift_32, op, f3, f7 } 905*1f154020SRobert Mustacchi #define DIS_RISCV_SHIFT64(str, op, f3, f7) \ 906*1f154020SRobert Mustacchi { str, DIS_RISCV_I_SHIFT64_TYPE, dis_riscv_shift_64, op, f3, f7 } 907*1f154020SRobert Mustacchi #define DIS_RISCV_CSR(str, op, f3) \ 908*1f154020SRobert Mustacchi { str, DIS_RISCV_I_I_TYPE, dis_riscv_csr, op, f3 } 909*1f154020SRobert Mustacchi #define DIS_RISCV_CSRI(str, op, f3) \ 910*1f154020SRobert Mustacchi { str, DIS_RISCV_I_I_TYPE, dis_riscv_csri, op, f3 } 911*1f154020SRobert Mustacchi #define DIS_RISCV_LOAD(str, op, f3) \ 912*1f154020SRobert Mustacchi { str, DIS_RISCV_I_I_TYPE, dis_riscv_load, op, f3 } 913*1f154020SRobert Mustacchi 914*1f154020SRobert Mustacchi #define DIS_RISCV_MASK(str, mask, val, func) \ 915*1f154020SRobert Mustacchi { str, DIS_RISCV_I_MASK_TYPE, func, mask, val } 916*1f154020SRobert Mustacchi 917*1f154020SRobert Mustacchi 918*1f154020SRobert Mustacchi /* 919*1f154020SRobert Mustacchi * Atomic-extension specific entries 920*1f154020SRobert Mustacchi */ 921*1f154020SRobert Mustacchi #define DIS_RISCV_A32(str, op, f3, f5) \ 922*1f154020SRobert Mustacchi { str, DIS_RISCV_I_RV32A_TYPE, dis_riscv_rv32a, op, f3, f5 } 923*1f154020SRobert Mustacchi #define DIS_RISCV_A32LOAD(str, op, f3, f5, f2) \ 924*1f154020SRobert Mustacchi { str, DIS_RISCV_I_RV32A_LOAD_TYPE, dis_riscv_rv32a_load, op, f3, \ 925*1f154020SRobert Mustacchi f5, f2 } 926*1f154020SRobert Mustacchi 927*1f154020SRobert Mustacchi /* 928*1f154020SRobert Mustacchi * Floating-point specific entries 929*1f154020SRobert Mustacchi */ 930*1f154020SRobert Mustacchi #define DIS_RISCV_FP_LOAD(str, op, f3) \ 931*1f154020SRobert Mustacchi { str, DIS_RISCV_I_I_TYPE, dis_riscv_fp_load, op, f3 } 932*1f154020SRobert Mustacchi #define DIS_RISCV_FP_STORE(str, op, f3) \ 933*1f154020SRobert Mustacchi { str, DIS_RISCV_I_S_TYPE, dis_riscv_fp_store, op, f3 } 934*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R(str, op, f3, f7) \ 935*1f154020SRobert Mustacchi { str, DIS_RISCV_I_R_TYPE, dis_riscv_fp_r, op, f3, f7 } 936*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R4(str, op, f2) \ 937*1f154020SRobert Mustacchi { str, DIS_RISCV_I_R4_TYPE, dis_riscv_fp_r4, op, 0, 0, f2 } 938*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS2_FP(str, op, rs2, f7) \ 939*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fp, op, rs2, f7 } 940*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS2_FP_NR(str, op, rs2, f7) \ 941*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fp_nr, op, rs2, f7 } 942*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS2_FPI(str, op, rs2, f7) \ 943*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fpi, op, rs2, f7 } 944*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS2_IFP(str, op, rs2, f7) \ 945*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_ifp, op, rs2, f7 } 946*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RS2_IFP_NR(str, op, rs2, f7) \ 947*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_ifp_nr, op, rs2, f7 } 948*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RM(str, op, f7) \ 949*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_RM_TYPE, dis_riscv_fp_rm, op, 0, f7 } 950*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R_RS2_FPI(str, op, f3, rs2, f7) \ 951*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_fpi, op, f3, f7, \ 952*1f154020SRobert Mustacchi rs2 } 953*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R_RS2_IFP(str, op, f3, rs2, f7) \ 954*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_ifp, op, f3, f7, \ 955*1f154020SRobert Mustacchi rs2 } 956*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R_RS2_FPI_NR(str, op, f3, rs2, f7) \ 957*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_fpi_nr, op, f3, \ 958*1f154020SRobert Mustacchi f7, rs2 } 959*1f154020SRobert Mustacchi #define DIS_RISCV_FP_R_RS2_IFP_NR(str, op, f3, rs2, f7) \ 960*1f154020SRobert Mustacchi { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_ifp_nr, op, f3, \ 961*1f154020SRobert Mustacchi f7, rs2 } 962*1f154020SRobert Mustacchi #define DIS_RISCV_FP_RI(str, op, f3, f7) \ 963*1f154020SRobert Mustacchi { str, DIS_RISCV_I_R_TYPE, dis_riscv_fp_r_fpi, op, f3, f7 } 964*1f154020SRobert Mustacchi 965*1f154020SRobert Mustacchi /* 966*1f154020SRobert Mustacchi * This table is ordered such that it follows the ordering in the RISC-V ISA 967*1f154020SRobert Mustacchi * Manual. 968*1f154020SRobert Mustacchi */ 969*1f154020SRobert Mustacchi static dis_riscv_instr_t dis_riscv_4byte[] = { 970*1f154020SRobert Mustacchi /* 971*1f154020SRobert Mustacchi * RV32I 972*1f154020SRobert Mustacchi */ 973*1f154020SRobert Mustacchi DIS_RISCV_U32("lui", 0x37), 974*1f154020SRobert Mustacchi DIS_RISCV_U32("auipc", 0x17), 975*1f154020SRobert Mustacchi DIS_RISCV_J32("jal", 0x6f), 976*1f154020SRobert Mustacchi /* ret is a special case of jalr */ 977*1f154020SRobert Mustacchi DIS_RISCV_MASK("ret", 0xffffffff, 0x00008067, dis_riscv_name), 978*1f154020SRobert Mustacchi DIS_RISCV_I32("jalr", 0x67, 0x0), 979*1f154020SRobert Mustacchi DIS_RISCV_B32("beq", 0x63, 0x0), 980*1f154020SRobert Mustacchi DIS_RISCV_B32("bne", 0x63, 0x1), 981*1f154020SRobert Mustacchi DIS_RISCV_B32("blt", 0x63, 0x4), 982*1f154020SRobert Mustacchi DIS_RISCV_B32("bge", 0x63, 0x5), 983*1f154020SRobert Mustacchi DIS_RISCV_B32("bltu", 0x63, 0x6), 984*1f154020SRobert Mustacchi DIS_RISCV_B32("bgeu", 0x63, 0x7), 985*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lb", 0x03, 0x0), 986*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lh", 0x03, 0x1), 987*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lw", 0x03, 0x2), 988*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lbu", 0x03, 0x4), 989*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lhu", 0x03, 0x5), 990*1f154020SRobert Mustacchi DIS_RISCV_S32("sb", 0x23, 0x0), 991*1f154020SRobert Mustacchi DIS_RISCV_S32("sh", 0x23, 0x1), 992*1f154020SRobert Mustacchi DIS_RISCV_S32("sw", 0x23, 0x2), 993*1f154020SRobert Mustacchi /* nop is addi x0, x0, 0 */ 994*1f154020SRobert Mustacchi DIS_RISCV_MASK("nop", 0xffffffff, 0x00000013, dis_riscv_name), 995*1f154020SRobert Mustacchi DIS_RISCV_I32("addi", 0x13, 0x0), 996*1f154020SRobert Mustacchi DIS_RISCV_I32("slti", 0x13, 0x2), 997*1f154020SRobert Mustacchi DIS_RISCV_I32("sltiu", 0x13, 0x3), 998*1f154020SRobert Mustacchi DIS_RISCV_I32("xori", 0x13, 0x4), 999*1f154020SRobert Mustacchi DIS_RISCV_I32("ori", 0x13, 0x6), 1000*1f154020SRobert Mustacchi DIS_RISCV_I32("andi", 0x13, 0x7), 1001*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("slli", 0x13, 0x1, 0x00), 1002*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("srli", 0x13, 0x5, 0x00), 1003*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("srai", 0x13, 0x5, 0x20), 1004*1f154020SRobert Mustacchi DIS_RISCV_R32("add", 0x33, 0x0, 0x00), 1005*1f154020SRobert Mustacchi DIS_RISCV_R32("sub", 0x33, 0x0, 0x20), 1006*1f154020SRobert Mustacchi DIS_RISCV_R32("sll", 0x33, 0x1, 0x00), 1007*1f154020SRobert Mustacchi DIS_RISCV_R32("slt", 0x33, 0x2, 0x00), 1008*1f154020SRobert Mustacchi DIS_RISCV_R32("sltu", 0x33, 0x3, 0x00), 1009*1f154020SRobert Mustacchi DIS_RISCV_R32("xor", 0x33, 0x4, 0x00), 1010*1f154020SRobert Mustacchi DIS_RISCV_R32("srl", 0x33, 0x5, 0x00), 1011*1f154020SRobert Mustacchi DIS_RISCV_R32("sra", 0x33, 0x5, 0x20), 1012*1f154020SRobert Mustacchi DIS_RISCV_R32("or", 0x33, 0x6, 0x00), 1013*1f154020SRobert Mustacchi DIS_RISCV_R32("and", 0x33, 0x7, 0x00), 1014*1f154020SRobert Mustacchi DIS_RISCV_MASK("fence", 0xf00fffff, 0xf, dis_riscv_fence), 1015*1f154020SRobert Mustacchi DIS_RISCV_MASK("fence.i", 0xfffff00f, 0x100f, dis_riscv_name), 1016*1f154020SRobert Mustacchi DIS_RISCV_MASK("ecall", 0xffffffff, 0x73, dis_riscv_name), 1017*1f154020SRobert Mustacchi DIS_RISCV_MASK("ebreak", 0xffffffff, 0x100073, dis_riscv_name), 1018*1f154020SRobert Mustacchi DIS_RISCV_CSR("csrrw", 0x73, 0x1), 1019*1f154020SRobert Mustacchi DIS_RISCV_CSR("csrrs", 0x73, 0x2), 1020*1f154020SRobert Mustacchi DIS_RISCV_CSR("csrrc", 0x73, 0x3), 1021*1f154020SRobert Mustacchi DIS_RISCV_CSRI("csrrwi", 0x73, 0x5), 1022*1f154020SRobert Mustacchi DIS_RISCV_CSRI("csrrsi", 0x73, 0x6), 1023*1f154020SRobert Mustacchi DIS_RISCV_CSRI("csrrci", 0x73, 0x7), 1024*1f154020SRobert Mustacchi /* 1025*1f154020SRobert Mustacchi * RV64I 1026*1f154020SRobert Mustacchi */ 1027*1f154020SRobert Mustacchi DIS_RISCV_LOAD("lwu", 0x03, 0x6), 1028*1f154020SRobert Mustacchi DIS_RISCV_LOAD("ld", 0x03, 0x3), 1029*1f154020SRobert Mustacchi DIS_RISCV_S32("sd", 0x23, 0x3), 1030*1f154020SRobert Mustacchi DIS_RISCV_SHIFT64("slli", 0x13, 0x1, 0x0), 1031*1f154020SRobert Mustacchi DIS_RISCV_SHIFT64("srli", 0x13, 0x5, 0x0), 1032*1f154020SRobert Mustacchi DIS_RISCV_SHIFT64("srai", 0x13, 0x5, 0x10), 1033*1f154020SRobert Mustacchi DIS_RISCV_I32("addiw", 0x1b, 0x0), 1034*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("slliw", 0x1b, 0x1, 0x0), 1035*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("srliw", 0x1b, 0x5, 0x0), 1036*1f154020SRobert Mustacchi DIS_RISCV_SHIFT32("sraiw", 0x1b, 0x5, 0x20), 1037*1f154020SRobert Mustacchi DIS_RISCV_R32("addw", 0x3b, 0x0, 0x00), 1038*1f154020SRobert Mustacchi DIS_RISCV_R32("subw", 0x3b, 0x0, 0x20), 1039*1f154020SRobert Mustacchi DIS_RISCV_R32("sllw", 0x3b, 0x1, 0x00), 1040*1f154020SRobert Mustacchi DIS_RISCV_R32("srlw", 0x3b, 0x5, 0x00), 1041*1f154020SRobert Mustacchi DIS_RISCV_R32("sraw", 0x3b, 0x5, 0x20), 1042*1f154020SRobert Mustacchi /* 1043*1f154020SRobert Mustacchi * RV32M 1044*1f154020SRobert Mustacchi */ 1045*1f154020SRobert Mustacchi DIS_RISCV_R32("mul", 0x33, 0x0, 0x01), 1046*1f154020SRobert Mustacchi DIS_RISCV_R32("mulh", 0x33, 0x1, 0x01), 1047*1f154020SRobert Mustacchi DIS_RISCV_R32("mulhsu", 0x33, 0x2, 0x01), 1048*1f154020SRobert Mustacchi DIS_RISCV_R32("mulhu", 0x33, 0x3, 0x01), 1049*1f154020SRobert Mustacchi DIS_RISCV_R32("div", 0x33, 0x4, 0x01), 1050*1f154020SRobert Mustacchi DIS_RISCV_R32("divu", 0x33, 0x5, 0x01), 1051*1f154020SRobert Mustacchi DIS_RISCV_R32("rem", 0x33, 0x6, 0x01), 1052*1f154020SRobert Mustacchi DIS_RISCV_R32("remu", 0x33, 0x7, 0x01), 1053*1f154020SRobert Mustacchi /* 1054*1f154020SRobert Mustacchi * RV64M 1055*1f154020SRobert Mustacchi */ 1056*1f154020SRobert Mustacchi DIS_RISCV_R32("mulw", 0x3b, 0x0, 0x01), 1057*1f154020SRobert Mustacchi DIS_RISCV_R32("divw", 0x3b, 0x4, 0x01), 1058*1f154020SRobert Mustacchi DIS_RISCV_R32("divuw", 0x3b, 0x5, 0x01), 1059*1f154020SRobert Mustacchi DIS_RISCV_R32("remw", 0x3b, 0x6, 0x01), 1060*1f154020SRobert Mustacchi DIS_RISCV_R32("remuw", 0x3b, 0x7, 0x01), 1061*1f154020SRobert Mustacchi /* 1062*1f154020SRobert Mustacchi * RV32A 1063*1f154020SRobert Mustacchi */ 1064*1f154020SRobert Mustacchi DIS_RISCV_A32LOAD("lr.w", 0x2f, 0x2, 0x02, 0x0), 1065*1f154020SRobert Mustacchi DIS_RISCV_A32("sc.w", 0x2f, 0x2, 0x03), 1066*1f154020SRobert Mustacchi DIS_RISCV_A32("amoswap.w", 0x2f, 0x2, 0x01), 1067*1f154020SRobert Mustacchi DIS_RISCV_A32("amoadd.w", 0x2f, 0x2, 0x00), 1068*1f154020SRobert Mustacchi DIS_RISCV_A32("amoxor.w", 0x2f, 0x2, 0x04), 1069*1f154020SRobert Mustacchi DIS_RISCV_A32("amoand.w", 0x2f, 0x2, 0x0c), 1070*1f154020SRobert Mustacchi DIS_RISCV_A32("amoor.w", 0x2f, 0x2, 0x08), 1071*1f154020SRobert Mustacchi DIS_RISCV_A32("amomin.w", 0x2f, 0x2, 0x10), 1072*1f154020SRobert Mustacchi DIS_RISCV_A32("amomax.w", 0x2f, 0x2, 0x14), 1073*1f154020SRobert Mustacchi DIS_RISCV_A32("amominu.w", 0x2f, 0x2, 0x18), 1074*1f154020SRobert Mustacchi DIS_RISCV_A32("amomaxu.w", 0x2f, 0x2, 0x1c), 1075*1f154020SRobert Mustacchi /* 1076*1f154020SRobert Mustacchi * RV64A 1077*1f154020SRobert Mustacchi */ 1078*1f154020SRobert Mustacchi DIS_RISCV_A32LOAD("lr.d", 0x2f, 0x3, 0x02, 0x0), 1079*1f154020SRobert Mustacchi DIS_RISCV_A32("sc.d", 0x2f, 0x3, 0x03), 1080*1f154020SRobert Mustacchi DIS_RISCV_A32("amoswap.d", 0x2f, 0x3, 0x01), 1081*1f154020SRobert Mustacchi DIS_RISCV_A32("amoadd.d", 0x2f, 0x3, 0x00), 1082*1f154020SRobert Mustacchi DIS_RISCV_A32("amoxor.d", 0x2f, 0x3, 0x04), 1083*1f154020SRobert Mustacchi DIS_RISCV_A32("amoand.d", 0x2f, 0x3, 0x0c), 1084*1f154020SRobert Mustacchi DIS_RISCV_A32("amoor.d", 0x2f, 0x3, 0x08), 1085*1f154020SRobert Mustacchi DIS_RISCV_A32("amomin.d", 0x2f, 0x3, 0x10), 1086*1f154020SRobert Mustacchi DIS_RISCV_A32("amomax.d", 0x2f, 0x3, 0x14), 1087*1f154020SRobert Mustacchi DIS_RISCV_A32("amominu.d", 0x2f, 0x3, 0x18), 1088*1f154020SRobert Mustacchi DIS_RISCV_A32("amomaxu.d", 0x2f, 0x3, 0x1c), 1089*1f154020SRobert Mustacchi /* 1090*1f154020SRobert Mustacchi * RV32F 1091*1f154020SRobert Mustacchi */ 1092*1f154020SRobert Mustacchi DIS_RISCV_FP_LOAD("flw", 0x07, 0x2), 1093*1f154020SRobert Mustacchi DIS_RISCV_FP_STORE("fsw", 0x27, 0x2), 1094*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fmadd.s", 0x43, 0x0), 1095*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fmsub.s", 0x47, 0x0), 1096*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fnmsub.s", 0x4b, 0x0), 1097*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fnmadd.s", 0x4f, 0x0), 1098*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fadd.s", 0x53, 0x00), 1099*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fsub.s", 0x53, 0x04), 1100*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fmul.s", 0x53, 0x08), 1101*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fdiv.s", 0x53, 0xc), 1102*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FP("fsqrt.s", 0x53, 0x00, 0x2c), 1103*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnj.s", 0x53, 0x0, 0x10), 1104*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnjn.s", 0x53, 0x1, 0x10), 1105*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnjx.s", 0x53, 0x2, 0x10), 1106*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fmin.s", 0x53, 0x0, 0x14), 1107*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fmax.s", 0x53, 0x1, 0x14), 1108*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.w.s", 0x53, 0x00, 0x60), 1109*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.wu.s", 0x53, 0x01, 0x60), 1110*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_FPI_NR("fmv.x.w", 0x53, 0x00, 0x00, 0x70), 1111*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("feq.s", 0x53, 0x2, 0x50), 1112*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("flt.s", 0x53, 0x1, 0x50), 1113*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("fle.s", 0x53, 0x0, 0x50), 1114*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_FPI_NR("fclass.s", 0x53, 0x1, 0x00, 0x70), 1115*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.s.w", 0x53, 0x00, 0x68), 1116*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.s.wu", 0x53, 0x01, 0x68), 1117*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_IFP_NR("fmv.w.x", 0x53, 0x0, 0x00, 0x78), 1118*1f154020SRobert Mustacchi /* 1119*1f154020SRobert Mustacchi * RV64F 1120*1f154020SRobert Mustacchi */ 1121*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.l.s", 0x53, 0x02, 0x60), 1122*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.lu.s", 0x53, 0x03, 0x60), 1123*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.s.l", 0x53, 0x02, 0x68), 1124*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.s.lu", 0x53, 0x03, 0x68), 1125*1f154020SRobert Mustacchi /* 1126*1f154020SRobert Mustacchi * RV32D 1127*1f154020SRobert Mustacchi */ 1128*1f154020SRobert Mustacchi DIS_RISCV_FP_LOAD("fld", 0x07, 0x3), 1129*1f154020SRobert Mustacchi DIS_RISCV_FP_STORE("fsd", 0x27, 0x3), 1130*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fmadd.d", 0x43, 0x1), 1131*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fmsub.d", 0x47, 0x1), 1132*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fnmsub.d", 0x4b, 0x1), 1133*1f154020SRobert Mustacchi DIS_RISCV_FP_R4("fnmadd.d", 0x4f, 0x1), 1134*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fadd.d", 0x53, 0x01), 1135*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fsub.d", 0x53, 0x05), 1136*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fmul.d", 0x53, 0x09), 1137*1f154020SRobert Mustacchi DIS_RISCV_FP_RM("fdiv.d", 0x53, 0xd), 1138*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FP("fsqrt.d", 0x53, 0x00, 0x2d), 1139*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnj.d", 0x53, 0x0, 0x11), 1140*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnjn.d", 0x53, 0x1, 0x11), 1141*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fsgnjx.d", 0x53, 0x2, 0x11), 1142*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fmin.d", 0x53, 0x0, 0x15), 1143*1f154020SRobert Mustacchi DIS_RISCV_FP_R("fmax.d", 0x53, 0x1, 0x15), 1144*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FP("fcvt.s.d", 0x53, 0x01, 0x20), 1145*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FP_NR("fcvt.d.s", 0x53, 0x00, 0x21), 1146*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("feq.d", 0x53, 0x2, 0x51), 1147*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("flt.d", 0x53, 0x1, 0x51), 1148*1f154020SRobert Mustacchi DIS_RISCV_FP_RI("fle.d", 0x53, 0x0, 0x51), 1149*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_FPI_NR("fclass.d", 0x53, 0x1, 0x00, 0x71), 1150*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.w.d", 0x53, 0x00, 0x61), 1151*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.wu.d", 0x53, 0x01, 0x61), 1152*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP_NR("fcvt.d.w", 0x53, 0x00, 0x69), 1153*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP_NR("fcvt.d.wu", 0x53, 0x01, 0x69), 1154*1f154020SRobert Mustacchi /* 1155*1f154020SRobert Mustacchi * RV64D 1156*1f154020SRobert Mustacchi */ 1157*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.l.d", 0x53, 0x02, 0x61), 1158*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_FPI("fcvt.lu.d", 0x53, 0x03, 0x61), 1159*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_FPI_NR("fmv.x.d", 0x53, 0x0, 0x00, 0x71), 1160*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.d.l", 0x53, 0x02, 0x69), 1161*1f154020SRobert Mustacchi DIS_RISCV_FP_RS2_IFP("fcvt.d.lu", 0x53, 0x03, 0x69), 1162*1f154020SRobert Mustacchi DIS_RISCV_FP_R_RS2_IFP_NR("fmv.d.x", 0x53, 0x0, 0x00, 0x79), 1163*1f154020SRobert Mustacchi /* 1164*1f154020SRobert Mustacchi * Privileged Instructions from RISC-V Privileged Architectures V1.10. 1165*1f154020SRobert Mustacchi */ 1166*1f154020SRobert Mustacchi DIS_RISCV_MASK("uret", 0xffffffff, 0x00200073, dis_riscv_name), 1167*1f154020SRobert Mustacchi DIS_RISCV_MASK("sret", 0xffffffff, 0x10200073, dis_riscv_name), 1168*1f154020SRobert Mustacchi DIS_RISCV_MASK("mret", 0xffffffff, 0x30200073, dis_riscv_name), 1169*1f154020SRobert Mustacchi DIS_RISCV_MASK("wfi", 0xffffffff, 0x10500073, dis_riscv_name), 1170*1f154020SRobert Mustacchi DIS_RISCV_MASK("sfence.vma", 0xfe007fff, 0x12000073, dis_riscv_rs1_rs2) 1171*1f154020SRobert Mustacchi }; 1172*1f154020SRobert Mustacchi 1173*1f154020SRobert Mustacchi static void 1174*1f154020SRobert Mustacchi dis_riscv_decode_4byte(dis_handle_t *dhp, uint32_t instr, char *buf, 1175*1f154020SRobert Mustacchi size_t buflen) 1176*1f154020SRobert Mustacchi { 1177*1f154020SRobert Mustacchi uint_t i; 1178*1f154020SRobert Mustacchi 1179*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_4byte); i++) { 1180*1f154020SRobert Mustacchi dis_riscv_instr_t *t = &dis_riscv_4byte[i]; 1181*1f154020SRobert Mustacchi switch (t->drv_type) { 1182*1f154020SRobert Mustacchi case DIS_RISCV_I_R_TYPE: 1183*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1184*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && 1185*1f154020SRobert Mustacchi DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { 1186*1f154020SRobert Mustacchi break; 1187*1f154020SRobert Mustacchi } 1188*1f154020SRobert Mustacchi continue; 1189*1f154020SRobert Mustacchi case DIS_RISCV_I_I_TYPE: 1190*1f154020SRobert Mustacchi case DIS_RISCV_I_S_TYPE: 1191*1f154020SRobert Mustacchi case DIS_RISCV_I_B_TYPE: 1192*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1193*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3) { 1194*1f154020SRobert Mustacchi break; 1195*1f154020SRobert Mustacchi } 1196*1f154020SRobert Mustacchi continue; 1197*1f154020SRobert Mustacchi case DIS_RISCV_I_U_TYPE: 1198*1f154020SRobert Mustacchi case DIS_RISCV_I_J_TYPE: 1199*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode) { 1200*1f154020SRobert Mustacchi break; 1201*1f154020SRobert Mustacchi } 1202*1f154020SRobert Mustacchi continue; 1203*1f154020SRobert Mustacchi case DIS_RISCV_I_R4_TYPE: 1204*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1205*1f154020SRobert Mustacchi DIS_RISCV_FUNCT2(instr) == t->drv_funct2) { 1206*1f154020SRobert Mustacchi break; 1207*1f154020SRobert Mustacchi } 1208*1f154020SRobert Mustacchi continue; 1209*1f154020SRobert Mustacchi case DIS_RISCV_I_MASK_TYPE: 1210*1f154020SRobert Mustacchi if ((instr & t->drv_opcode) == t->drv_funct3) { 1211*1f154020SRobert Mustacchi break; 1212*1f154020SRobert Mustacchi } 1213*1f154020SRobert Mustacchi continue; 1214*1f154020SRobert Mustacchi case DIS_RISCV_I_SHIFT64_TYPE: 1215*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1216*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && 1217*1f154020SRobert Mustacchi DIS_RISCV_SFUNCT7(instr) == t->drv_funct7) { 1218*1f154020SRobert Mustacchi break; 1219*1f154020SRobert Mustacchi } 1220*1f154020SRobert Mustacchi continue; 1221*1f154020SRobert Mustacchi 1222*1f154020SRobert Mustacchi case DIS_RISCV_I_RV32A_LOAD_TYPE: 1223*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1224*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && 1225*1f154020SRobert Mustacchi DIS_RISCV_RVA_FUNCT5(instr) == t->drv_funct7 && 1226*1f154020SRobert Mustacchi DIS_RISCV_RS2(instr) == t->drv_funct2) { 1227*1f154020SRobert Mustacchi break; 1228*1f154020SRobert Mustacchi } 1229*1f154020SRobert Mustacchi continue; 1230*1f154020SRobert Mustacchi case DIS_RISCV_I_RV32A_TYPE: 1231*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1232*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && 1233*1f154020SRobert Mustacchi DIS_RISCV_RVA_FUNCT5(instr) == t->drv_funct7) { 1234*1f154020SRobert Mustacchi break; 1235*1f154020SRobert Mustacchi } 1236*1f154020SRobert Mustacchi continue; 1237*1f154020SRobert Mustacchi case DIS_RISCV_I_FP_RS2OP_TYPE: 1238*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1239*1f154020SRobert Mustacchi DIS_RISCV_RS2(instr) == t->drv_funct3 && 1240*1f154020SRobert Mustacchi DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { 1241*1f154020SRobert Mustacchi break; 1242*1f154020SRobert Mustacchi } 1243*1f154020SRobert Mustacchi continue; 1244*1f154020SRobert Mustacchi case DIS_RISCV_I_FP_RM_TYPE: 1245*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1246*1f154020SRobert Mustacchi DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { 1247*1f154020SRobert Mustacchi break; 1248*1f154020SRobert Mustacchi } 1249*1f154020SRobert Mustacchi continue; 1250*1f154020SRobert Mustacchi case DIS_RISCV_I_FP_R_RS2_TYPE: 1251*1f154020SRobert Mustacchi if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && 1252*1f154020SRobert Mustacchi DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && 1253*1f154020SRobert Mustacchi DIS_RISCV_RS2(instr) == t->drv_funct2 && 1254*1f154020SRobert Mustacchi DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { 1255*1f154020SRobert Mustacchi break; 1256*1f154020SRobert Mustacchi } 1257*1f154020SRobert Mustacchi continue; 1258*1f154020SRobert Mustacchi default: 1259*1f154020SRobert Mustacchi continue; 1260*1f154020SRobert Mustacchi } 1261*1f154020SRobert Mustacchi 1262*1f154020SRobert Mustacchi t->drv_print(dhp, instr, t, buf, buflen); 1263*1f154020SRobert Mustacchi return; 1264*1f154020SRobert Mustacchi } 1265*1f154020SRobert Mustacchi 1266*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "<unknown>"); 1267*1f154020SRobert Mustacchi } 1268*1f154020SRobert Mustacchi 1269*1f154020SRobert Mustacchi /* 1270*1f154020SRobert Mustacchi * Two byte decode table types. 1271*1f154020SRobert Mustacchi */ 1272*1f154020SRobert Mustacchi typedef enum dis_riscv_ctype { 1273*1f154020SRobert Mustacchi /* 1274*1f154020SRobert Mustacchi * Indicates that we should match based on the opcode and funct3. 1275*1f154020SRobert Mustacchi */ 1276*1f154020SRobert Mustacchi DIS_RISCV_C_FUNCT3, 1277*1f154020SRobert Mustacchi /* 1278*1f154020SRobert Mustacchi * Indicates that we should match the instruction based on a mask. 1279*1f154020SRobert Mustacchi */ 1280*1f154020SRobert Mustacchi DIS_RISCV_C_MATCH 1281*1f154020SRobert Mustacchi } dis_riscv_ctype_t; 1282*1f154020SRobert Mustacchi 1283*1f154020SRobert Mustacchi /* 1284*1f154020SRobert Mustacchi * The compact forms are depending on the elf class. This is used to keep track 1285*1f154020SRobert Mustacchi * of the class and match it. 1286*1f154020SRobert Mustacchi */ 1287*1f154020SRobert Mustacchi typedef enum dis_riscv_c_class { 1288*1f154020SRobert Mustacchi DIS_RISCV_CL_ALL, 1289*1f154020SRobert Mustacchi DIS_RISCV_CL_32, 1290*1f154020SRobert Mustacchi DIS_RISCV_CL_64, 1291*1f154020SRobert Mustacchi DIS_RISCV_CL_32_64, 1292*1f154020SRobert Mustacchi DIS_RISCV_CL_64_128 1293*1f154020SRobert Mustacchi } dis_riscv_c_class_t; 1294*1f154020SRobert Mustacchi 1295*1f154020SRobert Mustacchi struct dis_riscv_c_instr; 1296*1f154020SRobert Mustacchi typedef void (*dis_riscv_c_func_t)(dis_handle_t *, uint32_t, 1297*1f154020SRobert Mustacchi struct dis_riscv_c_instr *, char *, size_t); 1298*1f154020SRobert Mustacchi 1299*1f154020SRobert Mustacchi typedef struct dis_riscv_c_instr { 1300*1f154020SRobert Mustacchi const char *drv_c_name; 1301*1f154020SRobert Mustacchi dis_riscv_ctype_t drv_c_type; 1302*1f154020SRobert Mustacchi dis_riscv_c_func_t drv_c_print; 1303*1f154020SRobert Mustacchi dis_riscv_c_class_t drv_c_class; 1304*1f154020SRobert Mustacchi uint_t drv_c_opcode; 1305*1f154020SRobert Mustacchi uint_t drv_c_funct; 1306*1f154020SRobert Mustacchi uint_t drv_c_mask; 1307*1f154020SRobert Mustacchi uint_t drv_c_match; 1308*1f154020SRobert Mustacchi } dis_riscv_c_instr_t; 1309*1f154020SRobert Mustacchi 1310*1f154020SRobert Mustacchi #define DIS_RISCV_C_OPCODE(x) ((x) & 0x03) 1311*1f154020SRobert Mustacchi #define DIS_RISCV_C_FUNCT3(x) (((x) & 0xe000) >> 13) 1312*1f154020SRobert Mustacchi 1313*1f154020SRobert Mustacchi #define DIS_RISCV_C_RS1(x) (((x) & 0x0f80) >> 7) 1314*1f154020SRobert Mustacchi #define DIS_RISCV_C_RS2(x) (((x) & 0x007c) >> 2) 1315*1f154020SRobert Mustacchi #define DIS_RISCV_C_RD(x) DIS_RISCV_C_RS1(x) 1316*1f154020SRobert Mustacchi 1317*1f154020SRobert Mustacchi #define DIS_RISCV_C_RS1P(x) (((x) & 0x0380) >> 7) 1318*1f154020SRobert Mustacchi #define DIS_RISCV_C_RS2P(x) DIS_RISCV_C_RDP(x) 1319*1f154020SRobert Mustacchi #define DIS_RISCV_C_RDP(x) (((x) & 0x001c) >> 2) 1320*1f154020SRobert Mustacchi 1321*1f154020SRobert Mustacchi /* 1322*1f154020SRobert Mustacchi * CJ format immediate extractor 1323*1f154020SRobert Mustacchi */ 1324*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_11(x) (((x) & 0x1000) >> 1) 1325*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_4(x) (((x) & 0x0800) >> 7) 1326*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_9_8(x) (((x) & 0x0600) >> 1) 1327*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_10(x) (((x) & 0x0100) << 2) 1328*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_6(x) (((x) & 0x0080) >> 1) 1329*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_7(x) (((x) & 0x0040) << 1) 1330*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_3_1(x) (((x) & 0x0038) >> 3) 1331*1f154020SRobert Mustacchi #define DIS_RISCV_C_J_5(x) (((x) & 0x0004) << 3) 1332*1f154020SRobert Mustacchi 1333*1f154020SRobert Mustacchi /* 1334*1f154020SRobert Mustacchi * Compact Branch extractor 1335*1f154020SRobert Mustacchi */ 1336*1f154020SRobert Mustacchi #define DIS_RISCV_C_B_8(x) (((x) & 0x1000) >> 4) 1337*1f154020SRobert Mustacchi #define DIS_RISCV_C_B_4_3(x) (((x) & 0x0c00) >> 7) 1338*1f154020SRobert Mustacchi #define DIS_RISCV_C_B_7_6(x) (((x) & 0x0060) << 1) 1339*1f154020SRobert Mustacchi #define DIS_RISCV_C_B_2_1(x) (((x) & 0x0018) >> 2) 1340*1f154020SRobert Mustacchi #define DIS_RISCV_C_B_5(x) (((x) & 0x0004) << 3) 1341*1f154020SRobert Mustacchi 1342*1f154020SRobert Mustacchi /* 1343*1f154020SRobert Mustacchi * c.addi16spn extractor 1344*1f154020SRobert Mustacchi */ 1345*1f154020SRobert Mustacchi #define DIS_RISCV_C_A16_9(x) (((x) & 0x1000) >> 3) 1346*1f154020SRobert Mustacchi #define DIS_RISCV_C_A16_4(x) (((x) & 0x0040) >> 2) 1347*1f154020SRobert Mustacchi #define DIS_RISCV_C_A16_6(x) (((x) & 0x0020) << 1) 1348*1f154020SRobert Mustacchi #define DIS_RISCV_C_A16_8_7(x) (((x) & 0x0018) << 4) 1349*1f154020SRobert Mustacchi #define DIS_RISCV_C_A16_5(x) (((x) & 0x0004) << 3) 1350*1f154020SRobert Mustacchi 1351*1f154020SRobert Mustacchi /* 1352*1f154020SRobert Mustacchi * c.addi4spn extractor 1353*1f154020SRobert Mustacchi */ 1354*1f154020SRobert Mustacchi #define DIS_RISCV_C_A4_5_4(x) (((x) & 0x1800) >> 7) 1355*1f154020SRobert Mustacchi #define DIS_RISCV_C_A4_9_6(x) (((x) & 0x0700) >> 2) 1356*1f154020SRobert Mustacchi #define DIS_RISCV_C_A4_2(x) (((x) & 0x0040) >> 4) 1357*1f154020SRobert Mustacchi #define DIS_RISCV_C_A4_3(x) (((x) & 0x0020) >> 2) 1358*1f154020SRobert Mustacchi 1359*1f154020SRobert Mustacchi /*ARGSUSED*/ 1360*1f154020SRobert Mustacchi static void 1361*1f154020SRobert Mustacchi dis_riscv_c_name(dis_handle_t *dhp, uint32_t instr, 1362*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1363*1f154020SRobert Mustacchi { 1364*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s", table->drv_c_name); 1365*1f154020SRobert Mustacchi } 1366*1f154020SRobert Mustacchi 1367*1f154020SRobert Mustacchi static void 1368*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dis_handle_t *dhp, const char *name, const char *dreg, 1369*1f154020SRobert Mustacchi const char *sreg, uint32_t off, char *buf, size_t buflen) 1370*1f154020SRobert Mustacchi { 1371*1f154020SRobert Mustacchi 1372*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 1373*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0%o(%s)", name, dreg, 1374*1f154020SRobert Mustacchi off, sreg); 1375*1f154020SRobert Mustacchi } else { 1376*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,0x%x(%s)", name, dreg, 1377*1f154020SRobert Mustacchi off, sreg); 1378*1f154020SRobert Mustacchi } 1379*1f154020SRobert Mustacchi } 1380*1f154020SRobert Mustacchi 1381*1f154020SRobert Mustacchi static void 1382*1f154020SRobert Mustacchi dis_riscv_c_lwsp(dis_handle_t *dhp, uint32_t instr, 1383*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1384*1f154020SRobert Mustacchi { 1385*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x000c) << 4) | 1386*1f154020SRobert Mustacchi ((instr & 0x1000) >> 7) | ((instr & 0x0070) >> 2); 1387*1f154020SRobert Mustacchi 1388*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1389*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], imm, buf, 1390*1f154020SRobert Mustacchi buflen); 1391*1f154020SRobert Mustacchi } 1392*1f154020SRobert Mustacchi 1393*1f154020SRobert Mustacchi static void 1394*1f154020SRobert Mustacchi dis_riscv_c_ldsp(dis_handle_t *dhp, uint32_t instr, 1395*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1396*1f154020SRobert Mustacchi { 1397*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x001c) << 4) | 1398*1f154020SRobert Mustacchi ((instr & 0x1000) >> 7) | ((instr & 0x0060) >> 2); 1399*1f154020SRobert Mustacchi 1400*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1401*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], 1402*1f154020SRobert Mustacchi imm, buf, buflen); 1403*1f154020SRobert Mustacchi } 1404*1f154020SRobert Mustacchi 1405*1f154020SRobert Mustacchi static void 1406*1f154020SRobert Mustacchi dis_riscv_c_flwsp(dis_handle_t *dhp, uint32_t instr, 1407*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1408*1f154020SRobert Mustacchi { 1409*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x000c) << 4) | 1410*1f154020SRobert Mustacchi ((instr & 0x1000) >> 7) | ((instr & 0x0070) >> 2); 1411*1f154020SRobert Mustacchi 1412*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1413*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], 1414*1f154020SRobert Mustacchi imm, buf, buflen); 1415*1f154020SRobert Mustacchi } 1416*1f154020SRobert Mustacchi 1417*1f154020SRobert Mustacchi static void 1418*1f154020SRobert Mustacchi dis_riscv_c_fldsp(dis_handle_t *dhp, uint32_t instr, 1419*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1420*1f154020SRobert Mustacchi { 1421*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x001c) << 4) | 1422*1f154020SRobert Mustacchi ((instr & 0x1000) >> 7) | ((instr & 0x0060) >> 2); 1423*1f154020SRobert Mustacchi 1424*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1425*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], 1426*1f154020SRobert Mustacchi imm, buf, buflen); 1427*1f154020SRobert Mustacchi } 1428*1f154020SRobert Mustacchi 1429*1f154020SRobert Mustacchi static void 1430*1f154020SRobert Mustacchi dis_riscv_c_swsp(dis_handle_t *dhp, uint32_t instr, 1431*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1432*1f154020SRobert Mustacchi { 1433*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0180) >> 1) | ((instr & 0x1e00) >> 7); 1434*1f154020SRobert Mustacchi 1435*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1436*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, 1437*1f154020SRobert Mustacchi buf, buflen); 1438*1f154020SRobert Mustacchi } 1439*1f154020SRobert Mustacchi 1440*1f154020SRobert Mustacchi static void 1441*1f154020SRobert Mustacchi dis_riscv_c_sdsp(dis_handle_t *dhp, uint32_t instr, 1442*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1443*1f154020SRobert Mustacchi { 1444*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0380) >> 1) | ((instr & 0x1c00) >> 7); 1445*1f154020SRobert Mustacchi 1446*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1447*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, 1448*1f154020SRobert Mustacchi buf, buflen); 1449*1f154020SRobert Mustacchi } 1450*1f154020SRobert Mustacchi 1451*1f154020SRobert Mustacchi static void 1452*1f154020SRobert Mustacchi dis_riscv_c_fswsp(dis_handle_t *dhp, uint32_t instr, 1453*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1454*1f154020SRobert Mustacchi { 1455*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0180) >> 1) | ((instr & 0x1e00) >> 7); 1456*1f154020SRobert Mustacchi 1457*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1458*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, 1459*1f154020SRobert Mustacchi buf, buflen); 1460*1f154020SRobert Mustacchi } 1461*1f154020SRobert Mustacchi 1462*1f154020SRobert Mustacchi static void 1463*1f154020SRobert Mustacchi dis_riscv_c_fsdsp(dis_handle_t *dhp, uint32_t instr, 1464*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1465*1f154020SRobert Mustacchi { 1466*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0380) >> 1) | ((instr & 0x1c00) >> 7); 1467*1f154020SRobert Mustacchi 1468*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1469*1f154020SRobert Mustacchi dis_riscv_fpregs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, 1470*1f154020SRobert Mustacchi buf, buflen); 1471*1f154020SRobert Mustacchi } 1472*1f154020SRobert Mustacchi 1473*1f154020SRobert Mustacchi static void 1474*1f154020SRobert Mustacchi dis_riscv_c_lw(dis_handle_t *dhp, uint32_t instr, 1475*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1476*1f154020SRobert Mustacchi { 1477*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0020) << 1) | ((instr & 0x1c) >> 7) | 1478*1f154020SRobert Mustacchi ((instr & 0x0040) >> 3); 1479*1f154020SRobert Mustacchi 1480*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1481*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], 1482*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], 1483*1f154020SRobert Mustacchi imm, buf, buflen); 1484*1f154020SRobert Mustacchi } 1485*1f154020SRobert Mustacchi 1486*1f154020SRobert Mustacchi static void 1487*1f154020SRobert Mustacchi dis_riscv_c_ld(dis_handle_t *dhp, uint32_t instr, 1488*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1489*1f154020SRobert Mustacchi { 1490*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0060) << 1) | ((instr & 0x1c) >> 7); 1491*1f154020SRobert Mustacchi 1492*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1493*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], 1494*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], 1495*1f154020SRobert Mustacchi imm, buf, buflen); 1496*1f154020SRobert Mustacchi } 1497*1f154020SRobert Mustacchi 1498*1f154020SRobert Mustacchi static void 1499*1f154020SRobert Mustacchi dis_riscv_c_flw(dis_handle_t *dhp, uint32_t instr, 1500*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1501*1f154020SRobert Mustacchi { 1502*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0020) << 1) | ((instr & 0x1c) >> 7) | 1503*1f154020SRobert Mustacchi ((instr & 0x0040) >> 3); 1504*1f154020SRobert Mustacchi 1505*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1506*1f154020SRobert Mustacchi dis_riscv_c_fpregs[DIS_RISCV_C_RDP(instr)], 1507*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], 1508*1f154020SRobert Mustacchi imm, buf, buflen); 1509*1f154020SRobert Mustacchi } 1510*1f154020SRobert Mustacchi 1511*1f154020SRobert Mustacchi static void 1512*1f154020SRobert Mustacchi dis_riscv_c_fld(dis_handle_t *dhp, uint32_t instr, 1513*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1514*1f154020SRobert Mustacchi { 1515*1f154020SRobert Mustacchi uint32_t imm = ((instr & 0x0060) << 1) | ((instr & 0x1c) >> 7); 1516*1f154020SRobert Mustacchi 1517*1f154020SRobert Mustacchi dis_riscv_c_loadstore(dhp, table->drv_c_name, 1518*1f154020SRobert Mustacchi dis_riscv_c_fpregs[DIS_RISCV_C_RDP(instr)], 1519*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], 1520*1f154020SRobert Mustacchi imm, buf, buflen); 1521*1f154020SRobert Mustacchi } 1522*1f154020SRobert Mustacchi 1523*1f154020SRobert Mustacchi /* 1524*1f154020SRobert Mustacchi * The J type has the 11 bit immediate arranged as: 1525*1f154020SRobert Mustacchi * 1526*1f154020SRobert Mustacchi * offset[11|4|9:8|10|6|7|3:1|5] going from bits 2 to 12. 1527*1f154020SRobert Mustacchi */ 1528*1f154020SRobert Mustacchi static void 1529*1f154020SRobert Mustacchi dis_riscv_c_j(dis_handle_t *dhp, uint32_t instr, 1530*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1531*1f154020SRobert Mustacchi { 1532*1f154020SRobert Mustacchi const char *s; 1533*1f154020SRobert Mustacchi uint_t jimm = DIS_RISCV_C_J_11(instr) | DIS_RISCV_C_J_10(instr) | 1534*1f154020SRobert Mustacchi DIS_RISCV_C_J_9_8(instr) | DIS_RISCV_C_J_7(instr) | 1535*1f154020SRobert Mustacchi DIS_RISCV_C_J_6(instr) | DIS_RISCV_C_J_5(instr) | 1536*1f154020SRobert Mustacchi DIS_RISCV_C_J_4(instr) | DIS_RISCV_C_J_3_1(instr); 1537*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(jimm, 11, &s); 1538*1f154020SRobert Mustacchi 1539*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 1540*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s0%o", table->drv_c_name, 1541*1f154020SRobert Mustacchi s, imm); 1542*1f154020SRobert Mustacchi } else { 1543*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s0x%x", table->drv_c_name, 1544*1f154020SRobert Mustacchi s, imm); 1545*1f154020SRobert Mustacchi } 1546*1f154020SRobert Mustacchi } 1547*1f154020SRobert Mustacchi 1548*1f154020SRobert Mustacchi /*ARGSUSED*/ 1549*1f154020SRobert Mustacchi static void 1550*1f154020SRobert Mustacchi dis_riscv_c_jr(dis_handle_t *dhp, uint32_t instr, 1551*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1552*1f154020SRobert Mustacchi { 1553*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s", table->drv_c_name, 1554*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RS1(instr)]); 1555*1f154020SRobert Mustacchi } 1556*1f154020SRobert Mustacchi 1557*1f154020SRobert Mustacchi static void 1558*1f154020SRobert Mustacchi dis_riscv_c_regimm(dis_handle_t *dhp, const char *instr, const char *dreg, 1559*1f154020SRobert Mustacchi const char *sign, uint_t imm, char *buf, size_t buflen) 1560*1f154020SRobert Mustacchi { 1561*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 1562*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0%o", instr, dreg, 1563*1f154020SRobert Mustacchi sign, imm); 1564*1f154020SRobert Mustacchi } else { 1565*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x", instr, dreg, 1566*1f154020SRobert Mustacchi sign, imm); 1567*1f154020SRobert Mustacchi } 1568*1f154020SRobert Mustacchi } 1569*1f154020SRobert Mustacchi 1570*1f154020SRobert Mustacchi static void 1571*1f154020SRobert Mustacchi dis_riscv_c_branch(dis_handle_t *dhp, uint32_t instr, 1572*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1573*1f154020SRobert Mustacchi { 1574*1f154020SRobert Mustacchi const char *s; 1575*1f154020SRobert Mustacchi uint_t bimm = DIS_RISCV_C_B_8(instr) | DIS_RISCV_C_B_7_6(instr) | 1576*1f154020SRobert Mustacchi DIS_RISCV_C_B_5(instr) | DIS_RISCV_C_B_4_3(instr) | 1577*1f154020SRobert Mustacchi DIS_RISCV_C_B_2_1(instr); 1578*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(bimm, 8, &s); 1579*1f154020SRobert Mustacchi 1580*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1581*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], s, imm, buf, buflen); 1582*1f154020SRobert Mustacchi } 1583*1f154020SRobert Mustacchi 1584*1f154020SRobert Mustacchi static void 1585*1f154020SRobert Mustacchi dis_riscv_c_bigimmint(dis_handle_t *dhp, uint32_t instr, 1586*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1587*1f154020SRobert Mustacchi { 1588*1f154020SRobert Mustacchi const char *s; 1589*1f154020SRobert Mustacchi uint_t limm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); 1590*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(limm, 5, &s); 1591*1f154020SRobert Mustacchi 1592*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1593*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], s, imm, buf, buflen); 1594*1f154020SRobert Mustacchi } 1595*1f154020SRobert Mustacchi 1596*1f154020SRobert Mustacchi static void 1597*1f154020SRobert Mustacchi dis_riscv_c_zext_bigimmint(dis_handle_t *dhp, uint32_t instr, 1598*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1599*1f154020SRobert Mustacchi { 1600*1f154020SRobert Mustacchi uint_t imm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); 1601*1f154020SRobert Mustacchi 1602*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1603*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], "", imm, buf, buflen); 1604*1f154020SRobert Mustacchi } 1605*1f154020SRobert Mustacchi 1606*1f154020SRobert Mustacchi static void 1607*1f154020SRobert Mustacchi dis_riscv_c_addi16sp(dis_handle_t *dhp, uint32_t instr, 1608*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1609*1f154020SRobert Mustacchi { 1610*1f154020SRobert Mustacchi const char *s; 1611*1f154020SRobert Mustacchi uint_t aimm = DIS_RISCV_C_A16_9(instr) | DIS_RISCV_C_A16_8_7(instr) | 1612*1f154020SRobert Mustacchi DIS_RISCV_C_A16_6(instr) | DIS_RISCV_C_A16_5(instr) | 1613*1f154020SRobert Mustacchi DIS_RISCV_C_A16_4(instr); 1614*1f154020SRobert Mustacchi int imm = dis_riscv_sign_extend(aimm, 9, &s); 1615*1f154020SRobert Mustacchi 1616*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1617*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], s, imm, buf, buflen); 1618*1f154020SRobert Mustacchi } 1619*1f154020SRobert Mustacchi 1620*1f154020SRobert Mustacchi static void 1621*1f154020SRobert Mustacchi dis_riscv_c_addi4spn(dis_handle_t *dhp, uint32_t instr, 1622*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1623*1f154020SRobert Mustacchi { 1624*1f154020SRobert Mustacchi uint_t imm = DIS_RISCV_C_A4_9_6(instr) | DIS_RISCV_C_A4_5_4(instr) | 1625*1f154020SRobert Mustacchi DIS_RISCV_C_A4_3(instr) | DIS_RISCV_C_A4_2(instr); 1626*1f154020SRobert Mustacchi 1627*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_OCTAL) != 0) { 1628*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,sp,0%o", 1629*1f154020SRobert Mustacchi table->drv_c_name, dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], 1630*1f154020SRobert Mustacchi imm); 1631*1f154020SRobert Mustacchi } else { 1632*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,sp,0x%x", 1633*1f154020SRobert Mustacchi table->drv_c_name, dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], 1634*1f154020SRobert Mustacchi imm); 1635*1f154020SRobert Mustacchi } 1636*1f154020SRobert Mustacchi } 1637*1f154020SRobert Mustacchi 1638*1f154020SRobert Mustacchi static void 1639*1f154020SRobert Mustacchi dis_riscv_c_immint(dis_handle_t *dhp, uint32_t instr, 1640*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1641*1f154020SRobert Mustacchi { 1642*1f154020SRobert Mustacchi const char *s; 1643*1f154020SRobert Mustacchi uint_t limm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); 1644*1f154020SRobert Mustacchi uint_t imm = dis_riscv_sign_extend(limm, 5, &s); 1645*1f154020SRobert Mustacchi 1646*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1647*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], s, imm, buf, buflen); 1648*1f154020SRobert Mustacchi } 1649*1f154020SRobert Mustacchi 1650*1f154020SRobert Mustacchi static void 1651*1f154020SRobert Mustacchi dis_riscv_c_zext_immint(dis_handle_t *dhp, uint32_t instr, 1652*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1653*1f154020SRobert Mustacchi { 1654*1f154020SRobert Mustacchi uint_t imm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); 1655*1f154020SRobert Mustacchi 1656*1f154020SRobert Mustacchi dis_riscv_c_regimm(dhp, table->drv_c_name, 1657*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], "", imm, buf, buflen); 1658*1f154020SRobert Mustacchi } 1659*1f154020SRobert Mustacchi 1660*1f154020SRobert Mustacchi /*ARGSUSED*/ 1661*1f154020SRobert Mustacchi static void 1662*1f154020SRobert Mustacchi dis_riscv_c_bigint(dis_handle_t *dhp, uint32_t instr, 1663*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1664*1f154020SRobert Mustacchi { 1665*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_c_name, 1666*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RD(instr)], 1667*1f154020SRobert Mustacchi dis_riscv_regs[DIS_RISCV_C_RS2(instr)]); 1668*1f154020SRobert Mustacchi } 1669*1f154020SRobert Mustacchi 1670*1f154020SRobert Mustacchi 1671*1f154020SRobert Mustacchi /*ARGSUSED*/ 1672*1f154020SRobert Mustacchi static void 1673*1f154020SRobert Mustacchi dis_riscv_c_int(dis_handle_t *dhp, uint32_t instr, 1674*1f154020SRobert Mustacchi dis_riscv_c_instr_t *table, char *buf, size_t buflen) 1675*1f154020SRobert Mustacchi { 1676*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_c_name, 1677*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], 1678*1f154020SRobert Mustacchi dis_riscv_c_regs[DIS_RISCV_C_RS2P(instr)]); 1679*1f154020SRobert Mustacchi } 1680*1f154020SRobert Mustacchi 1681*1f154020SRobert Mustacchi #define DIS_RISCV_CFUNCT3(name, class, op, funct, print) \ 1682*1f154020SRobert Mustacchi { name, DIS_RISCV_C_FUNCT3, print, class, op, funct, 0, 0 } 1683*1f154020SRobert Mustacchi #define DIS_RISCV_CMATCH(name, class, op, funct, mask, match, print) \ 1684*1f154020SRobert Mustacchi { name, DIS_RISCV_C_MATCH, print, class, op, funct, mask, match } 1685*1f154020SRobert Mustacchi 1686*1f154020SRobert Mustacchi static dis_riscv_c_instr_t dis_riscv_2byte[] = { 1687*1f154020SRobert Mustacchi /* Quadrant 0 */ 1688*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.addi4spn", DIS_RISCV_CL_32_64, 0x0, 0x0, 1689*1f154020SRobert Mustacchi dis_riscv_c_addi4spn), 1690*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fld", DIS_RISCV_CL_32_64, 0x0, 0x01, 1691*1f154020SRobert Mustacchi dis_riscv_c_fld), 1692*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.lw", DIS_RISCV_CL_ALL, 0x0, 0x2, 1693*1f154020SRobert Mustacchi dis_riscv_c_lw), 1694*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.flw", DIS_RISCV_CL_32, 0x0, 0x3, 1695*1f154020SRobert Mustacchi dis_riscv_c_flw), 1696*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("f.ld", DIS_RISCV_CL_64_128, 0x0, 0x3, 1697*1f154020SRobert Mustacchi dis_riscv_c_ld), 1698*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fsd", DIS_RISCV_CL_32_64, 0x0, 0x5, 1699*1f154020SRobert Mustacchi dis_riscv_c_fld), 1700*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.sw", DIS_RISCV_CL_ALL, 0x0, 0x6, 1701*1f154020SRobert Mustacchi dis_riscv_c_lw), 1702*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fsw", DIS_RISCV_CL_32, 0x0, 0x7, 1703*1f154020SRobert Mustacchi dis_riscv_c_flw), 1704*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.sd", DIS_RISCV_CL_64_128, 0x0, 0x7, 1705*1f154020SRobert Mustacchi dis_riscv_c_ld), 1706*1f154020SRobert Mustacchi /* Quadrant 1 */ 1707*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.nop", DIS_RISCV_CL_ALL, 0x01, 0x00, 0x1ffc, 0x0, 1708*1f154020SRobert Mustacchi dis_riscv_c_name), 1709*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.addi", DIS_RISCV_CL_ALL, 0x01, 0x00, 1710*1f154020SRobert Mustacchi dis_riscv_c_bigimmint), 1711*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.jal", DIS_RISCV_CL_32, 0x01, 0x01, 1712*1f154020SRobert Mustacchi dis_riscv_c_j), 1713*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.addiw", DIS_RISCV_CL_64_128, 0x01, 0x01, 1714*1f154020SRobert Mustacchi dis_riscv_c_bigimmint), 1715*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.li", DIS_RISCV_CL_ALL, 0x01, 0x02, 1716*1f154020SRobert Mustacchi dis_riscv_c_bigimmint), 1717*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.addi16sp", DIS_RISCV_CL_ALL, 0x01, 0x03, 0x0f80, 1718*1f154020SRobert Mustacchi 0x0100, dis_riscv_c_addi16sp), 1719*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.lui", DIS_RISCV_CL_ALL, 0x01, 0x03, 1720*1f154020SRobert Mustacchi dis_riscv_c_zext_bigimmint), 1721*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.srli", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0000, 1722*1f154020SRobert Mustacchi dis_riscv_c_zext_immint), 1723*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.srai", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0400, 1724*1f154020SRobert Mustacchi dis_riscv_c_zext_immint), 1725*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.andi", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0800, 1726*1f154020SRobert Mustacchi dis_riscv_c_immint), 1727*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.sub", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c00, 1728*1f154020SRobert Mustacchi dis_riscv_c_int), 1729*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.xor", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c20, 1730*1f154020SRobert Mustacchi dis_riscv_c_int), 1731*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.or", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c40, 1732*1f154020SRobert Mustacchi dis_riscv_c_int), 1733*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.and", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c60, 1734*1f154020SRobert Mustacchi dis_riscv_c_int), 1735*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.subw", DIS_RISCV_CL_64_128, 0x1, 0x4, 0x1c60, 1736*1f154020SRobert Mustacchi 0x1c00, dis_riscv_c_int), 1737*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.addw", DIS_RISCV_CL_64_128, 0x1, 0x4, 0x1c60, 1738*1f154020SRobert Mustacchi 0x1c20, dis_riscv_c_int), 1739*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.j", DIS_RISCV_CL_ALL, 0x1, 0x5, 1740*1f154020SRobert Mustacchi dis_riscv_c_j), 1741*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.beqz", DIS_RISCV_CL_ALL, 0x1, 0x6, 1742*1f154020SRobert Mustacchi dis_riscv_c_branch), 1743*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.bnez", DIS_RISCV_CL_ALL, 0x1, 0x7, 1744*1f154020SRobert Mustacchi dis_riscv_c_branch), 1745*1f154020SRobert Mustacchi /* Quadrant 2 */ 1746*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.slli", DIS_RISCV_CL_ALL, 0x2, 0x0, 1747*1f154020SRobert Mustacchi dis_riscv_c_zext_bigimmint), 1748*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fldsp", DIS_RISCV_CL_32_64, 0x2, 0x1, 1749*1f154020SRobert Mustacchi dis_riscv_c_fldsp), 1750*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.lwsp", DIS_RISCV_CL_ALL, 0x2, 0x2, 1751*1f154020SRobert Mustacchi dis_riscv_c_lwsp), 1752*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.flwsp", DIS_RISCV_CL_32, 0x2, 0x3, 1753*1f154020SRobert Mustacchi dis_riscv_c_flwsp), 1754*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.ldsp", DIS_RISCV_CL_64_128, 0x2, 0x3, 1755*1f154020SRobert Mustacchi dis_riscv_c_ldsp), 1756*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.jr", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x107c, 0x0, 1757*1f154020SRobert Mustacchi dis_riscv_c_jr), 1758*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.mv", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1000, 0x0, 1759*1f154020SRobert Mustacchi dis_riscv_c_bigint), 1760*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.ebreak", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1ffc, 0x1000, 1761*1f154020SRobert Mustacchi dis_riscv_c_name), 1762*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.jalr", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x107c, 0x1000, 1763*1f154020SRobert Mustacchi dis_riscv_c_jr), 1764*1f154020SRobert Mustacchi DIS_RISCV_CMATCH("c.add", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1000, 0x1000, 1765*1f154020SRobert Mustacchi dis_riscv_c_bigint), 1766*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fsdsp", DIS_RISCV_CL_32_64, 0x2, 0x5, 1767*1f154020SRobert Mustacchi dis_riscv_c_fsdsp), 1768*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.swsp", DIS_RISCV_CL_ALL, 0x2, 0x6, 1769*1f154020SRobert Mustacchi dis_riscv_c_swsp), 1770*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.fswsp", DIS_RISCV_CL_32, 0x2, 0x7, 1771*1f154020SRobert Mustacchi dis_riscv_c_fswsp), 1772*1f154020SRobert Mustacchi DIS_RISCV_CFUNCT3("c.sdsp", DIS_RISCV_CL_64_128, 0x2, 0x7, 1773*1f154020SRobert Mustacchi dis_riscv_c_sdsp), 1774*1f154020SRobert Mustacchi }; 1775*1f154020SRobert Mustacchi 1776*1f154020SRobert Mustacchi static void 1777*1f154020SRobert Mustacchi dis_riscv_decode_2byte(dis_handle_t *dhp, uint32_t instr, char *buf, 1778*1f154020SRobert Mustacchi size_t buflen) 1779*1f154020SRobert Mustacchi { 1780*1f154020SRobert Mustacchi uint_t i; 1781*1f154020SRobert Mustacchi 1782*1f154020SRobert Mustacchi for (i = 0; i < ARRAY_SIZE(dis_riscv_2byte); i++) { 1783*1f154020SRobert Mustacchi dis_riscv_c_instr_t *t = &dis_riscv_2byte[i]; 1784*1f154020SRobert Mustacchi switch (t->drv_c_class) { 1785*1f154020SRobert Mustacchi case DIS_RISCV_CL_ALL: 1786*1f154020SRobert Mustacchi break; 1787*1f154020SRobert Mustacchi case DIS_RISCV_CL_32: 1788*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_RISCV_32) == 0) 1789*1f154020SRobert Mustacchi continue; 1790*1f154020SRobert Mustacchi break; 1791*1f154020SRobert Mustacchi case DIS_RISCV_CL_64: 1792*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_RISCV_64) == 0) 1793*1f154020SRobert Mustacchi continue; 1794*1f154020SRobert Mustacchi break; 1795*1f154020SRobert Mustacchi case DIS_RISCV_CL_32_64: 1796*1f154020SRobert Mustacchi if ((dhp->dh_flags & 1797*1f154020SRobert Mustacchi (DIS_RISCV_32 | DIS_RISCV_64)) == 0) { 1798*1f154020SRobert Mustacchi continue; 1799*1f154020SRobert Mustacchi } 1800*1f154020SRobert Mustacchi break; 1801*1f154020SRobert Mustacchi case DIS_RISCV_CL_64_128: 1802*1f154020SRobert Mustacchi if ((dhp->dh_flags & DIS_RISCV_64) == 0) 1803*1f154020SRobert Mustacchi continue; 1804*1f154020SRobert Mustacchi break; 1805*1f154020SRobert Mustacchi } 1806*1f154020SRobert Mustacchi 1807*1f154020SRobert Mustacchi switch (t->drv_c_type) { 1808*1f154020SRobert Mustacchi case DIS_RISCV_C_FUNCT3: 1809*1f154020SRobert Mustacchi if (DIS_RISCV_C_OPCODE(instr) == t->drv_c_opcode && 1810*1f154020SRobert Mustacchi DIS_RISCV_C_FUNCT3(instr) == t->drv_c_funct) { 1811*1f154020SRobert Mustacchi break; 1812*1f154020SRobert Mustacchi } 1813*1f154020SRobert Mustacchi continue; 1814*1f154020SRobert Mustacchi case DIS_RISCV_C_MATCH: 1815*1f154020SRobert Mustacchi if (DIS_RISCV_C_OPCODE(instr) == t->drv_c_opcode && 1816*1f154020SRobert Mustacchi DIS_RISCV_C_FUNCT3(instr) == t->drv_c_funct && 1817*1f154020SRobert Mustacchi ((instr & t->drv_c_mask) == t->drv_c_match)) { 1818*1f154020SRobert Mustacchi break; 1819*1f154020SRobert Mustacchi } 1820*1f154020SRobert Mustacchi continue; 1821*1f154020SRobert Mustacchi default: 1822*1f154020SRobert Mustacchi continue; 1823*1f154020SRobert Mustacchi } 1824*1f154020SRobert Mustacchi 1825*1f154020SRobert Mustacchi t->drv_c_print(dhp, instr, t, buf, buflen); 1826*1f154020SRobert Mustacchi return; 1827*1f154020SRobert Mustacchi } 1828*1f154020SRobert Mustacchi 1829*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "<unknown>"); 1830*1f154020SRobert Mustacchi } 1831*1f154020SRobert Mustacchi 1832*1f154020SRobert Mustacchi 1833*1f154020SRobert Mustacchi /* 1834*1f154020SRobert Mustacchi * RISC-V instructions always come in parcels of two bytes. Read the next two 1835*1f154020SRobert Mustacchi * byte parcel and advance the address in the handle. Also, take care of endian 1836*1f154020SRobert Mustacchi * issues if required. 1837*1f154020SRobert Mustacchi */ 1838*1f154020SRobert Mustacchi static int 1839*1f154020SRobert Mustacchi dis_riscv_read_parcel(dis_handle_t *dhp, uint16_t *valp) 1840*1f154020SRobert Mustacchi { 1841*1f154020SRobert Mustacchi if ((dhp->dh_addr % 2) != 0) 1842*1f154020SRobert Mustacchi return (-1); 1843*1f154020SRobert Mustacchi 1844*1f154020SRobert Mustacchi if (dhp->dh_read(dhp->dh_data, dhp->dh_addr, valp, sizeof (*valp)) != 1845*1f154020SRobert Mustacchi sizeof (*valp)) 1846*1f154020SRobert Mustacchi return (-1); 1847*1f154020SRobert Mustacchi 1848*1f154020SRobert Mustacchi *valp = LE_16(*valp); 1849*1f154020SRobert Mustacchi 1850*1f154020SRobert Mustacchi dhp->dh_addr += 2; 1851*1f154020SRobert Mustacchi 1852*1f154020SRobert Mustacchi return (0); 1853*1f154020SRobert Mustacchi } 1854*1f154020SRobert Mustacchi 1855*1f154020SRobert Mustacchi /* 1856*1f154020SRobert Mustacchi * The first 'parcel' (uint16_t) of any instruction can be used to determine the 1857*1f154020SRobert Mustacchi * instruction length. This is derived from Section 1.2 Instruction Length 1858*1f154020SRobert Mustacchi * Encoding of Volume I: RISC-V User-Level ISA V2.2. 1859*1f154020SRobert Mustacchi * 1860*1f154020SRobert Mustacchi * | xxxxxxxxxxxxxxaa | 16-bit iff aa != 11 1861*1f154020SRobert Mustacchi * | xxxxxxxxxxxbbb11 | 32-bit iff bbb != 111 1862*1f154020SRobert Mustacchi * | xxxxxxxxxx011111 | 48-bit iff bbb != 111 1863*1f154020SRobert Mustacchi * | xxxxxxxxx0111111 | 64-bit iff bbb != 111 1864*1f154020SRobert Mustacchi * | xnnnxxxxx1111111 | (80 + 16*nnn)-bit iff nnn != 111 1865*1f154020SRobert Mustacchi */ 1866*1f154020SRobert Mustacchi #define RISCV_LEN_16_MASK 0x0003 1867*1f154020SRobert Mustacchi #define RISCV_LEN_32_MASK 0x001c 1868*1f154020SRobert Mustacchi #define RISCV_LEN_48_MASK 0x0020 1869*1f154020SRobert Mustacchi #define RISCV_LEN_64_MASK 0x0040 1870*1f154020SRobert Mustacchi #define RISCV_LEN_80_MASK 0x7000 1871*1f154020SRobert Mustacchi #define RISCV_LEN_80_SHIFT 12 1872*1f154020SRobert Mustacchi 1873*1f154020SRobert Mustacchi static int 1874*1f154020SRobert Mustacchi dis_riscv_decode_len(uint16_t instr) 1875*1f154020SRobert Mustacchi { 1876*1f154020SRobert Mustacchi if ((instr & RISCV_LEN_16_MASK) != RISCV_LEN_16_MASK) 1877*1f154020SRobert Mustacchi return (2); 1878*1f154020SRobert Mustacchi 1879*1f154020SRobert Mustacchi if ((instr & RISCV_LEN_32_MASK) != RISCV_LEN_32_MASK) 1880*1f154020SRobert Mustacchi return (4); 1881*1f154020SRobert Mustacchi 1882*1f154020SRobert Mustacchi if ((instr & RISCV_LEN_48_MASK) != RISCV_LEN_48_MASK) 1883*1f154020SRobert Mustacchi return (6); 1884*1f154020SRobert Mustacchi 1885*1f154020SRobert Mustacchi if ((instr & RISCV_LEN_64_MASK) != RISCV_LEN_64_MASK) 1886*1f154020SRobert Mustacchi return (8); 1887*1f154020SRobert Mustacchi 1888*1f154020SRobert Mustacchi if ((instr & RISCV_LEN_80_MASK) != RISCV_LEN_80_MASK) { 1889*1f154020SRobert Mustacchi uint_t factor = (instr & RISCV_LEN_80_MASK) >> 1890*1f154020SRobert Mustacchi RISCV_LEN_80_SHIFT; 1891*1f154020SRobert Mustacchi return ((10 + 2 * factor)); 1892*1f154020SRobert Mustacchi } 1893*1f154020SRobert Mustacchi 1894*1f154020SRobert Mustacchi return (-1); 1895*1f154020SRobert Mustacchi } 1896*1f154020SRobert Mustacchi 1897*1f154020SRobert Mustacchi static int 1898*1f154020SRobert Mustacchi dis_riscv_supports_flags(int flags) 1899*1f154020SRobert Mustacchi { 1900*1f154020SRobert Mustacchi int archflags = flags & DIS_ARCH_MASK; 1901*1f154020SRobert Mustacchi 1902*1f154020SRobert Mustacchi return (archflags == DIS_RISCV_32 || archflags == DIS_RISCV_64); 1903*1f154020SRobert Mustacchi } 1904*1f154020SRobert Mustacchi 1905*1f154020SRobert Mustacchi static int 1906*1f154020SRobert Mustacchi dis_riscv_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, 1907*1f154020SRobert Mustacchi size_t buflen) 1908*1f154020SRobert Mustacchi { 1909*1f154020SRobert Mustacchi int len; 1910*1f154020SRobert Mustacchi uint16_t parcel; 1911*1f154020SRobert Mustacchi uint32_t instr; 1912*1f154020SRobert Mustacchi 1913*1f154020SRobert Mustacchi 1914*1f154020SRobert Mustacchi dhp->dh_addr = addr; 1915*1f154020SRobert Mustacchi 1916*1f154020SRobert Mustacchi /* 1917*1f154020SRobert Mustacchi * All instructions have to be 2-byte aligned. Most have to be four byte 1918*1f154020SRobert Mustacchi * aligned, but we determine that after we decode the instruction size. 1919*1f154020SRobert Mustacchi * The 2-byte alignment check is done when we read the parcel. 1920*1f154020SRobert Mustacchi */ 1921*1f154020SRobert Mustacchi if (dis_riscv_read_parcel(dhp, &parcel) != 0) 1922*1f154020SRobert Mustacchi return (-1); 1923*1f154020SRobert Mustacchi 1924*1f154020SRobert Mustacchi len = dis_riscv_decode_len(parcel); 1925*1f154020SRobert Mustacchi if (len < 2 || (len % 2) != 0) 1926*1f154020SRobert Mustacchi return (-1); 1927*1f154020SRobert Mustacchi switch (len) { 1928*1f154020SRobert Mustacchi case 2: 1929*1f154020SRobert Mustacchi instr = parcel; 1930*1f154020SRobert Mustacchi dis_riscv_decode_2byte(dhp, instr, buf, buflen); 1931*1f154020SRobert Mustacchi break; 1932*1f154020SRobert Mustacchi case 4: 1933*1f154020SRobert Mustacchi instr = parcel; 1934*1f154020SRobert Mustacchi if (dis_riscv_read_parcel(dhp, &parcel) != 0) 1935*1f154020SRobert Mustacchi return (-1); 1936*1f154020SRobert Mustacchi instr |= parcel << 16; 1937*1f154020SRobert Mustacchi dis_riscv_decode_4byte(dhp, instr, buf, buflen); 1938*1f154020SRobert Mustacchi break; 1939*1f154020SRobert Mustacchi default: 1940*1f154020SRobert Mustacchi /* 1941*1f154020SRobert Mustacchi * This case represents a valid instruction length, but 1942*1f154020SRobert Mustacchi * something we don't understand. Treat this as an unknown 1943*1f154020SRobert Mustacchi * instruction. However, read the rest of the length of the 1944*1f154020SRobert Mustacchi * instruction to make sure that we read things correctly. 1945*1f154020SRobert Mustacchi */ 1946*1f154020SRobert Mustacchi (void) dis_snprintf(buf, buflen, "<unknown>"); 1947*1f154020SRobert Mustacchi for (; len > 0; len -= 2) { 1948*1f154020SRobert Mustacchi if (dis_riscv_read_parcel(dhp, &parcel) != 0) { 1949*1f154020SRobert Mustacchi return (-1); 1950*1f154020SRobert Mustacchi } 1951*1f154020SRobert Mustacchi } 1952*1f154020SRobert Mustacchi break; 1953*1f154020SRobert Mustacchi } 1954*1f154020SRobert Mustacchi 1955*1f154020SRobert Mustacchi return (0); 1956*1f154020SRobert Mustacchi } 1957*1f154020SRobert Mustacchi 1958*1f154020SRobert Mustacchi /*ARGSUSED*/ 1959*1f154020SRobert Mustacchi static int 1960*1f154020SRobert Mustacchi dis_riscv_min_instrlen(dis_handle_t *dhp) 1961*1f154020SRobert Mustacchi { 1962*1f154020SRobert Mustacchi return (2); 1963*1f154020SRobert Mustacchi } 1964*1f154020SRobert Mustacchi 1965*1f154020SRobert Mustacchi /*ARGSUSED*/ 1966*1f154020SRobert Mustacchi static int 1967*1f154020SRobert Mustacchi dis_riscv_max_instrlen(dis_handle_t *dhp) 1968*1f154020SRobert Mustacchi { 1969*1f154020SRobert Mustacchi return (22); 1970*1f154020SRobert Mustacchi } 1971*1f154020SRobert Mustacchi 1972*1f154020SRobert Mustacchi static int 1973*1f154020SRobert Mustacchi dis_riscv_instrlen(dis_handle_t *dhp, uint64_t addr) 1974*1f154020SRobert Mustacchi { 1975*1f154020SRobert Mustacchi int ret; 1976*1f154020SRobert Mustacchi uint16_t parcel; 1977*1f154020SRobert Mustacchi 1978*1f154020SRobert Mustacchi dhp->dh_addr = addr; 1979*1f154020SRobert Mustacchi 1980*1f154020SRobert Mustacchi if (dis_riscv_read_parcel(dhp, &parcel) != 0) 1981*1f154020SRobert Mustacchi return (-1); 1982*1f154020SRobert Mustacchi 1983*1f154020SRobert Mustacchi /* 1984*1f154020SRobert Mustacchi * Get length based on this parcel. Check for required alignment. 2-byte 1985*1f154020SRobert Mustacchi * alignment was already taken care of when we read the parcel. 1986*1f154020SRobert Mustacchi */ 1987*1f154020SRobert Mustacchi ret = dis_riscv_decode_len(parcel); 1988*1f154020SRobert Mustacchi if (ret >= 4 && (addr % 4) != 0) 1989*1f154020SRobert Mustacchi return (-1); 1990*1f154020SRobert Mustacchi 1991*1f154020SRobert Mustacchi return (ret); 1992*1f154020SRobert Mustacchi } 1993*1f154020SRobert Mustacchi 1994*1f154020SRobert Mustacchi dis_arch_t dis_arch_riscv = { 1995*1f154020SRobert Mustacchi .da_supports_flags = dis_riscv_supports_flags, 1996*1f154020SRobert Mustacchi .da_disassemble = dis_riscv_disassemble, 1997*1f154020SRobert Mustacchi .da_min_instrlen = dis_riscv_min_instrlen, 1998*1f154020SRobert Mustacchi .da_max_instrlen = dis_riscv_max_instrlen, 1999*1f154020SRobert Mustacchi .da_instrlen = dis_riscv_instrlen 2000*1f154020SRobert Mustacchi }; 2001