1 /* Disassemble Xilinx microblaze instructions.
2 Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
21 * Redistribution and use in source and binary forms are permitted
22 * provided that the above copyright notice and this paragraph are
23 * duplicated in all such forms and that any documentation,
24 * advertising materials, and other materials related to such
25 * distribution and use acknowledge that the software was developed
26 * by Xilinx, Inc. The name of the Company may not be used to endorse
27 * or promote products derived from this software without specific prior
29 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
41 #ifndef MICROBLAZE_OPC
42 #define MICROBLAZE_OPC
43 /* Assembler instructions for Xilinx's microblaze processor
44 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
47 This program is free software; you can redistribute it and/or modify
48 it under the terms of the GNU General Public License as published by
49 the Free Software Foundation; either version 2 of the License, or
50 (at your option) any later version.
52 This program is distributed in the hope that it will be useful,
53 but WITHOUT ANY WARRANTY; without even the implied warranty of
54 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 GNU General Public License for more details.
57 You should have received a copy of the GNU General Public License
58 along with this program; if not, write to the Free Software
59 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
62 * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
64 * Redistribution and use in source and binary forms are permitted
65 * provided that the above copyright notice and this paragraph are
66 * duplicated in all such forms and that any documentation,
67 * advertising materials, and other materials related to such
68 * distribution and use acknowledge that the software was developed
69 * by Xilinx, Inc. The name of the Company may not be used to endorse
70 * or promote products derived from this software without specific prior
72 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
73 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
74 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
80 #ifndef MICROBLAZE_OPCM
81 #define MICROBLAZE_OPCM
84 * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
86 * Redistribution and use in source and binary forms are permitted
87 * provided that the above copyright notice and this paragraph are
88 * duplicated in all such forms and that any documentation,
89 * advertising materials, and other materials related to such
90 * distribution and use acknowledge that the software was developed
91 * by Xilinx, Inc. The name of the Company may not be used to endorse
92 * or promote products derived from this software without specific prior
94 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
95 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
96 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
102 enum microblaze_instr {
103 add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, cmp, cmpu,
104 addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
105 idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
106 ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
107 andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, wic, wdc, mts, mfs, br, brd,
108 brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
109 bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
110 imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
111 brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
112 bgtid, bgei, bgeid, lbu, lhu, lw, sb, sh, sw, lbui, lhui, lwi,
113 sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv,
114 fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, invalid_inst } ;
116 enum microblaze_instr_type {
117 arithmetic_inst, logical_inst, mult_inst, div_inst, branch_inst,
118 return_inst, immediate_inst, special_inst, memory_load_inst,
119 memory_store_inst, barrel_shift_inst, anyware_inst };
121 #define INST_WORD_SIZE 4
123 /* gen purpose regs go from 0 to 31 */
124 /* mask is reg num - max_reg_num, ie reg_num - 32 in this case */
126 #define REG_PC_MASK 0x8000
127 #define REG_MSR_MASK 0x8001
128 #define REG_EAR_MASK 0x8003
129 #define REG_ESR_MASK 0x8005
130 #define REG_FSR_MASK 0x8007
133 #define MAX_REGNUM 31
135 #define REG_PC 32 /* PC */
136 #define REG_MSR 33 /* machine status reg */
137 #define REG_EAR 35 /* Exception reg */
138 #define REG_ESR 37 /* Exception reg */
139 #define REG_FSR 39 /* FPU Status reg */
141 /* alternate names for gen purpose regs */
142 #define REG_SP 1 /* stack pointer */
143 #define REG_ROSDP 2 /* read-only small data pointer */
144 #define REG_RWSDP 13 /* read-write small data pointer */
146 /* Assembler Register - Used in Delay Slot Optimization */
150 #define RD_LOW 21 /* low bit for RD */
151 #define RA_LOW 16 /* low bit for RA */
152 #define RB_LOW 11 /* low bit for RB */
153 #define IMM_LOW 0 /* low bit for immediate */
155 #define RD_MASK 0x03E00000
156 #define RA_MASK 0x001F0000
157 #define RB_MASK 0x0000F800
158 #define IMM_MASK 0x0000FFFF
160 // imm mask for barrel shifts
161 #define IMM5_MASK 0x0000001F
164 // imm mask for get, put instructions
165 #define IMM12_MASK 0x00000FFF
167 // imm mask for msrset, msrclr instructions
168 #define IMM14_MASK 0x00003FFF
170 #endif /* MICROBLAZE-OPCM */
172 #define INST_TYPE_RD_R1_R2 0
173 #define INST_TYPE_RD_R1_IMM 1
174 #define INST_TYPE_RD_R1_UNSIGNED_IMM 2
175 #define INST_TYPE_RD_R1 3
176 #define INST_TYPE_RD_R2 4
177 #define INST_TYPE_RD_IMM 5
178 #define INST_TYPE_R2 6
179 #define INST_TYPE_R1_R2 7
180 #define INST_TYPE_R1_IMM 8
181 #define INST_TYPE_IMM 9
182 #define INST_TYPE_SPECIAL_R1 10
183 #define INST_TYPE_RD_SPECIAL 11
184 #define INST_TYPE_R1 12
185 // new instn type for barrel shift imms
186 #define INST_TYPE_RD_R1_IMM5 13
187 #define INST_TYPE_RD_IMM12 14
188 #define INST_TYPE_R1_IMM12 15
190 // new insn type for insn cache
191 #define INST_TYPE_RD_R1_SPECIAL 16
193 // new insn type for msrclr, msrset insns.
194 #define INST_TYPE_RD_IMM14 17
196 // new insn type for tuqula rd - addik rd, r0, 42
197 #define INST_TYPE_RD 18
199 #define INST_TYPE_NONE 25
203 #define INST_PC_OFFSET 1 /* instructions where the label address is resolved as a PC offset (for branch label)*/
204 #define INST_NO_OFFSET 0 /* instructions where the label address is resolved as an absolute value (for data mem or abs address)*/
206 #define IMMVAL_MASK_NON_SPECIAL 0x0000
207 #define IMMVAL_MASK_MTS 0x4000
208 #define IMMVAL_MASK_MFS 0x0000
210 #define OPCODE_MASK_H 0xFC000000 /* High 6 bits only */
211 #define OPCODE_MASK_H1 0xFFE00000 /* High 11 bits */
212 #define OPCODE_MASK_H2 0xFC1F0000 /* High 6 and bits 20-16 */
213 #define OPCODE_MASK_H12 0xFFFF0000 /* High 16 */
214 #define OPCODE_MASK_H4 0xFC0007FF /* High 6 and low 11 bits */
215 #define OPCODE_MASK_H13S 0xFFE0FFF0 /* High 11 and 15:1 bits and last nibble of last byte for spr */
216 #define OPCODE_MASK_H23S 0xFC1FFFF0 /* High 6, 20-16 and 15:1 bits and last nibble of last byte for spr */
217 #define OPCODE_MASK_H34 0xFC00FFFF /* High 6 and low 16 bits */
218 #define OPCODE_MASK_H14 0xFFE007FF /* High 11 and low 11 bits */
219 #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits */
220 #define OPCODE_MASK_H124 0xFFFF07FF /* High 16, and low 11 bits */
221 #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits */
222 #define OPCODE_MASK_H3 0xFC000600 /* High 6 bits and bits 21, 22 */
223 #define OPCODE_MASK_H32 0xFC00F000 /* High 6 bits and bit 16, 17, 18 and 19*/
224 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits */
226 // New Mask for msrset, msrclr insns.
227 #define OPCODE_MASK_H23N 0xFC1FC000 /* High 6 and bits 12 - 18 */
230 #define NO_DELAY_SLOT 0
232 #define MAX_OPCODES 149
234 struct op_code_struct {
236 short inst_type; /* registers and immediate values involved */
237 short inst_offset_type; /* immediate vals offset from PC? (= 1 for branches) */
238 short delay_slots; /* info about delay slots needed after this instr. */
240 unsigned long bit_sequence; /* all the fixed bits for the op are set and all the variable bits (reg names, imm vals) are set to 0 */
241 unsigned long opcode_mask; /* which bits define the opcode */
242 enum microblaze_instr instr;
243 enum microblaze_instr_type instr_type;
244 /* more info about output format here */
245 } opcodes[MAX_OPCODES] =
248 {"add", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst },
249 {"rsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst },
250 {"addc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst },
251 {"rsubc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000000, OPCODE_MASK_H4, rsubc, arithmetic_inst },
252 {"addk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000000, OPCODE_MASK_H4, addk, arithmetic_inst },
253 {"rsubk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000000, OPCODE_MASK_H4, rsubk, arithmetic_inst },
254 {"cmp", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000001, OPCODE_MASK_H4, cmp, arithmetic_inst },
255 {"cmpu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000003, OPCODE_MASK_H4, cmpu, arithmetic_inst },
256 {"addkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000000, OPCODE_MASK_H4, addkc, arithmetic_inst },
257 {"rsubkc",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000000, OPCODE_MASK_H4, rsubkc, arithmetic_inst },
258 {"addi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, addi, arithmetic_inst },
259 {"rsubi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, rsubi, arithmetic_inst },
260 {"addic", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, addic, arithmetic_inst },
261 {"rsubic",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, rsubic, arithmetic_inst },
262 {"addik", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, addik, arithmetic_inst },
263 {"rsubik",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, rsubik, arithmetic_inst },
264 {"addikc",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, addikc, arithmetic_inst },
265 {"rsubikc",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, rsubikc, arithmetic_inst },
266 {"mul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000000, OPCODE_MASK_H4, mul, mult_inst },
267 {"idiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x48000000, OPCODE_MASK_H4, idiv, div_inst },
268 {"idivu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x48000002, OPCODE_MASK_H4, idivu, div_inst },
269 {"bsll", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000400, OPCODE_MASK_H3, bsll, barrel_shift_inst },
270 {"bsra", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000200, OPCODE_MASK_H3, bsra, barrel_shift_inst },
271 {"bsrl", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000000, OPCODE_MASK_H3, bsrl, barrel_shift_inst },
272 {"get", INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C000000, OPCODE_MASK_H32, get, anyware_inst },
273 {"put", INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C008000, OPCODE_MASK_H32, put, anyware_inst },
274 {"nget", INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C004000, OPCODE_MASK_H32, nget, anyware_inst },
275 {"nput", INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00C000, OPCODE_MASK_H32, nput, anyware_inst },
276 {"cget", INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C002000, OPCODE_MASK_H32, cget, anyware_inst },
277 {"cput", INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00A000, OPCODE_MASK_H32, cput, anyware_inst },
278 {"ncget", INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
279 {"ncput", INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
280 {"muli", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
281 {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
282 {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
283 {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
284 {"or", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, or, logical_inst },
285 {"and", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, and, logical_inst },
286 {"xor", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, xor, logical_inst },
287 {"andn", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000000, OPCODE_MASK_H4, andn, logical_inst },
288 {"pcmpbf",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000400, OPCODE_MASK_H4, pcmpbf, logical_inst },
289 {"pcmpbc",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000400, OPCODE_MASK_H4, pcmpbc, logical_inst },
290 {"pcmpeq",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000400, OPCODE_MASK_H4, pcmpeq, logical_inst },
291 {"pcmpne",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000400, OPCODE_MASK_H4, pcmpne, logical_inst },
292 {"sra", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000001, OPCODE_MASK_H34, sra, logical_inst },
293 {"src", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000021, OPCODE_MASK_H34, src, logical_inst },
294 {"srl", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000041, OPCODE_MASK_H34, srl, logical_inst },
295 {"sext8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000060, OPCODE_MASK_H34, sext8, logical_inst },
296 {"sext16",INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000061, OPCODE_MASK_H34, sext16, logical_inst },
297 {"wic", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
298 {"wdc", INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
299 {"mts", INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
300 {"mfs", INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
301 {"br", INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
302 {"brd", INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98100000, OPCODE_MASK_H124, brd, branch_inst },
303 {"brld", INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98140000, OPCODE_MASK_H24, brld, branch_inst },
304 {"bra", INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98080000, OPCODE_MASK_H124, bra, branch_inst },
305 {"brad", INST_TYPE_R2, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98180000, OPCODE_MASK_H124, brad, branch_inst },
306 {"brald", INST_TYPE_RD_R2, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x981C0000, OPCODE_MASK_H24, brald, branch_inst },
307 {"brk", INST_TYPE_RD_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x980C0000, OPCODE_MASK_H24, microblaze_brk, branch_inst },
308 {"beq", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C000000, OPCODE_MASK_H14, beq, branch_inst },
309 {"beqd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E000000, OPCODE_MASK_H14, beqd, branch_inst },
310 {"bne", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C200000, OPCODE_MASK_H14, bne, branch_inst },
311 {"bned", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E200000, OPCODE_MASK_H14, bned, branch_inst },
312 {"blt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C400000, OPCODE_MASK_H14, blt, branch_inst },
313 {"bltd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E400000, OPCODE_MASK_H14, bltd, branch_inst },
314 {"ble", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C600000, OPCODE_MASK_H14, ble, branch_inst },
315 {"bled", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E600000, OPCODE_MASK_H14, bled, branch_inst },
316 {"bgt", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C800000, OPCODE_MASK_H14, bgt, branch_inst },
317 {"bgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E800000, OPCODE_MASK_H14, bgtd, branch_inst },
318 {"bge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9CA00000, OPCODE_MASK_H14, bge, branch_inst },
319 {"bged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9EA00000, OPCODE_MASK_H14, bged, branch_inst },
320 {"ori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, ori, logical_inst },
321 {"andi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, andi, logical_inst },
322 {"xori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, xori, logical_inst },
323 {"andni", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, andni, logical_inst },
324 {"imm", INST_TYPE_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB0000000, OPCODE_MASK_H12, imm, immediate_inst },
325 {"rtsd", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000000, OPCODE_MASK_H1, rtsd, return_inst },
326 {"rtid", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6200000, OPCODE_MASK_H1, rtid, return_inst },
327 {"rtbd", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6400000, OPCODE_MASK_H1, rtbd, return_inst },
328 {"rted", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6800000, OPCODE_MASK_H1, rted, return_inst },
329 {"bri", INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8000000, OPCODE_MASK_H12, bri, branch_inst },
330 {"brid", INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8100000, OPCODE_MASK_H12, brid, branch_inst },
331 {"brlid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8140000, OPCODE_MASK_H2, brlid, branch_inst },
332 {"brai", INST_TYPE_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8080000, OPCODE_MASK_H12, brai, branch_inst },
333 {"braid", INST_TYPE_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8180000, OPCODE_MASK_H12, braid, branch_inst },
334 {"bralid",INST_TYPE_RD_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB81C0000, OPCODE_MASK_H2, bralid, branch_inst },
335 {"brki", INST_TYPE_RD_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB80C0000, OPCODE_MASK_H2, brki, branch_inst },
336 {"beqi", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC000000, OPCODE_MASK_H1, beqi, branch_inst },
337 {"beqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE000000, OPCODE_MASK_H1, beqid, branch_inst },
338 {"bnei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC200000, OPCODE_MASK_H1, bnei, branch_inst },
339 {"bneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE200000, OPCODE_MASK_H1, bneid, branch_inst },
340 {"blti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC400000, OPCODE_MASK_H1, blti, branch_inst },
341 {"bltid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE400000, OPCODE_MASK_H1, bltid, branch_inst },
342 {"blei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC600000, OPCODE_MASK_H1, blei, branch_inst },
343 {"bleid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE600000, OPCODE_MASK_H1, bleid, branch_inst },
344 {"bgti", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC800000, OPCODE_MASK_H1, bgti, branch_inst },
345 {"bgtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE800000, OPCODE_MASK_H1, bgtid, branch_inst },
346 {"bgei", INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBCA00000, OPCODE_MASK_H1, bgei, branch_inst },
347 {"bgeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBEA00000, OPCODE_MASK_H1, bgeid, branch_inst },
348 {"lbu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000000, OPCODE_MASK_H4, lbu, memory_load_inst },
349 {"lhu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000000, OPCODE_MASK_H4, lhu, memory_load_inst },
350 {"lw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000000, OPCODE_MASK_H4, lw, memory_load_inst },
351 {"sb", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000000, OPCODE_MASK_H4, sb, memory_store_inst },
352 {"sh", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000000, OPCODE_MASK_H4, sh, memory_store_inst },
353 {"sw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst },
354 {"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst },
355 {"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst },
356 {"lwi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, lwi, memory_load_inst },
357 {"sbi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF0000000, OPCODE_MASK_H, sbi, memory_store_inst },
358 {"shi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF4000000, OPCODE_MASK_H, shi, memory_store_inst },
359 {"swi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, swi, memory_store_inst },
360 {"nop", INST_TYPE_NONE, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H1234, invalid_inst, logical_inst }, /* translates to or r0, r0, r0 */
361 {"la", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* la translates to addik */
362 {"tuqula",INST_TYPE_RD, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3000002A, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* tuqula rd translates to addik rd, r0, 42 */
363 {"not", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA800FFFF, OPCODE_MASK_H34, invalid_inst, logical_inst }, /* not translates to xori rd,ra,-1 */
364 {"neg", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* neg translates to rsub rd, ra, r0 */
365 {"rtb", INST_TYPE_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000004, OPCODE_MASK_H1, invalid_inst, return_inst }, /* rtb translates to rts rd, 4 */
366 {"sub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* sub translates to rsub rd, rb, ra */
367 {"lmi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, invalid_inst, memory_load_inst },
368 {"smi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, invalid_inst, memory_store_inst },
369 {"msrset",INST_TYPE_RD_IMM14, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94100000, OPCODE_MASK_H23N, msrset, special_inst },
370 {"msrclr",INST_TYPE_RD_IMM14, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94110000, OPCODE_MASK_H23N, msrclr, special_inst },
371 {"fadd", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000000, OPCODE_MASK_H4, fadd, arithmetic_inst },
372 {"frsub", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000080, OPCODE_MASK_H4, frsub, arithmetic_inst },
373 {"fmul", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000100, OPCODE_MASK_H4, fmul, arithmetic_inst },
374 {"fdiv", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000180, OPCODE_MASK_H4, fdiv, arithmetic_inst },
375 {"fcmp.lt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000210, OPCODE_MASK_H4, fcmp_lt, arithmetic_inst },
376 {"fcmp.eq", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000220, OPCODE_MASK_H4, fcmp_eq, arithmetic_inst },
377 {"fcmp.le", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000230, OPCODE_MASK_H4, fcmp_le, arithmetic_inst },
378 {"fcmp.gt", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000240, OPCODE_MASK_H4, fcmp_gt, arithmetic_inst },
379 {"fcmp.ne", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000250, OPCODE_MASK_H4, fcmp_ne, arithmetic_inst },
380 {"fcmp.ge", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000260, OPCODE_MASK_H4, fcmp_ge, arithmetic_inst },
381 {"fcmp.un", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000200, OPCODE_MASK_H4, fcmp_un, arithmetic_inst },
385 /* prefix for register names */
386 char register_prefix[] = "r";
387 char special_register_prefix[] = "spr";
388 char fsl_register_prefix[] = "rfsl";
391 /* #defines for valid immediate range */
392 #define MIN_IMM 0x80000000
393 #define MAX_IMM 0x7fffffff
395 #define MIN_IMM12 0x000
396 #define MAX_IMM12 0x7ff
398 #define MIN_IMM14 0x0000
399 #define MAX_IMM14 0x1fff
401 #endif /* MICROBLAZE_OPC */
406 #define get_field_rd(instr) get_field(instr, RD_MASK, RD_LOW)
407 #define get_field_r1(instr) get_field(instr, RA_MASK, RA_LOW)
408 #define get_field_r2(instr) get_field(instr, RB_MASK, RB_LOW)
409 #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW)
410 #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW)
413 get_field (long instr, long mask, unsigned short low)
416 sprintf(tmpstr, "%s%d", register_prefix, (int)((instr & mask) >> low));
417 return(strdup(tmpstr));
421 get_field_imm (long instr)
424 sprintf(tmpstr, "%d", (short)((instr & IMM_MASK) >> IMM_LOW));
425 return(strdup(tmpstr));
429 get_field_imm5 (long instr)
432 sprintf(tmpstr, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
433 return(strdup(tmpstr));
437 get_field_imm12 (long instr)
440 sprintf(tmpstr, "%s%d", fsl_register_prefix, (short)((instr & IMM12_MASK) >> IMM_LOW));
441 return(strdup(tmpstr));
445 get_field_imm14 (long instr)
448 sprintf(tmpstr, "%d", (short)((instr & IMM14_MASK) >> IMM_LOW));
449 return(strdup(tmpstr));
454 get_field_unsigned_imm (long instr)
457 sprintf(tmpstr, "%d", (int)((instr & IMM_MASK) >> IMM_LOW));
458 return(strdup(tmpstr));
464 get_field_special (instr)
469 sprintf(tmpstr, "%s%s", register_prefix, (((instr & IMM_MASK) >> IMM_LOW) & REG_MSR_MASK) == 0 ? "pc" : "msr");
471 return(strdup(tmpstr));
476 get_field_special (long instr, struct op_code_struct * op)
481 switch ( (((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) ) {
502 sprintf(tmpstr, "%s%s", register_prefix, spr);
503 return(strdup(tmpstr));
507 read_insn_microblaze(bfd_vma memaddr, struct disassemble_info *info,
508 struct op_code_struct ** opr)
510 unsigned char ibytes[4];
512 struct op_code_struct * op;
515 status = info->read_memory_func (memaddr, ibytes, 4, info);
519 info->memory_error_func (status, memaddr, info);
523 if (info->endian == BFD_ENDIAN_BIG)
524 inst = (ibytes[0] << 24) | (ibytes[1] << 16) | (ibytes[2] << 8) | ibytes[3];
525 else if (info->endian == BFD_ENDIAN_LITTLE)
526 inst = (ibytes[3] << 24) | (ibytes[2] << 16) | (ibytes[1] << 8) | ibytes[0];
530 /* Just a linear search of the table. */
531 for (op = opcodes; op->name != 0; op ++)
532 if (op->bit_sequence == (inst & op->opcode_mask))
541 print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
543 fprintf_ftype fprintf = info->fprintf_func;
544 void * stream = info->stream;
545 unsigned long inst, prev_inst;
546 struct op_code_struct * op, *pop;
548 boolean immfound = false;
549 static bfd_vma prev_insn_addr = -1; /*init the prev insn addr */
550 static int prev_insn_vma = -1; /*init the prev insn vma */
551 int curr_insn_vma = info->buffer_vma;
553 info->bytes_per_chunk = 4;
555 inst = read_insn_microblaze (memaddr, info, &op);
559 if (prev_insn_vma == curr_insn_vma) {
560 if (memaddr-(info->bytes_per_chunk) == prev_insn_addr) {
561 prev_inst = read_insn_microblaze (prev_insn_addr, info, &pop);
564 if (pop->instr == imm) {
565 immval = (get_int_field_imm(prev_inst) << 16) & 0xffff0000;
574 /* make curr insn as prev insn */
575 prev_insn_addr = memaddr;
576 prev_insn_vma = curr_insn_vma;
579 fprintf (stream, ".short 0x%04x", inst);
582 fprintf (stream, "%s", op->name);
584 switch (op->inst_type)
586 case INST_TYPE_RD_R1_R2:
587 fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_r2(inst));
589 case INST_TYPE_RD_R1_IMM:
590 fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_imm(inst));
591 if (info->print_address_func && get_int_field_r1(inst) == 0 && info->symbol_at_address_func) {
593 immval |= (get_int_field_imm(inst) & 0x0000ffff);
595 immval = get_int_field_imm(inst);
597 immval |= 0xFFFF0000;
599 if (immval > 0 && info->symbol_at_address_func(immval, info)) {
600 fprintf (stream, "\t// ");
601 info->print_address_func (immval, info);
605 case INST_TYPE_RD_R1_IMM5:
606 fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_imm5(inst));
608 case INST_TYPE_RD_IMM12:
609 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm12(inst));
611 case INST_TYPE_R1_IMM12:
612 fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_imm12(inst));
614 case INST_TYPE_RD_SPECIAL:
615 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_special(inst, op));
617 case INST_TYPE_SPECIAL_R1:
618 fprintf(stream, "\t%s, %s", get_field_special(inst, op), get_field_r1(inst));
620 case INST_TYPE_RD_R1:
621 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r1(inst));
623 case INST_TYPE_R1_R2:
624 fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_r2(inst));
626 case INST_TYPE_R1_IMM:
627 fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_imm(inst));
628 /* The non-pc relative instructions are returns, which shouldn't
629 have a label printed */
630 if (info->print_address_func && op->inst_offset_type == INST_PC_OFFSET && info->symbol_at_address_func) {
632 immval |= (get_int_field_imm(inst) & 0x0000ffff);
634 immval = get_int_field_imm(inst);
636 immval |= 0xFFFF0000;
639 if (immval > 0 && info->symbol_at_address_func(immval, info)) {
640 fprintf (stream, "\t// ");
641 info->print_address_func (immval, info);
643 fprintf (stream, "\t\t// ");
644 fprintf (stream, "%x", immval);
648 case INST_TYPE_RD_IMM:
649 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm(inst));
650 if (info->print_address_func && info->symbol_at_address_func) {
652 immval |= (get_int_field_imm(inst) & 0x0000ffff);
654 immval = get_int_field_imm(inst);
656 immval |= 0xFFFF0000;
658 if (op->inst_offset_type == INST_PC_OFFSET)
659 immval += (int) memaddr;
660 if (info->symbol_at_address_func(immval, info)) {
661 fprintf (stream, "\t// ");
662 info->print_address_func (immval, info);
667 fprintf(stream, "\t%s", get_field_imm(inst));
668 if (info->print_address_func && info->symbol_at_address_func && op->instr != imm) {
670 immval |= (get_int_field_imm(inst) & 0x0000ffff);
672 immval = get_int_field_imm(inst);
674 immval |= 0xFFFF0000;
676 if (op->inst_offset_type == INST_PC_OFFSET)
677 immval += (int) memaddr;
678 if (immval > 0 && info->symbol_at_address_func(immval, info)) {
679 fprintf (stream, "\t// ");
680 info->print_address_func (immval, info);
681 } else if (op->inst_offset_type == INST_PC_OFFSET) {
682 fprintf (stream, "\t\t// ");
683 fprintf (stream, "%x", immval);
687 case INST_TYPE_RD_R2:
688 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
691 fprintf(stream, "\t%s", get_field_r2(inst));
694 fprintf(stream, "\t%s", get_field_r1(inst));
696 case INST_TYPE_RD_R1_SPECIAL:
697 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
699 case INST_TYPE_RD_IMM14:
700 fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm14(inst));
702 /* For tuqula instruction */
704 fprintf(stream, "\t%s", get_field_rd(inst));
708 /* if the disassembler lags the instruction set */
709 fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
714 /* Say how many bytes we consumed? */
719 static enum microblaze_instr
720 get_insn_microblaze (long inst, boolean *isunsignedimm,
721 enum microblaze_instr_type *insn_type,
724 struct op_code_struct * op;
725 *isunsignedimm = false;
727 /* Just a linear search of the table. */
728 for (op = opcodes; op->name != 0; op ++)
729 if (op->bit_sequence == (inst & op->opcode_mask))
735 *isunsignedimm = (op->inst_type == INST_TYPE_RD_R1_UNSIGNED_IMM);
736 *insn_type = op->instr_type;
737 *delay_slots = op->delay_slots;
745 get_delay_slots_microblaze ( long inst )
747 boolean isunsignedimm;
748 enum microblaze_instr_type insn_type;
749 enum microblaze_instr op;
752 op = get_insn_microblaze( inst, &isunsignedimm, &insn_type, &delay_slots);
753 if (op == invalid_inst)
761 static enum microblaze_instr
762 microblaze_decode_insn (long insn, int *rd, int *ra, int *rb, int *imm)
764 enum microblaze_instr op;
766 enum microblaze_instr_type t2;
769 op = get_insn_microblaze(insn, &t1, &t2, &t3);
770 *rd = (insn & RD_MASK) >> RD_LOW;
771 *ra = (insn & RA_MASK) >> RA_LOW;
772 *rb = (insn & RB_MASK) >> RB_LOW;
773 t3 = (insn & IMM_MASK) >> IMM_LOW;
781 microblaze_get_target_address (long inst, boolean immfound, int immval,
782 long pcval, long r1val, long r2val,
783 boolean *targetvalid,
784 boolean *unconditionalbranch)
786 struct op_code_struct * op;
789 *unconditionalbranch = false;
790 /* Just a linear search of the table. */
791 for (op = opcodes; op->name != 0; op ++)
792 if (op->bit_sequence == (inst & op->opcode_mask))
796 *targetvalid = false;
797 } else if (op->instr_type == branch_inst) {
798 switch (op->inst_type) {
800 *unconditionalbranch = true;
802 case INST_TYPE_RD_R2:
803 case INST_TYPE_R1_R2:
806 if (op->inst_offset_type == INST_PC_OFFSET)
810 *unconditionalbranch = true;
812 case INST_TYPE_RD_IMM:
813 case INST_TYPE_R1_IMM:
815 targetaddr = (immval << 16) & 0xffff0000;
816 targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
818 targetaddr = get_int_field_imm(inst);
819 if (targetaddr & 0x8000)
820 targetaddr |= 0xFFFF0000;
822 if (op->inst_offset_type == INST_PC_OFFSET)
827 *targetvalid = false;
830 } else if (op->instr_type == return_inst) {
832 targetaddr = (immval << 16) & 0xffff0000;
833 targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
835 targetaddr = get_int_field_imm(inst);
836 if (targetaddr & 0x8000)
837 targetaddr |= 0xFFFF0000;
842 *targetvalid = false;