Commit e90e390c2b8368d534cccfd2aaca1f6a0ae5d53d

Authored by Edgar E. Iglesias
1 parent b779e29e

microblaze: Add disassembler.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
dis-asm.h
... ... @@ -218,6 +218,7 @@ enum bfd_architecture
218 218 #define bfd_mach_cris_v0_v10 255
219 219 #define bfd_mach_cris_v32 32
220 220 #define bfd_mach_cris_v10_v32 1032
  221 + bfd_arch_microblaze, /* Xilinx MicroBlaze. */
221 222 bfd_arch_last
222 223 };
223 224 #define bfd_mach_s390_31 31
... ... @@ -400,6 +401,7 @@ extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
400 401 extern int print_insn_ppc PARAMS ((bfd_vma, disassemble_info*));
401 402 extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
402 403 extern int print_insn_crisv32 PARAMS ((bfd_vma, disassemble_info*));
  404 +extern int print_insn_microblaze PARAMS ((bfd_vma, disassemble_info*));
403 405  
404 406 #if 0
405 407 /* Fetch the disassembler for a given BFD, if that support is available. */
... ...
... ... @@ -195,6 +195,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
195 195 #elif defined(TARGET_CRIS)
196 196 disasm_info.mach = bfd_mach_cris_v32;
197 197 print_insn = print_insn_crisv32;
  198 +#elif defined(TARGET_MICROBLAZE)
  199 + disasm_info.mach = bfd_arch_microblaze;
  200 + print_insn = print_insn_microblaze;
