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 | } |