Statistics
| Branch: | Revision:

root / lm32-dis.c @ c28fa5a0

History | View | Annotate | Download (12.6 kB)

1 79368f49 Michael Walle
/*
2 79368f49 Michael Walle
 *  Simple LatticeMico32 disassembler.
3 79368f49 Michael Walle
 *
4 79368f49 Michael Walle
 *  Copyright (c) 2012 Michael Walle <michael@walle.cc>
5 79368f49 Michael Walle
 *
6 79368f49 Michael Walle
 * This library is free software; you can redistribute it and/or
7 79368f49 Michael Walle
 * modify it under the terms of the GNU Lesser General Public
8 79368f49 Michael Walle
 * License as published by the Free Software Foundation; either
9 79368f49 Michael Walle
 * version 2 of the License, or (at your option) any later version.
10 79368f49 Michael Walle
 *
11 79368f49 Michael Walle
 * This library is distributed in the hope that it will be useful,
12 79368f49 Michael Walle
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 79368f49 Michael Walle
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 79368f49 Michael Walle
 * Lesser General Public License for more details.
15 79368f49 Michael Walle
 *
16 79368f49 Michael Walle
 * You should have received a copy of the GNU Lesser General Public
17 79368f49 Michael Walle
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 79368f49 Michael Walle
 *
19 79368f49 Michael Walle
 */