198 201 #else
199 202 fprintf(out, "0x" TARGET_FMT_lx
200 203 ": Asm output not supported on this arch\n", code);
... ...
microblaze-dis.c 0 → 100755
  1 +/* Disassemble Xilinx microblaze instructions.
  2 + Copyright (C) 1993, 1999, 2000 Free Software Foundation, Inc.
  3 +
  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.
  8 +
  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.
  13 +
  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. */
  17 +
  18 +/*
  19 + * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
  20 + *
  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
  28 + * written permission.
  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.
  32 + *
  33 + * Xilinx, Inc.
  34 + */
  35 +
  36 +
  37 +#include <stdio.h>
  38 +#define STATIC_TABLE
  39 +#define DEFINE_TABLE
  40 +
  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.
  45 +
  46 +
  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.
  51 +
  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.
  56 +
  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. */
  60 +
  61 +/*
  62 + * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
  63 + *
  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
  71 + * written permission.
  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.
  75 + *
  76 + * Xilinx, Inc.
  77 + */
  78 +
  79 +
  80 +#ifndef MICROBLAZE_OPCM
  81 +#define MICROBLAZE_OPCM
  82 +
  83 +/*
  84 + * Copyright (c) 2001 Xilinx, Inc. All rights reserved.
  85 + *
  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
  93 + * written permission.
  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.
  97 + *
  98 + * Xilinx, Inc.
  99 + * $Header:
  100 + */
  101 +
  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 } ;
  115 +
  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 };
  120 +
  121 +#define INST_WORD_SIZE 4
  122 +
  123 +/* gen purpose regs go from 0 to 31 */
  124 +/* mask is reg num - max_reg_num, ie reg_num - 32 in this case */
  125 +
  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
  131 +
  132 +#define MIN_REGNUM 0
  133 +#define MAX_REGNUM 31
  134 +
  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 */
  140 +
  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 */
  145 +
  146 +/* Assembler Register - Used in Delay Slot Optimization */
  147 +#define REG_AS 18
  148 +#define REG_ZERO 0
  149 +
  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 */
  154 +
  155 +#define RD_MASK 0x03E00000
  156 +#define RA_MASK 0x001F0000
  157 +#define RB_MASK 0x0000F800
  158 +#define IMM_MASK 0x0000FFFF
  159 +
  160 +// imm mask for barrel shifts
  161 +#define IMM5_MASK 0x0000001F
  162 +
  163 +
  164 +// imm mask for get, put instructions
  165 +#define IMM12_MASK 0x00000FFF
  166 +
  167 +// imm mask for msrset, msrclr instructions
  168 +#define IMM14_MASK 0x00003FFF
  169 +
  170 +#endif /* MICROBLAZE-OPCM */
  171 +
  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
  189 +
  190 + // new insn type for insn cache
  191 +#define INST_TYPE_RD_R1_SPECIAL 16
  192 +
  193 +// new insn type for msrclr, msrset insns.
  194 +#define INST_TYPE_RD_IMM14 17
  195 +
  196 +// new insn type for tuqula rd - addik rd, r0, 42
  197 +#define INST_TYPE_RD 18
  198 +
  199 +#define INST_TYPE_NONE 25
  200 +
  201 +
  202 +
  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)*/
  205 +
  206 +#define IMMVAL_MASK_NON_SPECIAL 0x0000
  207 +#define IMMVAL_MASK_MTS 0x4000
  208 +#define IMMVAL_MASK_MFS 0x0000
  209 +
  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 */
  225 +
  226 +// New Mask for msrset, msrclr insns.
  227 +#define OPCODE_MASK_H23N 0xFC1FC000 /* High 6 and bits 12 - 18 */
  228 +
  229 +#define DELAY_SLOT 1
  230 +#define NO_DELAY_SLOT 0
  231 +
  232 +#define MAX_OPCODES 149
  233 +
  234 +struct op_code_struct {
  235 + const char *name;
  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. */
  239 + short immval_mask;
  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] =
  246 +
  247 +{
  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 },
  382 + {""}
  383 +};
  384 +
  385 +/* prefix for register names */
  386 +char register_prefix[] = "r";
  387 +char special_register_prefix[] = "spr";
  388 +char fsl_register_prefix[] = "rfsl";
  389 +
  390 +
  391 +/* #defines for valid immediate range */
  392 +#define MIN_IMM 0x80000000
  393 +#define MAX_IMM 0x7fffffff
  394 +
  395 +#define MIN_IMM12 0x000
  396 +#define MAX_IMM12 0x7ff
  397 +
  398 +#define MIN_IMM14 0x0000
  399 +#define MAX_IMM14 0x1fff
  400 +
  401 +#endif /* MICROBLAZE_OPC */
  402 +
  403 +#include "dis-asm.h"
  404 +#include <strings.h>
  405 +
  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)
  411 +
  412 +static char *
  413 +get_field (long instr, long mask, unsigned short low)
  414 +{
  415 + char tmpstr[25];
  416 + sprintf(tmpstr, "%s%d", register_prefix, (int)((instr & mask) >> low));
  417 + return(strdup(tmpstr));
  418 +}
  419 +
  420 +static char *
  421 +get_field_imm (long instr)
  422 +{
  423 + char tmpstr[25];
  424 + sprintf(tmpstr, "%d", (short)((instr & IMM_MASK) >> IMM_LOW));
  425 + return(strdup(tmpstr));
  426 +}
  427 +
  428 +static char *
  429 +get_field_imm5 (long instr)
  430 +{
  431 + char tmpstr[25];
  432 + sprintf(tmpstr, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
  433 + return(strdup(tmpstr));
  434 +}
  435 +
  436 +static char *
  437 +get_field_imm12 (long instr)
  438 +{
  439 + char tmpstr[25];
  440 + sprintf(tmpstr, "%s%d", fsl_register_prefix, (short)((instr & IMM12_MASK) >> IMM_LOW));
  441 + return(strdup(tmpstr));
  442 +}
  443 +
  444 +static char *
  445 +get_field_imm14 (long instr)
  446 +{
  447 + char tmpstr[25];
  448 + sprintf(tmpstr, "%d", (short)((instr & IMM14_MASK) >> IMM_LOW));
  449 + return(strdup(tmpstr));
  450 +}
  451 +
  452 +#if 0
  453 +static char *
  454 +get_field_unsigned_imm (long instr)
  455 +{
  456 + char tmpstr[25];
  457 + sprintf(tmpstr, "%d", (int)((instr & IMM_MASK) >> IMM_LOW));
  458 + return(strdup(tmpstr));
  459 +}
  460 +#endif
  461 +
  462 +/*
  463 + char *
  464 + get_field_special (instr)
  465 + long instr;
  466 + {
  467 + char tmpstr[25];
  468 +
  469 + sprintf(tmpstr, "%s%s", register_prefix, (((instr & IMM_MASK) >> IMM_LOW) & REG_MSR_MASK) == 0 ? "pc" : "msr");
  470 +
  471 + return(strdup(tmpstr));
  472 + }
  473 +*/
  474 +
  475 +static char *
  476 +get_field_special (long instr, struct op_code_struct * op)
  477 +{
  478 + char tmpstr[25];
  479 + char spr[5];
  480 +
  481 + switch ( (((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) ) {
  482 + case REG_MSR_MASK :
  483 + strcpy(spr, "msr");
  484 + break;
  485 + case REG_PC_MASK :
  486 + strcpy(spr, "pc");
  487 + break;
  488 + case REG_EAR_MASK :
  489 + strcpy(spr, "ear");
  490 + break;
  491 + case REG_ESR_MASK :
  492 + strcpy(spr, "esr");
  493 + break;
  494 + case REG_FSR_MASK :
  495 + strcpy(spr, "fsr");
  496 + break;
  497 + default :
  498 + strcpy(spr, "pc");
  499 + break;
  500 + }
  501 +
  502 + sprintf(tmpstr, "%s%s", register_prefix, spr);
  503 + return(strdup(tmpstr));
  504 +}
  505 +
  506 +static unsigned long
  507 +read_insn_microblaze(bfd_vma memaddr, struct disassemble_info *info,
  508 + struct op_code_struct ** opr)
  509 +{
  510 + unsigned char ibytes[4];
  511 + int status;
  512 + struct op_code_struct * op;
  513 + unsigned long inst;
  514 +
  515 + status = info->read_memory_func (memaddr, ibytes, 4, info);
  516 +
  517 + if (status != 0)
  518 + {
  519 + info->memory_error_func (status, memaddr, info);
  520 + return 0;
  521 + }
  522 +
  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];
  527 + else
  528 + abort ();
  529 +
  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))
  533 + break;
  534 +
  535 + *opr = op;
  536 + return inst;
  537 +}
  538 +
  539 +
  540 +int
  541 +print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
  542 +{
  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;
  547 + int immval = 0;
  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;
  552 +
  553 + info->bytes_per_chunk = 4;
  554 +
  555 + inst = read_insn_microblaze (memaddr, info, &op);
  556 + if (inst == 0)
  557 + return -1;
  558 +
  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);
  562 + if (prev_inst == 0)
  563 + return -1;
  564 + if (pop->instr == imm) {
  565 + immval = (get_int_field_imm(prev_inst) << 16) & 0xffff0000;
  566 + immfound = true;
  567 + }
  568 + else {
  569 + immval = 0;
  570 + immfound = false;
  571 + }
  572 + }
  573 + }
  574 + /* make curr insn as prev insn */
  575 + prev_insn_addr = memaddr;
  576 + prev_insn_vma = curr_insn_vma;
  577 +
  578 + if (op->name == 0)
  579 + fprintf (stream, ".short 0x%04x", inst);
  580 + else
  581 + {
  582 + fprintf (stream, "%s", op->name);
  583 +
  584 + switch (op->inst_type)
  585 + {
  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));
  588 + break;
  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) {
  592 + if (immfound)
  593 + immval |= (get_int_field_imm(inst) & 0x0000ffff);
  594 + else {
  595 + immval = get_int_field_imm(inst);
  596 + if (immval & 0x8000)
  597 + immval |= 0xFFFF0000;
  598 + }
  599 + if (immval > 0 && info->symbol_at_address_func(immval, info)) {
  600 + fprintf (stream, "\t// ");
  601 + info->print_address_func (immval, info);
  602 + }
  603 + }
  604 + break;
  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));
  607 + break;
  608 + case INST_TYPE_RD_IMM12:
  609 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm12(inst));
  610 + break;
  611 + case INST_TYPE_R1_IMM12:
  612 + fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_imm12(inst));
  613 + break;
  614 + case INST_TYPE_RD_SPECIAL:
  615 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_special(inst, op));
  616 + break;
  617 + case INST_TYPE_SPECIAL_R1:
  618 + fprintf(stream, "\t%s, %s", get_field_special(inst, op), get_field_r1(inst));
  619 + break;
  620 + case INST_TYPE_RD_R1:
  621 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r1(inst));
  622 + break;
  623 + case INST_TYPE_R1_R2:
  624 + fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_r2(inst));
  625 + break;
  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) {
  631 + if (immfound)
  632 + immval |= (get_int_field_imm(inst) & 0x0000ffff);
  633 + else {
  634 + immval = get_int_field_imm(inst);
  635 + if (immval & 0x8000)
  636 + immval |= 0xFFFF0000;
  637 + }
  638 + immval += memaddr;
  639 + if (immval > 0 && info->symbol_at_address_func(immval, info)) {
  640 + fprintf (stream, "\t// ");
  641 + info->print_address_func (immval, info);
  642 + } else {
  643 + fprintf (stream, "\t\t// ");
  644 + fprintf (stream, "%x", immval);
  645 + }
  646 + }
  647 + break;
  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) {
  651 + if (immfound)
  652 + immval |= (get_int_field_imm(inst) & 0x0000ffff);
  653 + else {
  654 + immval = get_int_field_imm(inst);
  655 + if (immval & 0x8000)
  656 + immval |= 0xFFFF0000;
  657 + }
  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);
  663 + }
  664 + }
  665 + break;
  666 + case INST_TYPE_IMM:
  667 + fprintf(stream, "\t%s", get_field_imm(inst));
  668 + if (info->print_address_func && info->symbol_at_address_func && op->instr != imm) {
  669 + if (immfound)
  670 + immval |= (get_int_field_imm(inst) & 0x0000ffff);
  671 + else {
  672 + immval = get_int_field_imm(inst);
  673 + if (immval & 0x8000)
  674 + immval |= 0xFFFF0000;
  675 + }
  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);
  684 + }
  685 + }
  686 + break;
  687 + case INST_TYPE_RD_R2:
  688 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
  689 + break;
  690 + case INST_TYPE_R2:
  691 + fprintf(stream, "\t%s", get_field_r2(inst));
  692 + break;
  693 + case INST_TYPE_R1:
  694 + fprintf(stream, "\t%s", get_field_r1(inst));
  695 + break;
  696 + case INST_TYPE_RD_R1_SPECIAL:
  697 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
  698 + break;
  699 + case INST_TYPE_RD_IMM14:
  700 + fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm14(inst));
  701 + break;
  702 + /* For tuqula instruction */
  703 + case INST_TYPE_RD:
  704 + fprintf(stream, "\t%s", get_field_rd(inst));
  705 + break;
  706 +
  707 + default:
  708 + /* if the disassembler lags the instruction set */
  709 + fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
  710 + break;
  711 + }
  712 + }
  713 +
  714 + /* Say how many bytes we consumed? */
  715 + return 4;
  716 +}
  717 +
  718 +#if 0
  719 +static enum microblaze_instr
  720 +get_insn_microblaze (long inst, boolean *isunsignedimm,
  721 + enum microblaze_instr_type *insn_type,
  722 + short *delay_slots )
  723 +{
  724 + struct op_code_struct * op;
  725 + *isunsignedimm = false;
  726 +
  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))
  730 + break;
  731 +
  732 + if (op->name == 0)
  733 + return invalid_inst;
  734 + else {
  735 + *isunsignedimm = (op->inst_type == INST_TYPE_RD_R1_UNSIGNED_IMM);
  736 + *insn_type = op->instr_type;
  737 + *delay_slots = op->delay_slots;
  738 + return op->instr;
  739 + }
  740 +}
  741 +#endif
  742 +
  743 +#if 0
  744 +static short
  745 +get_delay_slots_microblaze ( long inst )
  746 +{
  747 + boolean isunsignedimm;
  748 + enum microblaze_instr_type insn_type;
  749 + enum microblaze_instr op;
  750 + short delay_slots;
  751 +
  752 + op = get_insn_microblaze( inst, &isunsignedimm, &insn_type, &delay_slots);
  753 + if (op == invalid_inst)
  754 + return 0;
  755 + else
  756 + return delay_slots;
  757 +}
  758 +#endif
  759 +
  760 +#if 0
  761 +static enum microblaze_instr
  762 +microblaze_decode_insn (long insn, int *rd, int *ra, int *rb, int *imm)
  763 +{
  764 + enum microblaze_instr op;
  765 + boolean t1;
  766 + enum microblaze_instr_type t2;
  767 + short t3;
  768 +
  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;
  774 + *imm = (int) t3;
  775 + return (op);
  776 +}
  777 +#endif
  778 +
  779 +#if 0
  780 +static unsigned long
  781 +microblaze_get_target_address (long inst, boolean immfound, int immval,
  782 + long pcval, long r1val, long r2val,
  783 + boolean *targetvalid,
  784 + boolean *unconditionalbranch)
  785 +{
  786 + struct op_code_struct * op;
  787 + long targetaddr = 0;
  788 +
  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))
  793 + break;
  794 +
  795 + if (op->name == 0) {
  796 + *targetvalid = false;
  797 + } else if (op->instr_type == branch_inst) {
  798 + switch (op->inst_type) {
  799 + case INST_TYPE_R2:
  800 + *unconditionalbranch = true;
  801 + /* fallthru */
  802 + case INST_TYPE_RD_R2:
  803 + case INST_TYPE_R1_R2:
  804 + targetaddr = r2val;
  805 + *targetvalid = true;
  806 + if (op->inst_offset_type == INST_PC_OFFSET)
  807 + targetaddr += pcval;
  808 + break;
  809 + case INST_TYPE_IMM:
  810 + *unconditionalbranch = true;
  811 + /* fallthru */
  812 + case INST_TYPE_RD_IMM:
  813 + case INST_TYPE_R1_IMM:
  814 + if (immfound) {
  815 + targetaddr = (immval << 16) & 0xffff0000;
  816 + targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
  817 + } else {
  818 + targetaddr = get_int_field_imm(inst);
  819 + if (targetaddr & 0x8000)
  820 + targetaddr |= 0xFFFF0000;
  821 + }
  822 + if (op->inst_offset_type == INST_PC_OFFSET)
  823 + targetaddr += pcval;
  824 + *targetvalid = true;
  825 + break;
  826 + default:
  827 + *targetvalid = false;
  828 + break;
  829 + }
  830 + } else if (op->instr_type == return_inst) {
  831 + if (immfound) {
  832 + targetaddr = (immval << 16) & 0xffff0000;
  833 + targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
  834 + } else {
  835 + targetaddr = get_int_field_imm(inst);
  836 + if (targetaddr & 0x8000)
  837 + targetaddr |= 0xFFFF0000;
  838 + }
  839 + targetaddr += r1val;
  840 + *targetvalid = true;
  841 + } else {
  842 + *targetvalid = false;
  843 + }
  844 + return targetaddr;
  845 +}
  846 +#endif
... ...