The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/riscv/riscv/db_disasm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2016-2018 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Portions of this software were developed by SRI International and the
    6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Portions of this software were developed by the University of Cambridge
   10  * Computer Laboratory as part of the CTSRD Project, with support from the
   11  * UK Higher Education Innovation Fund (HEIF).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD$");
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <ddb/ddb.h>
   41 #include <ddb/db_access.h>
   42 #include <ddb/db_sym.h>
   43 
   44 #include <machine/encoding.h>
   45 
   46 #define X_RA    1
   47 #define X_SP    2
   48 #define X_GP    3
   49 #define X_TP    4
   50 #define X_T0    5
   51 #define X_T1    6
   52 #define X_T2    7
   53 #define X_T3    28
   54 
   55 #define RD_SHIFT        7
   56 #define RD_MASK         (0x1f << RD_SHIFT)
   57 #define RS1_SHIFT       15
   58 #define RS1_MASK        (0x1f << RS1_SHIFT)
   59 #define RS2_SHIFT       20
   60 #define RS2_MASK        (0x1f << RS2_SHIFT)
   61 #define IMM_SHIFT       20
   62 #define IMM_MASK        (0xfff << IMM_SHIFT)
   63 
   64 static char *reg_name[32] = {
   65         "zero", "ra",   "sp",   "gp",   "tp",   "t0",   "t1",   "t2",
   66         "s0",   "s1",   "a0",   "a1",   "a2",   "a3",   "a4",   "a5",
   67         "a6",   "a7",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
   68         "s8",   "s9",   "s10",  "s11",  "t3",   "t4",   "t5",   "t6"
   69 };
   70 
   71 static char *fp_reg_name[32] = {
   72         "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
   73         "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
   74         "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
   75         "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
   76 };
   77 
   78 struct riscv_op {
   79         char *name;
   80         char *fmt;
   81         int match;
   82         int mask;
   83         int (*match_func)(struct riscv_op *op, uint32_t insn);
   84 };
   85 
   86 static int
   87 m_op(struct riscv_op *op, uint32_t insn)
   88 {
   89 
   90         if (((insn ^ op->match) & op->mask) == 0)
   91                 return (1);
   92 
   93         return (0);
   94 }
   95 
   96 static struct riscv_op riscv_opcodes[] = {
   97         /* Aliases first */
   98         {"ret","", MATCH_JALR | (X_RA << RS1_SHIFT),
   99             MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK, m_op },
  100 
  101         { "beq",        "s,t,p",        MATCH_BEQ, MASK_BEQ,            m_op },
  102         { "bne",        "s,t,p",        MATCH_BNE, MASK_BNE,            m_op },
  103         { "blt",        "s,t,p",        MATCH_BLT, MASK_BLT,            m_op },
  104         { "bge",        "s,t,p",        MATCH_BGE, MASK_BGE,            m_op },
  105         { "bltu",       "s,t,p",        MATCH_BLTU, MASK_BLTU,          m_op },
  106         { "bgeu",       "s,t,p",        MATCH_BGEU, MASK_BGEU,          m_op },
  107         { "jalr",       "d,o(s)",       MATCH_JALR, MASK_JALR,          m_op },
  108         { "jal",        "d,a",          MATCH_JAL, MASK_JAL,            m_op },
  109         { "lui",        "d,u",          MATCH_LUI, MASK_LUI,            m_op },
  110         { "auipc",      "d,u",          MATCH_AUIPC, MASK_AUIPC,        m_op },
  111         { "addi",       "d,s,j",        MATCH_ADDI, MASK_ADDI,          m_op },
  112         { "slli",       "d,s,>",        MATCH_SLLI, MASK_SLLI,          m_op },
  113         { "slti",       "d,s,j",        MATCH_SLTI, MASK_SLTI,          m_op },
  114         { "sltiu",      "d,s,j",        MATCH_SLTIU, MASK_SLTIU,        m_op },
  115         { "xori",       "d,s,j",        MATCH_XORI, MASK_XORI,          m_op },
  116         { "srli",       "d,s,>",        MATCH_SRLI, MASK_SRLI,          m_op },
  117         { "srai",       "d,s,>",        MATCH_SRAI, MASK_SRAI,          m_op },
  118         { "ori",        "d,s,j",        MATCH_ORI, MASK_ORI,            m_op },
  119         { "andi",       "d,s,j",        MATCH_ANDI, MASK_ANDI,          m_op },
  120         { "add",        "d,s,t",        MATCH_ADD, MASK_ADD,            m_op },
  121         { "sub",        "d,s,t",        MATCH_SUB, MASK_SUB,            m_op },
  122         { "sll",        "d,s,t",        MATCH_SLL, MASK_SLL,            m_op },
  123         { "slt",        "d,s,t",        MATCH_SLT, MASK_SLT,            m_op },
  124         { "sltu",       "d,s,t",        MATCH_SLTU, MASK_SLTU,          m_op },
  125         { "xor",        "d,s,t",        MATCH_XOR, MASK_XOR,            m_op },
  126         { "srl",        "d,s,t",        MATCH_SRL, MASK_SRL,            m_op },
  127         { "sra",        "d,s,t",        MATCH_SRA, MASK_SRA,            m_op },
  128         { "or",         "d,s,t",        MATCH_OR, MASK_OR,              m_op },
  129         { "and",        "d,s,t",        MATCH_AND, MASK_AND,            m_op },
  130         { "addiw",      "d,s,j",        MATCH_ADDIW, MASK_ADDIW,        m_op },
  131         { "slliw",      "d,s,<",        MATCH_SLLIW, MASK_SLLIW,        m_op },
  132         { "srliw",      "d,s,<",        MATCH_SRLIW, MASK_SRLIW,        m_op },
  133         { "sraiw",      "d,s,<",        MATCH_SRAIW, MASK_SRAIW,        m_op },
  134         { "addw",       "d,s,t",        MATCH_ADDW, MASK_ADDW,          m_op },
  135         { "subw",       "d,s,t",        MATCH_SUBW, MASK_SUBW,          m_op },
  136         { "sllw",       "d,s,t",        MATCH_SLLW, MASK_SLLW,          m_op },
  137         { "srlw",       "d,s,t",        MATCH_SRLW, MASK_SRLW,          m_op },
  138         { "sraw",       "d,s,t",        MATCH_SRAW, MASK_SRAW,          m_op },
  139         { "lb",         "d,o(s)",       MATCH_LB, MASK_LB,              m_op },
  140         { "lh",         "d,o(s)",       MATCH_LH, MASK_LH,              m_op },
  141         { "lw",         "d,o(s)",       MATCH_LW, MASK_LW,              m_op },
  142         { "ld",         "d,o(s)",       MATCH_LD, MASK_LD,              m_op },
  143         { "lbu",        "d,o(s)",       MATCH_LBU, MASK_LBU,            m_op },
  144         { "lhu",        "d,o(s)",       MATCH_LHU, MASK_LHU,            m_op },
  145         { "lwu",        "d,o(s)",       MATCH_LWU, MASK_LWU,            m_op },
  146         { "sb",         "t,q(s)",       MATCH_SB, MASK_SB,              m_op },
  147         { "sh",         "t,q(s)",       MATCH_SH, MASK_SH,              m_op },
  148         { "sw",         "t,q(s)",       MATCH_SW, MASK_SW,              m_op },
  149         { "sd",         "t,q(s)",       MATCH_SD, MASK_SD,              m_op },
  150         { "fence",      "P,Q",          MATCH_FENCE, MASK_FENCE,        m_op },
  151         { "fence.i",    "",             MATCH_FENCE_I, MASK_FENCE_I,    m_op },
  152         { "mul",        "d,s,t",        MATCH_MUL, MASK_MUL,            m_op },
  153         { "mulh",       "d,s,t",        MATCH_MULH, MASK_MULH,          m_op },
  154         { "mulhsu",     "d,s,t",        MATCH_MULHSU, MASK_MULHSU,      m_op },
  155         { "mulhu",      "d,s,t",        MATCH_MULHU, MASK_MULHU,        m_op },
  156         { "div",        "d,s,t",        MATCH_DIV, MASK_DIV,            m_op },
  157         { "divu",       "d,s,t",        MATCH_DIVU, MASK_DIVU,          m_op },
  158         { "rem",        "d,s,t",        MATCH_REM, MASK_REM,            m_op },
  159         { "remu",       "d,s,t",        MATCH_REMU, MASK_REMU,          m_op },
  160         { "mulw",       "d,s,t",        MATCH_MULW, MASK_MULW,          m_op },
  161         { "divw",       "d,s,t",        MATCH_DIVW, MASK_DIVW,          m_op },
  162         { "divuw",      "d,s,t",        MATCH_DIVUW, MASK_DIVUW,        m_op },
  163         { "remw",       "d,s,t",        MATCH_REMW, MASK_REMW,          m_op },
  164         { "remuw",      "d,s,t",        MATCH_REMUW, MASK_REMUW,        m_op },
  165         { "amoadd.w",   "d,t,0(s)",     MATCH_AMOADD_W, MASK_AMOADD_W,  m_op },
  166         { "amoxor.w",   "d,t,0(s)",     MATCH_AMOXOR_W, MASK_AMOXOR_W,  m_op },
  167         { "amoor.w",    "d,t,0(s)",     MATCH_AMOOR_W, MASK_AMOOR_W,    m_op },
  168         { "amoand.w",   "d,t,0(s)",     MATCH_AMOAND_W, MASK_AMOAND_W,  m_op },
  169         { "amomin.w",   "d,t,0(s)",     MATCH_AMOMIN_W, MASK_AMOMIN_W,  m_op },
  170         { "amomax.w",   "d,t,0(s)",     MATCH_AMOMAX_W, MASK_AMOMAX_W,  m_op },
  171         { "amominu.w",  "d,t,0(s)",     MATCH_AMOMINU_W, MASK_AMOMINU_W,m_op },
  172         { "amomaxu.w",  "d,t,0(s)",     MATCH_AMOMAXU_W, MASK_AMOMAXU_W,m_op },
  173         { "amoswap.w",  "d,t,0(s)",     MATCH_AMOSWAP_W, MASK_AMOSWAP_W,m_op },
  174         { "lr.w",       "d,0(s)",       MATCH_LR_W, MASK_LR_W,          m_op },
  175         { "sc.w",       "d,t,0(s)",     MATCH_SC_W, MASK_SC_W,          m_op },
  176         { "amoadd.d",   "d,t,0(s)",     MATCH_AMOADD_D, MASK_AMOADD_D,  m_op },
  177         { "amoxor.d",   "d,t,0(s)",     MATCH_AMOXOR_D, MASK_AMOXOR_D,  m_op },
  178         { "amoor.d",    "d,t,0(s)",     MATCH_AMOOR_D, MASK_AMOOR_D,    m_op },
  179         { "amoand.d",   "d,t,0(s)",     MATCH_AMOAND_D, MASK_AMOAND_D,  m_op },
  180         { "amomin.d",   "d,t,0(s)",     MATCH_AMOMIN_D, MASK_AMOMIN_D,  m_op },
  181         { "amomax.d",   "d,t,0(s)",     MATCH_AMOMAX_D, MASK_AMOMAX_D,  m_op },
  182         { "amominu.d",  "d,t,0(s)",     MATCH_AMOMINU_D, MASK_AMOMINU_D,m_op },
  183         { "amomaxu.d",  "d,t,0(s)",     MATCH_AMOMAXU_D, MASK_AMOMAXU_D,m_op },
  184         { "amoswap.d",  "d,t,0(s)",     MATCH_AMOSWAP_D, MASK_AMOSWAP_D,m_op },
  185         { "lr.d",       "d,0(s)",       MATCH_LR_D, MASK_LR_D,          m_op },
  186         { "sc.d",       "d,t,0(s)",     MATCH_SC_D, MASK_SC_D,          m_op },
  187         { "ecall",      "",             MATCH_ECALL, MASK_ECALL,        m_op },
  188         { "ebreak",     "",             MATCH_EBREAK, MASK_EBREAK,      m_op },
  189         { "uret",       "",             MATCH_URET, MASK_URET,          m_op },
  190         { "sret",       "",             MATCH_SRET, MASK_SRET,          m_op },
  191         { "mret",       "",             MATCH_MRET, MASK_MRET,          m_op },
  192         { "dret",       "",             MATCH_DRET, MASK_DRET,          m_op },
  193         { "sfence.vma", "",     MATCH_SFENCE_VMA, MASK_SFENCE_VMA,      m_op },
  194         { "wfi",        "",             MATCH_WFI, MASK_WFI,            m_op },
  195         { "csrrw",      "d,E,s",        MATCH_CSRRW, MASK_CSRRW,        m_op },
  196         { "csrrs",      "d,E,s",        MATCH_CSRRS, MASK_CSRRS,        m_op },
  197         { "csrrc",      "d,E,s",        MATCH_CSRRC, MASK_CSRRC,        m_op },
  198         { "csrrwi",     "d,E,Z",        MATCH_CSRRWI, MASK_CSRRWI,      m_op },
  199         { "csrrsi",     "d,E,Z",        MATCH_CSRRSI, MASK_CSRRSI,      m_op },
  200         { "csrrci",     "d,E,Z",        MATCH_CSRRCI, MASK_CSRRCI,      m_op },
  201         { "fadd.s",     "D,S,T",        MATCH_FADD_S, MASK_FADD_S,      m_op },
  202         { "fsub.s",     "D,S,T",        MATCH_FSUB_S, MASK_FSUB_S,      m_op },
  203         { "fmul.s",     "D,S,T",        MATCH_FMUL_S, MASK_FMUL_S,      m_op },
  204         { "fdiv.s",     "D,S,T",        MATCH_FDIV_S, MASK_FDIV_S,      m_op },
  205         { "fsgnj.s",    "D,S,T",        MATCH_FSGNJ_S, MASK_FSGNJ_S,    m_op },
  206         { "fsgnjn.s",   "D,S,T",        MATCH_FSGNJN_S, MASK_FSGNJN_S,  m_op },
  207         { "fsgnjx.s",   "D,S,T",        MATCH_FSGNJX_S, MASK_FSGNJX_S,  m_op },
  208         { "fmin.s",     "D,S,T",        MATCH_FMIN_S, MASK_FMIN_S,      m_op },
  209         { "fmax.s",     "D,S,T",        MATCH_FMAX_S, MASK_FMAX_S,      m_op },
  210         { "fsqrt.s",    "D,S",          MATCH_FSQRT_S, MASK_FSQRT_S,    m_op },
  211         { "fadd.d",     "D,S,T",        MATCH_FADD_D, MASK_FADD_D,      m_op },
  212         { "fsub.d",     "D,S,T",        MATCH_FSUB_D, MASK_FSUB_D,      m_op },
  213         { "fmul.d",     "D,S,T",        MATCH_FMUL_D, MASK_FMUL_D,      m_op },
  214         { "fdiv.d",     "D,S,T",        MATCH_FDIV_D, MASK_FDIV_D,      m_op },
  215         { "fsgnj.d",    "D,S,T",        MATCH_FSGNJ_D, MASK_FSGNJ_D,    m_op },
  216         { "fsgnjn.d",   "D,S,T",        MATCH_FSGNJN_D, MASK_FSGNJN_D,  m_op },
  217         { "fsgnjx.d",   "D,S,T",        MATCH_FSGNJX_D, MASK_FSGNJX_D,  m_op },
  218         { "fmin.d",     "D,S,T",        MATCH_FMIN_D, MASK_FMIN_D,      m_op },
  219         { "fmax.d",     "D,S,T",        MATCH_FMAX_D, MASK_FMAX_D,      m_op },
  220         { "fcvt.s.d",   "D,S",          MATCH_FCVT_S_D, MASK_FCVT_S_D,  m_op },
  221         { "fcvt.d.s",   "D,S",          MATCH_FCVT_D_S, MASK_FCVT_D_S,  m_op },
  222         { "fsqrt.d",    "D,S",          MATCH_FSQRT_D, MASK_FSQRT_D,    m_op },
  223         { "fadd.q",     "D,S,T",        MATCH_FADD_Q, MASK_FADD_Q,      m_op },
  224         { "fsub.q",     "D,S,T",        MATCH_FSUB_Q, MASK_FSUB_Q,      m_op },
  225         { "fmul.q",     "D,S,T",        MATCH_FMUL_Q, MASK_FMUL_Q,      m_op },
  226         { "fdiv.q",     "D,S,T",        MATCH_FDIV_Q, MASK_FDIV_Q,      m_op },
  227         { "fsgnj.q",    "D,S,T",        MATCH_FSGNJ_Q, MASK_FSGNJ_Q,    m_op },
  228         { "fsgnjn.q",   "D,S,T",        MATCH_FSGNJN_Q, MASK_FSGNJN_Q,  m_op },
  229         { "fsgnjx.q",   "D,S,T",        MATCH_FSGNJX_Q, MASK_FSGNJX_Q,  m_op },
  230         { "fmin.q",     "D,S,T",        MATCH_FMIN_Q, MASK_FMIN_Q,      m_op },
  231         { "fmax.q",     "D,S,T",        MATCH_FMAX_Q, MASK_FMAX_Q,      m_op },
  232         { "fcvt.s.q",   "D,S",          MATCH_FCVT_S_Q, MASK_FCVT_S_Q,  m_op },
  233         { "fcvt.q.s",   "D,S",          MATCH_FCVT_Q_S, MASK_FCVT_Q_S,  m_op },
  234         { "fcvt.d.q",   "D,S",          MATCH_FCVT_D_Q, MASK_FCVT_D_Q,  m_op },
  235         { "fcvt.q.d",   "D,S",          MATCH_FCVT_Q_D, MASK_FCVT_Q_D,  m_op },
  236         { "fsqrt.q",    "D,S",          MATCH_FSQRT_Q, MASK_FSQRT_Q,    m_op },
  237         { "fle.s",      "d,S,T",        MATCH_FLE_S, MASK_FLE_S,        m_op },
  238         { "flt.s",      "d,S,T",        MATCH_FLT_S, MASK_FLT_S,        m_op },
  239         { "feq.s",      "d,S,T",        MATCH_FEQ_S, MASK_FEQ_S,        m_op },
  240         { "fle.d",      "d,S,T",        MATCH_FLE_D, MASK_FLE_D,        m_op },
  241         { "flt.d",      "d,S,T",        MATCH_FLT_D, MASK_FLT_D,        m_op },
  242         { "feq.d",      "d,S,T",        MATCH_FEQ_D, MASK_FEQ_D,        m_op },
  243         { "fle.q",      "d,S,T",        MATCH_FLE_Q, MASK_FLE_Q,        m_op },
  244         { "flt.q",      "d,S,T",        MATCH_FLT_Q, MASK_FLT_Q,        m_op },
  245         { "feq.q",      "d,S,T",        MATCH_FEQ_Q, MASK_FEQ_Q,        m_op },
  246         { "fcvt.w.s",   "d,S",          MATCH_FCVT_W_S, MASK_FCVT_W_S,  m_op },
  247         { "fcvt.wu.s",  "d,S",          MATCH_FCVT_WU_S, MASK_FCVT_WU_S,m_op },
  248         { "fcvt.l.s",   "d,S",          MATCH_FCVT_L_S, MASK_FCVT_L_S,  m_op },
  249         { "fcvt.lu.s",  "d,S",          MATCH_FCVT_LU_S, MASK_FCVT_LU_S,m_op },
  250         { "fmv.x.w",    "d,S",          MATCH_FMV_X_W, MASK_FMV_X_W,    m_op },
  251         { "fclass.s",   "d,S",          MATCH_FCLASS_S, MASK_FCLASS_S,  m_op },
  252         { "fcvt.w.d",   "d,S",          MATCH_FCVT_W_D, MASK_FCVT_W_D,  m_op },
  253         { "fcvt.wu.d",  "d,S",          MATCH_FCVT_WU_D, MASK_FCVT_WU_D,m_op },
  254         { "fcvt.l.d",   "d,S",          MATCH_FCVT_L_D, MASK_FCVT_L_D,  m_op },
  255         { "fcvt.lu.d",  "d,S",          MATCH_FCVT_LU_D, MASK_FCVT_LU_D,m_op },
  256         { "fmv.x.d",    "d,S",          MATCH_FMV_X_D, MASK_FMV_X_D,    m_op },
  257         { "fclass.d",   "d,S",          MATCH_FCLASS_D, MASK_FCLASS_D,  m_op },
  258         { "fcvt.w.q",   "d,S",          MATCH_FCVT_W_Q, MASK_FCVT_W_Q,  m_op },
  259         { "fcvt.wu.q",  "d,S",          MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q,m_op },
  260         { "fcvt.l.q",   "d,S",          MATCH_FCVT_L_Q, MASK_FCVT_L_Q,  m_op },
  261         { "fcvt.lu.q",  "d,S",          MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q,m_op },
  262         { "fmv.x.q",    "d,S",          MATCH_FMV_X_Q, MASK_FMV_X_Q,    m_op },
  263         { "fclass.q",   "d,S",          MATCH_FCLASS_Q, MASK_FCLASS_Q,  m_op },
  264         { "fcvt.s.w",   "D,s",          MATCH_FCVT_S_W, MASK_FCVT_S_W,  m_op },
  265         { "fcvt.s.wu",  "D,s",          MATCH_FCVT_S_WU, MASK_FCVT_S_WU,m_op },
  266         { "fcvt.s.l",   "D,s",          MATCH_FCVT_S_L, MASK_FCVT_S_L,  m_op },
  267         { "fcvt.s.lu",  "D,s",          MATCH_FCVT_S_LU, MASK_FCVT_S_LU,m_op },
  268         { "fmv.w.x",    "D,s",          MATCH_FMV_W_X, MASK_FMV_W_X,    m_op },
  269         { "fcvt.d.w",   "D,s",          MATCH_FCVT_D_W, MASK_FCVT_D_W,  m_op },
  270         { "fcvt.d.wu",  "D,s",          MATCH_FCVT_D_WU, MASK_FCVT_D_WU,m_op },
  271         { "fcvt.d.l",   "D,s",          MATCH_FCVT_D_L, MASK_FCVT_D_L,  m_op },
  272         { "fcvt.d.lu",  "D,s",          MATCH_FCVT_D_LU, MASK_FCVT_D_LU,m_op },
  273         { "fmv.d.x",    "D,s",          MATCH_FMV_D_X, MASK_FMV_D_X,    m_op },
  274         { "fcvt.q.w",   "D,s",          MATCH_FCVT_Q_W, MASK_FCVT_Q_W,  m_op },
  275         { "fcvt.q.wu",  "D,s",          MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU,m_op },
  276         { "fcvt.q.l",   "D,s",          MATCH_FCVT_Q_L, MASK_FCVT_Q_L,  m_op },
  277         { "fcvt.q.lu",  "D,s",          MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU,m_op },
  278         { "fmv.q.x",    "D,s",          MATCH_FMV_Q_X, MASK_FMV_Q_X,    m_op },
  279         { "flw",        "D,o(s)",       MATCH_FLW, MASK_FLW,            m_op },
  280         { "fld",        "D,o(s)",       MATCH_FLD, MASK_FLD,            m_op },
  281         { "flq",        "D,o(s)",       MATCH_FLQ, MASK_FLQ,            m_op },
  282         { "fsw",        "T,q(s)",       MATCH_FSW, MASK_FSW,            m_op },
  283         { "fsd",        "T,q(s)",       MATCH_FSD, MASK_FSD,            m_op },
  284         { "fsq",        "T,q(s)",       MATCH_FSQ, MASK_FSQ,            m_op },
  285         { "fmadd.s",    "D,S,T,R",      MATCH_FMADD_S, MASK_FMADD_S,    m_op },
  286         { "fmsub.s",    "D,S,T,R",      MATCH_FMSUB_S, MASK_FMSUB_S,    m_op },
  287         { "fnmsub.s",   "D,S,T,R",      MATCH_FNMSUB_S, MASK_FNMSUB_S,  m_op },
  288         { "fnmadd.s",   "D,S,T,R",      MATCH_FNMADD_S, MASK_FNMADD_S,  m_op },
  289         { "fmadd.d",    "D,S,T,R",      MATCH_FMADD_D, MASK_FMADD_D,    m_op },
  290         { "fmsub.d",    "D,S,T,R",      MATCH_FMSUB_D, MASK_FMSUB_D,    m_op },
  291         { "fnmsub.d",   "D,S,T,R",      MATCH_FNMSUB_D, MASK_FNMSUB_D,  m_op },
  292         { "fnmadd.d",   "D,S,T,R",      MATCH_FNMADD_D, MASK_FNMADD_D,  m_op },
  293         { "fmadd.q",    "D,S,T,R",      MATCH_FMADD_Q, MASK_FMADD_Q,    m_op },
  294         { "fmsub.q",    "D,S,T,R",      MATCH_FMSUB_Q, MASK_FMSUB_Q,    m_op },
  295         { "fnmsub.q",   "D,S,T,R",      MATCH_FNMSUB_Q, MASK_FNMSUB_Q,  m_op },
  296         { "fnmadd.q",   "D,S,T,R",      MATCH_FNMADD_Q, MASK_FNMADD_Q,  m_op },
  297         { NULL, NULL, 0, 0, NULL },
  298 };
  299 
  300 static struct riscv_op riscv_c_opcodes[] = {
  301         /* Aliases first */
  302         { "ret","",MATCH_C_JR | (X_RA << RD_SHIFT), MASK_C_JR | RD_MASK, m_op},
  303 
  304         /* C-Compressed ISA Extension Instructions */
  305         { "c.nop",      "",             MATCH_C_NOP, MASK_C_NOP,        m_op },
  306         { "c.ebreak",   "",             MATCH_C_EBREAK, MASK_C_EBREAK,  m_op },
  307         { "c.jr",       "d",            MATCH_C_JR, MASK_C_JR,          m_op },
  308         { "c.jalr",     "d",            MATCH_C_JALR, MASK_C_JALR,      m_op },
  309         { "c.jal",      "Ca",           MATCH_C_JAL, MASK_C_JAL,        m_op },
  310         { "c.ld",       "Ct,Cl(Cs)",    MATCH_C_LD, MASK_C_LD,          m_op },
  311         { "c.sd",       "Ct,Cl(Cs)",    MATCH_C_SD, MASK_C_SD,          m_op },
  312         { "c.addiw",    "d,Co",         MATCH_C_ADDIW, MASK_C_ADDIW,    m_op },
  313         { "c.ldsp",     "d,Cn(Cc)",     MATCH_C_LDSP, MASK_C_LDSP,      m_op },
  314         { "c.sdsp",     "CV,CN(Cc)",    MATCH_C_SDSP, MASK_C_SDSP,      m_op },
  315         { "c.addi4spn", "",     MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN,      m_op },
  316         { "c.addi16sp", "",     MATCH_C_ADDI16SP, MASK_C_ADDI16SP,      m_op },
  317         { "c.fld",      "CD,Cl(Cs)",    MATCH_C_FLD, MASK_C_FLD,        m_op },
  318         { "c.lw",       "Ct,Ck(Cs)",    MATCH_C_LW, MASK_C_LW,          m_op },
  319         { "c.flw",      "CD,Ck(Cs)",    MATCH_C_FLW, MASK_C_FLW,        m_op },
  320         { "c.fsd",      "CD,Cl(Cs)",    MATCH_C_FSD, MASK_C_FSD,        m_op },
  321         { "c.sw",       "Ct,Ck(Cs)",    MATCH_C_SW, MASK_C_SW,          m_op },
  322         { "c.fsw",      "CD,Ck(Cs)",    MATCH_C_FSW, MASK_C_FSW,        m_op },
  323         { "c.addi",     "d,Co",         MATCH_C_ADDI, MASK_C_ADDI,      m_op },
  324         { "c.li",       "d,Co",         MATCH_C_LI, MASK_C_LI,          m_op },
  325         { "c.lui",      "d,Cu",         MATCH_C_LUI, MASK_C_LUI,        m_op },
  326         { "c.srli",     "Cs,C>",        MATCH_C_SRLI, MASK_C_SRLI,      m_op },
  327         { "c.srai",     "Cs,C>",        MATCH_C_SRAI, MASK_C_SRAI,      m_op },
  328         { "c.andi",     "Cs,Co",        MATCH_C_ANDI, MASK_C_ANDI,      m_op },
  329         { "c.sub",      "Cs,Ct",        MATCH_C_SUB, MASK_C_SUB,        m_op },
  330         { "c.xor",      "Cs,Ct",        MATCH_C_XOR, MASK_C_XOR,        m_op },
  331         { "c.or",       "Cs,Ct",        MATCH_C_OR, MASK_C_OR,          m_op },
  332         { "c.and",      "Cs,Ct",        MATCH_C_AND, MASK_C_AND,        m_op },
  333         { "c.subw",     "Cs,Ct",        MATCH_C_SUBW, MASK_C_SUBW,      m_op },
  334         { "c.addw",     "Cs,Ct",        MATCH_C_ADDW, MASK_C_ADDW,      m_op },
  335         { "c.j",        "Ca",           MATCH_C_J, MASK_C_J,            m_op },
  336         { "c.beqz",     "Cs,Cp",        MATCH_C_BEQZ, MASK_C_BEQZ,      m_op },
  337         { "c.bnez",     "Cs,Cp",        MATCH_C_BNEZ, MASK_C_BNEZ,      m_op },
  338         { "c.slli",     "d,C>",         MATCH_C_SLLI, MASK_C_SLLI,      m_op },
  339         { "c.fldsp",    "D,Cn(Cc)",     MATCH_C_FLDSP, MASK_C_FLDSP,    m_op },
  340         { "c.lwsp",     "d,Cm(Cc)",     MATCH_C_LWSP, MASK_C_LWSP,      m_op },
  341         { "c.flwsp",    "D,Cm(Cc)",     MATCH_C_FLWSP, MASK_C_FLWSP,    m_op },
  342         { "c.mv",       "d,CV",         MATCH_C_MV, MASK_C_MV,          m_op },
  343         { "c.add",      "d,CV",         MATCH_C_ADD, MASK_C_ADD,        m_op },
  344         { "c.fsdsp",    "CT,CN(Cc)",    MATCH_C_FSDSP, MASK_C_FSDSP,    m_op },
  345         { "c.swsp",     "CV,CM(Cc)",    MATCH_C_SWSP, MASK_C_SWSP,      m_op },
  346         { "c.fswsp",    "CT,CM(Cc)",    MATCH_C_FSWSP, MASK_C_FSWSP,    m_op },
  347         { NULL, NULL, 0, 0, NULL },
  348 };
  349 
  350 static int
  351 oprint(struct riscv_op *op, vm_offset_t loc, int insn)
  352 {
  353         uint32_t rd, rs1, rs2, rs3;
  354         uint32_t val;
  355         const char *csr_name;
  356         int imm;
  357         char *p;
  358 
  359         p = op->fmt;
  360 
  361         rd = (insn & RD_MASK) >> RD_SHIFT;
  362         rs1 = (insn & RS1_MASK) >> RS1_SHIFT;
  363         rs2 = (insn & RS2_MASK) >> RS2_SHIFT;
  364 
  365         db_printf("%s\t", op->name);
  366 
  367         while (*p) {
  368                 switch (*p) {
  369                 case 'C':       /* C-Compressed ISA extension */
  370                         switch (*++p) {
  371                         case 't':
  372                                 rd = (insn >> 2) & 0x7;
  373                                 rd += 0x8;
  374                                 db_printf("%s", reg_name[rd]);
  375                                 break;
  376                         case 's':
  377                                 rs2 = (insn >> 7) & 0x7;
  378                                 rs2 += 0x8;
  379                                 db_printf("%s", reg_name[rs2]);
  380                                 break;
  381                         case 'l':
  382                                 imm = ((insn >> 10) & 0x7) << 3;
  383                                 imm |= ((insn >> 5) & 0x3) << 6;
  384                                 if (imm & (1 << 8))
  385                                         imm |= 0xffffff << 8;
  386                                 db_printf("%d", imm);
  387                                 break;
  388                         case 'k':
  389                                 imm = ((insn >> 10) & 0x7) << 3;
  390                                 imm |= ((insn >> 6) & 0x1) << 2;
  391                                 imm |= ((insn >> 5) & 0x1) << 6;
  392                                 if (imm & (1 << 8))
  393                                         imm |= 0xffffff << 8;
  394                                 db_printf("%d", imm);
  395                                 break;
  396                         case 'c':
  397                                 db_printf("sp");
  398                                 break;
  399                         case 'n':
  400                                 imm = ((insn >> 5) & 0x3) << 3;
  401                                 imm |= ((insn >> 12) & 0x1) << 5;
  402                                 imm |= ((insn >> 2) & 0x7) << 6;
  403                                 if (imm & (1 << 8))
  404                                         imm |= 0xffffff << 8;
  405                                 db_printf("%d", imm);
  406                                 break;
  407                         case 'N':
  408                                 imm = ((insn >> 10) & 0x7) << 3;
  409                                 imm |= ((insn >> 7) & 0x7) << 6;
  410                                 if (imm & (1 << 8))
  411                                         imm |= 0xffffff << 8;
  412                                 db_printf("%d", imm);
  413                                 break;
  414                         case 'u':
  415                                 imm = ((insn >> 2) & 0x1f) << 0;
  416                                 imm |= ((insn >> 12) & 0x1) << 5;
  417                                 if (imm & (1 << 5))
  418                                         imm |= (0x7ffffff << 5); /* sign ext */
  419                                 db_printf("0x%lx", imm);
  420                                 break;
  421                         case 'o':
  422                                 imm = ((insn >> 2) & 0x1f) << 0;
  423                                 imm |= ((insn >> 12) & 0x1) << 5;
  424                                 if (imm & (1 << 5))
  425                                         imm |= (0x7ffffff << 5); /* sign ext */
  426                                 db_printf("%d", imm);
  427                                 break;
  428                         case 'a':
  429                                 /* imm[11|4|9:8|10|6|7|3:1|5] << 2 */
  430                                 imm = ((insn >> 3) & 0x7) << 1;
  431                                 imm |= ((insn >> 11) & 0x1) << 4;
  432                                 imm |= ((insn >> 2) & 0x1) << 5;
  433                                 imm |= ((insn >> 7) & 0x1) << 6;
  434                                 imm |= ((insn >> 6) & 0x1) << 7;
  435                                 imm |= ((insn >> 9) & 0x3) << 8;
  436                                 imm |= ((insn >> 8) & 0x1) << 10;
  437                                 imm |= ((insn >> 12) & 0x1) << 11;
  438                                 if (imm & (1 << 11))
  439                                         imm |= (0xfffff << 12); /* sign ext */
  440                                 db_printf("0x%lx", (loc + imm));
  441                                 break;
  442                         case 'V':
  443                                 rs2 = (insn >> 2) & 0x1f;
  444                                 db_printf("%s", reg_name[rs2]);
  445                                 break;
  446                         case '>':
  447                                 imm = ((insn >> 2) & 0x1f) << 0;
  448                                 imm |= ((insn >> 12) & 0x1) << 5;
  449                                 db_printf("%d", imm);
  450                         };
  451                         break;
  452                 case 'd':
  453                         db_printf("%s", reg_name[rd]);
  454                         break;
  455                 case 'D':
  456                         db_printf("%s", fp_reg_name[rd]);
  457                         break;
  458                 case 's':
  459                         db_printf("%s", reg_name[rs1]);
  460                         break;
  461                 case 'S':
  462                         db_printf("%s", fp_reg_name[rs1]);
  463                         break;
  464                 case 't':
  465                         db_printf("%s", reg_name[rs2]);
  466                         break;
  467                 case 'T':
  468                         db_printf("%s", fp_reg_name[rs2]);
  469                         break;
  470                 case 'R':
  471                         rs3 = (insn >> 27) & 0x1f;
  472                         db_printf("%s", fp_reg_name[rs3]);
  473                         break;
  474                 case 'Z':
  475                         imm = (insn >> 15) & 0x1f;
  476                         db_printf("%d", imm);
  477                         break;
  478                 case 'p':
  479                         imm = ((insn >> 8) & 0xf) << 1;
  480                         imm |= ((insn >> 25) & 0x3f) << 5;
  481                         imm |= ((insn >> 7) & 0x1) << 11;
  482                         imm |= ((insn >> 31) & 0x1) << 12;
  483                         if (imm & (1 << 12))
  484                                 imm |= (0xfffff << 12); /* sign extend */
  485                         db_printf("0x%016lx", (loc + imm));
  486                         break;
  487                 case '(':
  488                 case ')':
  489                 case '[':
  490                 case ']':
  491                 case ',':
  492                         db_printf("%c", *p);
  493                         break;
  494                 case '':
  495                         if (!p[1])
  496                                 db_printf("%c", *p);
  497                         break;
  498                         
  499                 case 'o':
  500                         imm = (insn >> 20) & 0xfff;
  501                         if (imm & (1 << 11))
  502                                 imm |= (0xfffff << 12); /* sign extend */
  503                         db_printf("%d", imm);
  504                         break;
  505                 case 'q':
  506                         imm = (insn >> 7) & 0x1f;
  507                         imm |= ((insn >> 25) & 0x7f) << 5;
  508                         if (imm & (1 << 11))
  509                                 imm |= (0xfffff << 12); /* sign extend */
  510                         db_printf("%d", imm);
  511                         break;
  512                 case 'a':
  513                         /* imm[20|10:1|11|19:12] << 12 */
  514                         imm = ((insn >> 21) & 0x3ff) << 1;
  515                         imm |= ((insn >> 20) & 0x1) << 11;
  516                         imm |= ((insn >> 12) & 0xff) << 12;
  517                         imm |= ((insn >> 31) & 0x1) << 20;
  518                         if (imm & (1 << 20))
  519                                 imm |= (0xfff << 20);   /* sign extend */
  520                         db_printf("0x%lx", (loc + imm));
  521                         break;
  522                 case 'u':
  523                         /* imm[31:12] << 12 */
  524                         imm = (insn >> 12) & 0xfffff;
  525                         if (imm & (1 << 20))
  526                                 imm |= (0xfff << 20);   /* sign extend */
  527                         db_printf("0x%lx", imm);
  528                         break;
  529                 case 'j':
  530                         /* imm[11:0] << 20 */
  531                         imm = (insn >> 20) & 0xfff;
  532                         if (imm & (1 << 11))
  533                                 imm |= (0xfffff << 12); /* sign extend */
  534                         db_printf("%d", imm);
  535                         break;
  536                 case '>':
  537                         val = (insn >> 20) & 0x3f;
  538                         db_printf("0x%x", val);
  539                         break;
  540                 case '<':
  541                         val = (insn >> 20) & 0x1f;
  542                         db_printf("0x%x", val);
  543                         break;
  544                 case 'E':
  545                         val = (insn >> 20) & 0xfff;
  546                         csr_name = NULL;
  547                         switch (val) {
  548 #define DECLARE_CSR(name, num) case num: csr_name = #name; break;
  549 #include "machine/encoding.h"
  550 #undef DECLARE_CSR
  551                         }
  552                         if (csr_name)
  553                                 db_printf("%s", csr_name);
  554                         else
  555                                 db_printf("0x%x", val);
  556                         break;
  557                 case 'P':
  558                         if (insn & (1 << 27)) db_printf("i");
  559                         if (insn & (1 << 26)) db_printf("o");
  560                         if (insn & (1 << 25)) db_printf("r");
  561                         if (insn & (1 << 24)) db_printf("w");
  562                         break;
  563                 case 'Q':
  564                         if (insn & (1 << 23)) db_printf("i");
  565                         if (insn & (1 << 22)) db_printf("o");
  566                         if (insn & (1 << 21)) db_printf("r");
  567                         if (insn & (1 << 20)) db_printf("w");
  568                         break;
  569                 }
  570 
  571                 p++;
  572         }
  573 
  574         return (0);
  575 }
  576 
  577 vm_offset_t
  578 db_disasm(vm_offset_t loc, bool altfmt)
  579 {
  580         struct riscv_op *op;
  581         uint32_t insn;
  582         int j;
  583 
  584         insn = db_get_value(loc, 4, 0);
  585         for (j = 0; riscv_opcodes[j].name != NULL; j++) {
  586                 op = &riscv_opcodes[j];
  587                 if (op->match_func(op, insn)) {
  588                         oprint(op, loc, insn);
  589                         return(loc + 4);
  590                 }
  591         };
  592 
  593         insn = db_get_value(loc, 2, 0);
  594         for (j = 0; riscv_c_opcodes[j].name != NULL; j++) {
  595                 op = &riscv_c_opcodes[j];
  596                 if (op->match_func(op, insn)) {
  597                         oprint(op, loc, insn);
  598                         break;
  599                 }
  600         };
  601 
  602         return(loc + 2);
  603 }

Cache object: 50bda3212b55efbb09a02e077a04c058


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.