20 79368f49 Michael Walle
21 79368f49 Michael Walle
#include <stdio.h>
22 79368f49 Michael Walle
#include "dis-asm.h"
23 79368f49 Michael Walle
24 79368f49 Michael Walle
typedef enum {
25 79368f49 Michael Walle
    LM32_OP_SRUI = 0, LM32_OP_NORI, LM32_OP_MULI, LM32_OP_SH, LM32_OP_LB,
26 79368f49 Michael Walle
    LM32_OP_SRI, LM32_OP_XORI, LM32_OP_LH, LM32_OP_ANDI, LM32_OP_XNORI,
27 79368f49 Michael Walle
    LM32_OP_LW, LM32_OP_LHU, LM32_OP_SB, LM32_OP_ADDI, LM32_OP_ORI,
28 79368f49 Michael Walle
    LM32_OP_SLI, LM32_OP_LBU, LM32_OP_BE, LM32_OP_BG, LM32_OP_BGE,
29 79368f49 Michael Walle
    LM32_OP_BGEU, LM32_OP_BGU, LM32_OP_SW, LM32_OP_BNE, LM32_OP_ANDHI,
30 79368f49 Michael Walle
    LM32_OP_CMPEI, LM32_OP_CMPGI, LM32_OP_CMPGEI, LM32_OP_CMPGEUI,
31 79368f49 Michael Walle
    LM32_OP_CMPGUI, LM32_OP_ORHI, LM32_OP_CMPNEI, LM32_OP_SRU, LM32_OP_NOR,
32 79368f49 Michael Walle
    LM32_OP_MUL, LM32_OP_DIVU, LM32_OP_RCSR, LM32_OP_SR, LM32_OP_XOR,
33 79368f49 Michael Walle
    LM32_OP_ILL0, LM32_OP_AND, LM32_OP_XNOR, LM32_OP_ILL1, LM32_OP_SCALL,
34 79368f49 Michael Walle
    LM32_OP_SEXTB, LM32_OP_ADD, LM32_OP_OR, LM32_OP_SL, LM32_OP_B,
35 79368f49 Michael Walle
    LM32_OP_MODU, LM32_OP_SUB, LM32_OP_ILL2, LM32_OP_WCSR, LM32_OP_ILL3,
36 79368f49 Michael Walle
    LM32_OP_CALL, LM32_OP_SEXTH, LM32_OP_BI, LM32_OP_CMPE, LM32_OP_CMPG,
37 79368f49 Michael Walle
    LM32_OP_CMPGE, LM32_OP_CMPGEU, LM32_OP_CMPGU, LM32_OP_CALLI, LM32_OP_CMPNE,
38 79368f49 Michael Walle
} Lm32Opcode;
39 79368f49 Michael Walle
40 79368f49 Michael Walle
typedef enum {
41 79368f49 Michael Walle
    FMT_INVALID = 0, FMT_RRI5, FMT_RRI16, FMT_IMM26, FMT_LOAD, FMT_STORE,
42 79368f49 Michael Walle
    FMT_RRR, FMT_R, FMT_RNR, FMT_CRN, FMT_CNR, FMT_BREAK,
43 79368f49 Michael Walle
} Lm32OpcodeFmt;
44 79368f49 Michael Walle
45 79368f49 Michael Walle
typedef enum {
46 79368f49 Michael Walle
    LM32_CSR_IE = 0, LM32_CSR_IM, LM32_CSR_IP, LM32_CSR_ICC, LM32_CSR_DCC,
47 79368f49 Michael Walle
    LM32_CSR_CC, LM32_CSR_CFG, LM32_CSR_EBA, LM32_CSR_DC, LM32_CSR_DEBA,
48 79368f49 Michael Walle
    LM32_CSR_CFG2, LM32_CSR_JTX = 0xe, LM32_CSR_JRX, LM32_CSR_BP0,
49 79368f49 Michael Walle
    LM32_CSR_BP1, LM32_CSR_BP2, LM32_CSR_BP3, LM32_CSR_WP0 = 0x18,
50 79368f49 Michael Walle
    LM32_CSR_WP1, LM32_CSR_WP2, LM32_CSR_WP3,
51 79368f49 Michael Walle
} Lm32CsrNum;
52 79368f49 Michael Walle
53 79368f49 Michael Walle
typedef struct {
54 79368f49 Michael Walle
    int csr;
55 79368f49 Michael Walle
    const char *name;
56 79368f49 Michael Walle
} Lm32CsrInfo;
57 79368f49 Michael Walle
58 79368f49 Michael Walle
static const Lm32CsrInfo lm32_csr_info[] = {
59 79368f49 Michael Walle
    {LM32_CSR_IE,   "ie", },
60 79368f49 Michael Walle
    {LM32_CSR_IM,   "im", },
61 79368f49 Michael Walle
    {LM32_CSR_IP,   "ip", },
62 79368f49 Michael Walle
    {LM32_CSR_ICC,  "icc", },
63 79368f49 Michael Walle
    {LM32_CSR_DCC,  "dcc", },
64 79368f49 Michael Walle
    {LM32_CSR_CC,   "cc", },
65 79368f49 Michael Walle
    {LM32_CSR_CFG,  "cfg", },
66 79368f49 Michael Walle
    {LM32_CSR_EBA,  "eba", },
67 79368f49 Michael Walle
    {LM32_CSR_DC,   "dc", },
68 79368f49 Michael Walle
    {LM32_CSR_DEBA, "deba", },
69 79368f49 Michael Walle
    {LM32_CSR_CFG2, "cfg2", },
70 79368f49 Michael Walle
    {LM32_CSR_JTX,  "jtx", },
71 79368f49 Michael Walle
    {LM32_CSR_JRX,  "jrx", },
72 79368f49 Michael Walle
    {LM32_CSR_BP0,  "bp0", },
73 79368f49 Michael Walle
    {LM32_CSR_BP1,  "bp1", },
74 79368f49 Michael Walle
    {LM32_CSR_BP2,  "bp2", },
75 79368f49 Michael Walle
    {LM32_CSR_BP3,  "bp3", },
76 79368f49 Michael Walle
    {LM32_CSR_WP0,  "wp0", },
77 79368f49 Michael Walle
    {LM32_CSR_WP1,  "wp1", },
78 79368f49 Michael Walle
    {LM32_CSR_WP2,  "wp2", },
79 79368f49 Michael Walle
    {LM32_CSR_WP3,  "wp3", },
80 79368f49 Michael Walle
};
81 79368f49 Michael Walle
82 79368f49 Michael Walle
static const Lm32CsrInfo *find_csr_info(int csr)
83 79368f49 Michael Walle
{
84 79368f49 Michael Walle
    const Lm32CsrInfo *info;
85 79368f49 Michael Walle
    int i;
86 79368f49 Michael Walle
87 79368f49 Michael Walle
    for (i = 0; i < ARRAY_SIZE(lm32_csr_info); i++) {
88 79368f49 Michael Walle
        info = &lm32_csr_info[i];
89 79368f49 Michael Walle
        if (csr == info->csr) {
90 79368f49 Michael Walle
            return info;
91 79368f49 Michael Walle
        }
92 79368f49 Michael Walle
    }
93 79368f49 Michael Walle
94 79368f49 Michael Walle
    return NULL;
95 79368f49 Michael Walle
}
96 79368f49 Michael Walle
97 79368f49 Michael Walle
typedef struct {
98 79368f49 Michael Walle
    int reg;
99 79368f49 Michael Walle
    const char *name;
100 79368f49 Michael Walle
} Lm32RegInfo;
101 79368f49 Michael Walle
102 79368f49 Michael Walle
typedef enum {
103 79368f49 Michael Walle
    LM32_REG_R0 = 0, LM32_REG_R1, LM32_REG_R2, LM32_REG_R3, LM32_REG_R4,
104 79368f49 Michael Walle
    LM32_REG_R5, LM32_REG_R6, LM32_REG_R7, LM32_REG_R8, LM32_REG_R9,
105 79368f49 Michael Walle
    LM32_REG_R10, LM32_REG_R11, LM32_REG_R12, LM32_REG_R13, LM32_REG_R14,
106 79368f49 Michael Walle
    LM32_REG_R15, LM32_REG_R16, LM32_REG_R17, LM32_REG_R18, LM32_REG_R19,
107 79368f49 Michael Walle
    LM32_REG_R20, LM32_REG_R21, LM32_REG_R22, LM32_REG_R23, LM32_REG_R24,
108 79368f49 Michael Walle
    LM32_REG_R25, LM32_REG_GP, LM32_REG_FP, LM32_REG_SP, LM32_REG_RA,
109 79368f49 Michael Walle
    LM32_REG_EA, LM32_REG_BA,
110 79368f49 Michael Walle
} Lm32RegNum;
111 79368f49 Michael Walle
112 79368f49 Michael Walle
static const Lm32RegInfo lm32_reg_info[] = {
113 79368f49 Michael Walle
    {LM32_REG_R0,  "r0", },
114 79368f49 Michael Walle
    {LM32_REG_R1,  "r1", },
115 79368f49 Michael Walle
    {LM32_REG_R2,  "r2", },
116 79368f49 Michael Walle
    {LM32_REG_R3,  "r3", },
117 79368f49 Michael Walle
    {LM32_REG_R4,  "r4", },
118 79368f49 Michael Walle
    {LM32_REG_R5,  "r5", },
119 79368f49 Michael Walle
    {LM32_REG_R6,  "r6", },
120 79368f49 Michael Walle
    {LM32_REG_R7,  "r7", },
121 79368f49 Michael Walle
    {LM32_REG_R8,  "r8", },
122 79368f49 Michael Walle
    {LM32_REG_R9,  "r9", },
123 79368f49 Michael Walle
    {LM32_REG_R10, "r10", },
124 79368f49 Michael Walle
    {LM32_REG_R11, "r11", },
125 79368f49 Michael Walle
    {LM32_REG_R12, "r12", },
126 79368f49 Michael Walle
    {LM32_REG_R13, "r13", },
127 79368f49 Michael Walle
    {LM32_REG_R14, "r14", },
128 79368f49 Michael Walle
    {LM32_REG_R15, "r15", },
129 79368f49 Michael Walle
    {LM32_REG_R16, "r16", },
130 79368f49 Michael Walle
    {LM32_REG_R17, "r17", },
131 79368f49 Michael Walle
    {LM32_REG_R18, "r18", },
132 79368f49 Michael Walle
    {LM32_REG_R19, "r19", },
133 79368f49 Michael Walle
    {LM32_REG_R20, "r20", },
134 79368f49 Michael Walle
    {LM32_REG_R21, "r21", },
135 79368f49 Michael Walle
    {LM32_REG_R22, "r22", },
136 79368f49 Michael Walle
    {LM32_REG_R23, "r23", },
137 79368f49 Michael Walle
    {LM32_REG_R24, "r24", },
138 79368f49 Michael Walle
    {LM32_REG_R25, "r25", },
139 79368f49 Michael Walle
    {LM32_REG_GP,  "gp", },
140 79368f49 Michael Walle
    {LM32_REG_FP,  "fp", },
141 79368f49 Michael Walle
    {LM32_REG_SP,  "sp", },
142 79368f49 Michael Walle
    {LM32_REG_RA,  "ra", },
143 79368f49 Michael Walle
    {LM32_REG_EA,  "ea", },
144 79368f49 Michael Walle
    {LM32_REG_BA,  "ba", },
145 79368f49 Michael Walle
};
146 79368f49 Michael Walle
147 79368f49 Michael Walle
static const Lm32RegInfo *find_reg_info(int reg)
148 79368f49 Michael Walle
{
149 79368f49 Michael Walle
    assert(ARRAY_SIZE(lm32_reg_info) == 32);
150 79368f49 Michael Walle
    return &lm32_reg_info[reg & 0x1f];
151 79368f49 Michael Walle
}
152 79368f49 Michael Walle
153 79368f49 Michael Walle
typedef struct {
154 79368f49 Michael Walle
    struct {
155 79368f49 Michael Walle
        uint32_t code;
156 79368f49 Michael Walle
        uint32_t mask;
157 79368f49 Michael Walle
    } op;
158 79368f49 Michael Walle
    const char *name;
159 79368f49 Michael Walle
    const char *args_fmt;
160 79368f49 Michael Walle
} Lm32OpcodeInfo;
161 79368f49 Michael Walle
162 79368f49 Michael Walle
static const Lm32OpcodeInfo lm32_opcode_info[] = {
163 79368f49 Michael Walle
    /* pseudo instructions */
164 79368f49 Michael Walle
    {{0x34000000, 0xffffffff}, "nop",   NULL},
165 79368f49 Michael Walle
    {{0xac000002, 0xffffffff}, "break", NULL},
166 79368f49 Michael Walle
    {{0xac000003, 0xffffffff}, "scall", NULL},
167 79368f49 Michael Walle
    {{0xc3e00000, 0xffffffff}, "bret",  NULL},
168 79368f49 Michael Walle
    {{0xc3c00000, 0xffffffff}, "eret",  NULL},
169 79368f49 Michael Walle
    {{0xc3a00000, 0xffffffff}, "ret",   NULL},
170 79368f49 Michael Walle
    {{0xa4000000, 0xfc1f07ff}, "not",   "%2, %0"},
171 79368f49 Michael Walle
    {{0xb8000000, 0xfc1f07ff}, "mv",    "%2, %0"},
172 79368f49 Michael Walle
    {{0x71e00000, 0xffe00000}, "mvhi",  "%1, %u"},
173 79368f49 Michael Walle
    {{0x34000000, 0xffe00000}, "mvi",   "%1, %s"},
174 79368f49 Michael Walle
175 79368f49 Michael Walle
#define _O(op) {op << 26, 0x3f << 26}
176 79368f49 Michael Walle
    /* regular opcodes */
177 79368f49 Michael Walle
    {_O(LM32_OP_ADD),     "add",     "%2, %0, %1"  },
178 79368f49 Michael Walle
    {_O(LM32_OP_ADDI),    "addi",    "%1, %0, %s"  },
179 79368f49 Michael Walle
    {_O(LM32_OP_AND),     "and",     "%2, %0, %1"  },
180 79368f49 Michael Walle
    {_O(LM32_OP_ANDHI),   "andhi",   "%1, %0, %u"  },
181 79368f49 Michael Walle
    {_O(LM32_OP_ANDI),    "andi",    "%1, %0, %u"  },
182 79368f49 Michael Walle
    {_O(LM32_OP_B),       "b",       "%0",         },
183 79368f49 Michael Walle
    {_O(LM32_OP_BE),      "be",      "%1, %0, %r"  },
184 79368f49 Michael Walle
    {_O(LM32_OP_BG),      "bg",      "%1, %0, %r"  },
185 79368f49 Michael Walle
    {_O(LM32_OP_BGE),     "bge",     "%1, %0, %r"  },
186 79368f49 Michael Walle
    {_O(LM32_OP_BGEU),    "bgeu",    "%1, %0, %r"  },
187 79368f49 Michael Walle
    {_O(LM32_OP_BGU),     "bgu",     "%1, %0, %r"  },
188 79368f49 Michael Walle
    {_O(LM32_OP_BI),      "bi",      "%R",         },
189 79368f49 Michael Walle
    {_O(LM32_OP_BNE),     "bne",     "%1, %0, %r"  },
190 79368f49 Michael Walle
    {_O(LM32_OP_CALL),    "call",    "%0",         },
191 79368f49 Michael Walle
    {_O(LM32_OP_CALLI),   "calli",   "%R",         },
192 79368f49 Michael Walle
    {_O(LM32_OP_CMPE),    "cmpe",    "%2, %0, %1"  },
193 79368f49 Michael Walle
    {_O(LM32_OP_CMPEI),   "cmpei",   "%1, %0, %s"  },
194 79368f49 Michael Walle
    {_O(LM32_OP_CMPG),    "cmpg",    "%2, %0, %1"  },
195 79368f49 Michael Walle
    {_O(LM32_OP_CMPGE),   "cmpge",   "%2, %0, %1"  },
196 79368f49 Michael Walle
    {_O(LM32_OP_CMPGEI),  "cmpgei",  "%1, %0, %s"  },
197 79368f49 Michael Walle
    {_O(LM32_OP_CMPGEU),  "cmpgeu",  "%2, %0, %1"  },
198 79368f49 Michael Walle
    {_O(LM32_OP_CMPGEUI), "cmpgeui", "%1, %0, %s"  },
199 79368f49 Michael Walle
    {_O(LM32_OP_CMPGI),   "cmpgi",   "%1, %0, %s"  },
200 79368f49 Michael Walle
    {_O(LM32_OP_CMPGU),   "cmpgu",   "%2, %0, %1"  },
201 79368f49 Michael Walle
    {_O(LM32_OP_CMPGUI),  "cmpgui",  "%1, %0, %s"  },
202 79368f49 Michael Walle
    {_O(LM32_OP_CMPNE),   "cmpne",   "%2, %0, %1"  },
203 79368f49 Michael Walle
    {_O(LM32_OP_CMPNEI),  "cmpnei",  "%1, %0, %s"  },
204 79368f49 Michael Walle
    {_O(LM32_OP_DIVU),    "divu",    "%2, %0, %1"  },
205 79368f49 Michael Walle
    {_O(LM32_OP_LB),      "lb",      "%1, (%0+%s)" },
206 79368f49 Michael Walle
    {_O(LM32_OP_LBU),     "lbu",     "%1, (%0+%s)" },
207 79368f49 Michael Walle
    {_O(LM32_OP_LH),      "lh",      "%1, (%0+%s)" },
208 79368f49 Michael Walle
    {_O(LM32_OP_LHU),     "lhu",     "%1, (%0+%s)" },
209 79368f49 Michael Walle
    {_O(LM32_OP_LW),      "lw",      "%1, (%0+%s)" },
210 79368f49 Michael Walle
    {_O(LM32_OP_MODU),    "modu",    "%2, %0, %1"  },
211 79368f49 Michael Walle
    {_O(LM32_OP_MULI),    "muli",    "%1, %0, %s"  },
212 79368f49 Michael Walle
    {_O(LM32_OP_MUL),     "mul",     "%2, %0, %1"  },
213 79368f49 Michael Walle
    {_O(LM32_OP_NORI),    "nori",    "%1, %0, %u"  },
214 79368f49 Michael Walle
    {_O(LM32_OP_NOR),     "nor",     "%2, %0, %1"  },
215 79368f49 Michael Walle
    {_O(LM32_OP_ORHI),    "orhi",    "%1, %0, %u"  },
216 79368f49 Michael Walle
    {_O(LM32_OP_ORI),     "ori",     "%1, %0, %u"  },
217 79368f49 Michael Walle
    {_O(LM32_OP_OR),      "or",      "%2, %0, %1"  },
218 79368f49 Michael Walle
    {_O(LM32_OP_RCSR),    "rcsr",    "%2, %c",     },
219 79368f49 Michael Walle
    {_O(LM32_OP_SB),      "sb",      "(%0+%s), %1" },
220 79368f49 Michael Walle
    {_O(LM32_OP_SEXTB),   "sextb",   "%2, %0",     },
221 79368f49 Michael Walle
    {_O(LM32_OP_SEXTH),   "sexth",   "%2, %0",     },
222 79368f49 Michael Walle
    {_O(LM32_OP_SH),      "sh",      "(%0+%s), %1" },
223 79368f49 Michael Walle
    {_O(LM32_OP_SLI),     "sli",     "%1, %0, %h"  },
224 79368f49 Michael Walle
    {_O(LM32_OP_SL),      "sl",      "%2, %0, %1"  },
225 79368f49 Michael Walle
    {_O(LM32_OP_SRI),     "sri",     "%1, %0, %h"  },
226 79368f49 Michael Walle
    {_O(LM32_OP_SR),      "sr",      "%2, %0, %1"  },
227 79368f49 Michael Walle
    {_O(LM32_OP_SRUI),    "srui",    "%1, %0, %d"  },
228 79368f49 Michael Walle
    {_O(LM32_OP_SRU),     "sru",     "%2, %0, %s"  },
229 79368f49 Michael Walle
    {_O(LM32_OP_SUB),     "sub",     "%2, %0, %s"  },
230 79368f49 Michael Walle
    {_O(LM32_OP_SW),      "sw",      "(%0+%s), %1" },
231 79368f49 Michael Walle
    {_O(LM32_OP_WCSR),    "wcsr",    "%c, %1",     },
232 79368f49 Michael Walle
    {_O(LM32_OP_XNORI),   "xnori",   "%1, %0, %u"  },
233 79368f49 Michael Walle
    {_O(LM32_OP_XNOR),    "xnor",    "%2, %0, %1"  },
234 79368f49 Michael Walle
    {_O(LM32_OP_XORI),    "xori",    "%1, %0, %u"  },
235 79368f49 Michael Walle
    {_O(LM32_OP_XOR),     "xor",     "%2, %0, %1"  },
236 79368f49 Michael Walle
#undef _O
237 79368f49 Michael Walle
};
238 79368f49 Michael Walle
239 79368f49 Michael Walle
static const Lm32OpcodeInfo *find_opcode_info(uint32_t opcode)
240 79368f49 Michael Walle
{
241 79368f49 Michael Walle
    const Lm32OpcodeInfo *info;
242 79368f49 Michael Walle
    int i;
243 79368f49 Michael Walle
    for (i = 0; i < ARRAY_SIZE(lm32_opcode_info); i++) {
244 79368f49 Michael Walle
        info = &lm32_opcode_info[i];
245 79368f49 Michael Walle
        if ((opcode & info->op.mask) == info->op.code) {
246 79368f49 Michael Walle
            return info;
247 79368f49 Michael Walle
        }
248 79368f49 Michael Walle
    }
249 79368f49 Michael Walle
250 79368f49 Michael Walle
    return NULL;
251 79368f49 Michael Walle
}
252 79368f49 Michael Walle
253 79368f49 Michael Walle
int print_insn_lm32(bfd_vma memaddr, struct disassemble_info *info)
254 79368f49 Michael Walle
{
255 79368f49 Michael Walle
    fprintf_function fprintf_fn = info->fprintf_func;
256 79368f49 Michael Walle
    void *stream = info->stream;
257 79368f49 Michael Walle
    int rc;
258 79368f49 Michael Walle
    uint8_t insn[4];
259 79368f49 Michael Walle
    const Lm32OpcodeInfo *opc_info;
260 79368f49 Michael Walle
    uint32_t op;
261 79368f49 Michael Walle
    const char *args_fmt;
262 79368f49 Michael Walle
263 79368f49 Michael Walle
    rc = info->read_memory_func(memaddr, insn, 4, info);
264 79368f49 Michael Walle
    if (rc != 0) {
265 79368f49 Michael Walle
        info->memory_error_func(rc, memaddr, info);
266 79368f49 Michael Walle
        return -1;
267 79368f49 Michael Walle
    }
268 79368f49 Michael Walle
269 79368f49 Michael Walle
    fprintf_fn(stream, "%02x %02x %02x %02x    ",
270 79368f49 Michael Walle
            insn[0], insn[1], insn[2], insn[3]);
271 79368f49 Michael Walle
272 79368f49 Michael Walle
    op = bfd_getb32(insn);
273 79368f49 Michael Walle
    opc_info = find_opcode_info(op);
274 79368f49 Michael Walle
    if (opc_info) {
275 79368f49 Michael Walle
        fprintf_fn(stream, "%-8s ", opc_info->name);
276 79368f49 Michael Walle
        args_fmt = opc_info->args_fmt;
277 79368f49 Michael Walle
        while (args_fmt && *args_fmt) {
278 79368f49 Michael Walle
            if (*args_fmt == '%') {
279 79368f49 Michael Walle
                switch (*(++args_fmt)) {
280 79368f49 Michael Walle
                case '0': {
281 79368f49 Michael Walle
                    uint8_t r0;
282 79368f49 Michael Walle
                    const char *r0_name;
283 79368f49 Michael Walle
                    r0 = (op >> 21) & 0x1f;
284 79368f49 Michael Walle
                    r0_name = find_reg_info(r0)->name;
285 79368f49 Michael Walle
                    fprintf_fn(stream, "%s", r0_name);
286 79368f49 Michael Walle
                    break;
287 79368f49 Michael Walle
                }
288 79368f49 Michael Walle
                case '1': {
289 79368f49 Michael Walle
                    uint8_t r1;
290 79368f49 Michael Walle
                    const char *r1_name;
291 79368f49 Michael Walle
                    r1 = (op >> 16) & 0x1f;
292 79368f49 Michael Walle
                    r1_name = find_reg_info(r1)->name;
293 79368f49 Michael Walle
                    fprintf_fn(stream, "%s", r1_name);
294 79368f49 Michael Walle
                    break;
295 79368f49 Michael Walle
                }
296 79368f49 Michael Walle
                case '2': {
297 79368f49 Michael Walle
                    uint8_t r2;
298 79368f49 Michael Walle
                    const char *r2_name;
299 79368f49 Michael Walle
                    r2 = (op >> 11) & 0x1f;
300 79368f49 Michael Walle
                    r2_name = find_reg_info(r2)->name;
301 79368f49 Michael Walle
                    fprintf_fn(stream, "%s", r2_name);
302 79368f49 Michael Walle
                    break;
303 79368f49 Michael Walle
                }
304 79368f49 Michael Walle
                case 'c': {
305 79368f49 Michael Walle
                    uint8_t csr;
306 79368f49 Michael Walle
                    const char *csr_name;
307 79368f49 Michael Walle
                    csr = (op >> 21) & 0x1f;
308 79368f49 Michael Walle
                    csr_name = find_csr_info(csr)->name;
309 79368f49 Michael Walle
                    if (csr_name) {
310 79368f49 Michael Walle
                        fprintf_fn(stream, "%s", csr_name);
311 79368f49 Michael Walle
                    } else {
312 79368f49 Michael Walle
                        fprintf_fn(stream, "0x%x", csr);
313 79368f49 Michael Walle
                    }
314 79368f49 Michael Walle
                    break;
315 79368f49 Michael Walle
                }
316 79368f49 Michael Walle
                case 'u': {
317 79368f49 Michael Walle
                    uint16_t u16;
318 79368f49 Michael Walle
                    u16 = op & 0xffff;
319 79368f49 Michael Walle
                    fprintf_fn(stream, "0x%x", u16);
320 79368f49 Michael Walle
                    break;
321 79368f49 Michael Walle
                }
322 79368f49 Michael Walle
                case 's': {
323 79368f49 Michael Walle
                    int16_t s16;
324 79368f49 Michael Walle
                    s16 = (int16_t)(op & 0xffff);
325 79368f49 Michael Walle
                    fprintf_fn(stream, "%d", s16);
326 79368f49 Michael Walle
                    break;
327 79368f49 Michael Walle
                }
328 79368f49 Michael Walle
                case 'r': {
329 79368f49 Michael Walle
                    uint32_t rela;
330 79368f49 Michael Walle
                    rela = memaddr + (((int16_t)(op & 0xffff)) << 2);
331 79368f49 Michael Walle
                    fprintf_fn(stream, "%x", rela);
332 79368f49 Michael Walle
                    break;
333 79368f49 Michael Walle
                }
334 79368f49 Michael Walle
                case 'R': {
335 79368f49 Michael Walle
                    uint32_t rela;
336 79368f49 Michael Walle
                    int32_t imm26;
337 79368f49 Michael Walle
                    imm26 = (int32_t)((op & 0x3ffffff) << 6) >> 4;
338 79368f49 Michael Walle
                    rela = memaddr + imm26;
339 79368f49 Michael Walle
                    fprintf_fn(stream, "%x", rela);
340 79368f49 Michael Walle
                    break;
341 79368f49 Michael Walle
                }
342 79368f49 Michael Walle
                case 'h': {
343 79368f49 Michael Walle
                    uint8_t u5;
344 79368f49 Michael Walle
                    u5 = (op & 0x1f);
345 79368f49 Michael Walle
                    fprintf_fn(stream, "%d", u5);
346 79368f49 Michael Walle
                    break;
347 79368f49 Michael Walle
                }
348 79368f49 Michael Walle
                default:
349 79368f49 Michael Walle
                    break;
350 79368f49 Michael Walle
                }
351 79368f49 Michael Walle
            } else {
352 79368f49 Michael Walle
                fprintf_fn(stream, "%c", *args_fmt);
353 79368f49 Michael Walle
            }
354 79368f49 Michael Walle
            args_fmt++;
355 79368f49 Michael Walle
        }
356 79368f49 Michael Walle
    } else {
357 79368f49 Michael Walle
        fprintf_fn(stream, ".word 0x%x", op);
358 79368f49 Michael Walle
    }
359 79368f49 Michael Walle
360 79368f49 Michael Walle
    return 4;
361 79368f49 Michael Walle
}