Annotation of qemu/microblaze-dis.c, revision 1.1.1.1

1.1       root        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, see <http://www.gnu.org/licenses/>.  */
                     16: 
                     17: /*
                     18:  * Copyright (c) 2001 Xilinx, Inc.  All rights reserved. 
                     19:  *
                     20:  * Redistribution and use in source and binary forms are permitted
                     21:  * provided that the above copyright notice and this paragraph are
                     22:  * duplicated in all such forms and that any documentation,
                     23:  * advertising materials, and other materials related to such
                     24:  * distribution and use acknowledge that the software was developed
                     25:  * by Xilinx, Inc.  The name of the Company may not be used to endorse 
                     26:  * or promote products derived from this software without specific prior 
                     27:  * written permission.
                     28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     29:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     31:  *
                     32:  *     Xilinx, Inc.
                     33:  */
                     34: 
                     35: 
                     36: #include <stdio.h>
                     37: #define STATIC_TABLE
                     38: #define DEFINE_TABLE
                     39: 
                     40: #ifndef MICROBLAZE_OPC
                     41: #define MICROBLAZE_OPC
                     42: /* Assembler instructions for Xilinx's microblaze processor
                     43:    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
                     44: 
                     45:    
                     46: This program is free software; you can redistribute it and/or modify
                     47: it under the terms of the GNU General Public License as published by
                     48: the Free Software Foundation; either version 2 of the License, or
                     49: (at your option) any later version.
                     50: 
                     51: This program is distributed in the hope that it will be useful,
                     52: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     53: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     54: GNU General Public License for more details.
                     55: 
                     56: You should have received a copy of the GNU General Public License
                     57: along with this program; if not, see <http://www.gnu.org/licenses/>.  */
                     58: 
                     59: /*
                     60:  * Copyright (c) 2001 Xilinx, Inc.  All rights reserved. 
                     61:  *
                     62:  * Redistribution and use in source and binary forms are permitted
                     63:  * provided that the above copyright notice and this paragraph are
                     64:  * duplicated in all such forms and that any documentation,
                     65:  * advertising materials, and other materials related to such
                     66:  * distribution and use acknowledge that the software was developed
                     67:  * by Xilinx, Inc.  The name of the Company may not be used to endorse 
                     68:  * or promote products derived from this software without specific prior 
                     69:  * written permission.
                     70:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     71:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     72:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     73:  *
                     74:  *     Xilinx, Inc.
                     75:  */
                     76: 
                     77: 
                     78: #ifndef MICROBLAZE_OPCM
                     79: #define MICROBLAZE_OPCM
                     80: 
                     81: /*
                     82:  * Copyright (c) 2001 Xilinx, Inc.  All rights reserved. 
                     83:  *
                     84:  * Redistribution and use in source and binary forms are permitted
                     85:  * provided that the above copyright notice and this paragraph are
                     86:  * duplicated in all such forms and that any documentation,
                     87:  * advertising materials, and other materials related to such
                     88:  * distribution and use acknowledge that the software was developed
                     89:  * by Xilinx, Inc.  The name of the Company may not be used to endorse 
                     90:  * or promote products derived from this software without specific prior 
                     91:  * written permission.
                     92:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     93:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     94:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     95:  *
                     96:  *     Xilinx, Inc.
                     97:  * $Header:
                     98:  */
                     99: 
                    100: enum microblaze_instr {
                    101:    add, rsub, addc, rsubc, addk, rsubk, addkc, rsubkc, cmp, cmpu,
                    102:    addi, rsubi, addic, rsubic, addik, rsubik, addikc, rsubikc, mul,
                    103:    idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
                    104:    ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
                    105:    andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, wic, wdc, mts, mfs, br, brd,
                    106:    brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
                    107:    bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
                    108:    imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
                    109:    brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
                    110:    bgtid, bgei, bgeid, lbu, lhu, lw, sb, sh, sw, lbui, lhui, lwi,
                    111:    sbi, shi, swi, msrset, msrclr, tuqula, fadd, frsub, fmul, fdiv, 
                    112:    fcmp_lt, fcmp_eq, fcmp_le, fcmp_gt, fcmp_ne, fcmp_ge, fcmp_un, invalid_inst } ;
                    113: 
                    114: enum microblaze_instr_type {
                    115:    arithmetic_inst, logical_inst, mult_inst, div_inst, branch_inst,
                    116:    return_inst, immediate_inst, special_inst, memory_load_inst,
                    117:    memory_store_inst, barrel_shift_inst, anyware_inst };
                    118: 
                    119: #define INST_WORD_SIZE 4
                    120: 
                    121: /* gen purpose regs go from 0 to 31 */
                    122: /* mask is reg num - max_reg_num, ie reg_num - 32 in this case */
                    123: 
                    124: #define REG_PC_MASK 0x8000
                    125: #define REG_MSR_MASK 0x8001
                    126: #define REG_EAR_MASK 0x8003
                    127: #define REG_ESR_MASK 0x8005
                    128: #define REG_FSR_MASK 0x8007
                    129: 
                    130: #define MIN_REGNUM 0
                    131: #define MAX_REGNUM 31
                    132: 
                    133: #define REG_PC  32 /* PC */
                    134: #define REG_MSR 33 /* machine status reg */
                    135: #define REG_EAR 35 /* Exception reg */
                    136: #define REG_ESR 37 /* Exception reg */
                    137: #define REG_FSR 39 /* FPU Status reg */
                    138: 
                    139: /* alternate names for gen purpose regs */
                    140: #define REG_SP  1 /* stack pointer */
                    141: #define REG_ROSDP 2 /* read-only small data pointer */
                    142: #define REG_RWSDP 13 /* read-write small data pointer */
                    143: 
                    144: /* Assembler Register - Used in Delay Slot Optimization */
                    145: #define REG_AS    18
                    146: #define REG_ZERO  0
                    147:  
                    148: #define RD_LOW  21 /* low bit for RD */
                    149: #define RA_LOW  16 /* low bit for RA */
                    150: #define RB_LOW  11 /* low bit for RB */
                    151: #define IMM_LOW  0 /* low bit for immediate */
                    152: 
                    153: #define RD_MASK 0x03E00000
                    154: #define RA_MASK 0x001F0000
                    155: #define RB_MASK 0x0000F800
                    156: #define IMM_MASK 0x0000FFFF
                    157: 
                    158: // imm mask for barrel shifts
                    159: #define IMM5_MASK 0x0000001F
                    160: 
                    161: 
                    162: // imm mask for get, put instructions
                    163: #define  IMM12_MASK 0x00000FFF
                    164: 
                    165: // imm mask for msrset, msrclr instructions
                    166: #define  IMM14_MASK 0x00003FFF
                    167: 
                    168: #endif /* MICROBLAZE-OPCM */
                    169: 
                    170: #define INST_TYPE_RD_R1_R2 0
                    171: #define INST_TYPE_RD_R1_IMM 1
                    172: #define INST_TYPE_RD_R1_UNSIGNED_IMM 2
                    173: #define INST_TYPE_RD_R1 3
                    174: #define INST_TYPE_RD_R2 4
                    175: #define INST_TYPE_RD_IMM 5
                    176: #define INST_TYPE_R2 6
                    177: #define INST_TYPE_R1_R2 7
                    178: #define INST_TYPE_R1_IMM 8
                    179: #define INST_TYPE_IMM 9
                    180: #define INST_TYPE_SPECIAL_R1 10
                    181: #define INST_TYPE_RD_SPECIAL 11
                    182: #define INST_TYPE_R1 12
                    183:   // new instn type for barrel shift imms
                    184: #define INST_TYPE_RD_R1_IMM5  13
                    185: #define INST_TYPE_RD_IMM12    14
                    186: #define INST_TYPE_R1_IMM12    15
                    187: 
                    188:   // new insn type for insn cache
                    189: #define INST_TYPE_RD_R1_SPECIAL 16
                    190: 
                    191: // new insn type for msrclr, msrset insns.
                    192: #define INST_TYPE_RD_IMM14    17
                    193: 
                    194: // new insn type for tuqula rd - addik rd, r0, 42
                    195: #define INST_TYPE_RD    18
                    196: 
                    197: #define INST_TYPE_NONE 25
                    198: 
                    199: 
                    200: 
                    201: #define INST_PC_OFFSET 1 /* instructions where the label address is resolved as a PC offset (for branch label)*/
                    202: #define INST_NO_OFFSET 0 /* instructions where the label address is resolved as an absolute value (for data mem or abs address)*/
                    203: 
                    204: #define IMMVAL_MASK_NON_SPECIAL 0x0000
                    205: #define IMMVAL_MASK_MTS 0x4000
                    206: #define IMMVAL_MASK_MFS 0x0000
                    207: 
                    208: #define OPCODE_MASK_H   0xFC000000 /* High 6 bits only */
                    209: #define OPCODE_MASK_H1  0xFFE00000 /* High 11 bits */
                    210: #define OPCODE_MASK_H2  0xFC1F0000 /* High 6 and bits 20-16 */
                    211: #define OPCODE_MASK_H12 0xFFFF0000 /* High 16 */
                    212: #define OPCODE_MASK_H4  0xFC0007FF /* High 6 and low 11 bits */
                    213: #define OPCODE_MASK_H13S 0xFFE0FFF0 /* High 11 and 15:1 bits and last nibble of last byte for spr */
                    214: #define OPCODE_MASK_H23S 0xFC1FFFF0 /* High 6, 20-16 and 15:1 bits and last nibble of last byte for spr */
                    215: #define OPCODE_MASK_H34 0xFC00FFFF /* High 6 and low 16 bits */
                    216: #define OPCODE_MASK_H14 0xFFE007FF /* High 11 and low 11 bits */
                    217: #define OPCODE_MASK_H24 0xFC1F07FF /* High 6, bits 20-16 and low 11 bits */
                    218: #define OPCODE_MASK_H124  0xFFFF07FF /* High 16, and low 11 bits */
                    219: #define OPCODE_MASK_H1234 0xFFFFFFFF /* All 32 bits */
                    220: #define OPCODE_MASK_H3  0xFC000600 /* High 6 bits and bits 21, 22 */  
                    221: #define OPCODE_MASK_H32 0xFC00F000 /* High 6 bits and bit 16, 17, 18 and 19*/
                    222: #define OPCODE_MASK_H34B   0xFC0000FF /* High 6 bits and low 8 bits */
                    223: 
                    224: // New Mask for msrset, msrclr insns.
                    225: #define OPCODE_MASK_H23N  0xFC1FC000 /* High 6 and bits 12 - 18 */
                    226: 
                    227: #define DELAY_SLOT 1
                    228: #define NO_DELAY_SLOT 0
                    229: 
                    230: #define MAX_OPCODES 149
                    231: 
                    232: struct op_code_struct {
                    233:   const char *name;
                    234:   short inst_type; /* registers and immediate values involved */
                    235:   short inst_offset_type; /* immediate vals offset from PC? (= 1 for branches) */
                    236:   short delay_slots; /* info about delay slots needed after this instr. */
                    237:   short immval_mask;
                    238:   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 */ 
                    239:   unsigned long opcode_mask; /* which bits define the opcode */
                    240:   enum microblaze_instr instr;
                    241:   enum microblaze_instr_type instr_type;
                    242:   /* more info about output format here */
                    243: } opcodes[MAX_OPCODES] = 
                    244: 
                    245: { 
                    246:   {"add",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x00000000, OPCODE_MASK_H4, add, arithmetic_inst },
                    247:   {"rsub",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x04000000, OPCODE_MASK_H4, rsub, arithmetic_inst },
                    248:   {"addc",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x08000000, OPCODE_MASK_H4, addc, arithmetic_inst },
                    249:   {"rsubc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x0C000000, OPCODE_MASK_H4, rsubc, arithmetic_inst },
                    250:   {"addk",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x10000000, OPCODE_MASK_H4, addk, arithmetic_inst },
                    251:   {"rsubk", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000000, OPCODE_MASK_H4, rsubk, arithmetic_inst },
                    252:   {"cmp",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000001, OPCODE_MASK_H4, cmp, arithmetic_inst },
                    253:   {"cmpu",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x14000003, OPCODE_MASK_H4, cmpu, arithmetic_inst },
                    254:   {"addkc", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x18000000, OPCODE_MASK_H4, addkc, arithmetic_inst },
                    255:   {"rsubkc",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x1C000000, OPCODE_MASK_H4, rsubkc, arithmetic_inst },
                    256:   {"addi",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x20000000, OPCODE_MASK_H, addi, arithmetic_inst },
                    257:   {"rsubi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x24000000, OPCODE_MASK_H, rsubi, arithmetic_inst },
                    258:   {"addic", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x28000000, OPCODE_MASK_H, addic, arithmetic_inst },
                    259:   {"rsubic",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x2C000000, OPCODE_MASK_H, rsubic, arithmetic_inst },
                    260:   {"addik", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, addik, arithmetic_inst },
                    261:   {"rsubik",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x34000000, OPCODE_MASK_H, rsubik, arithmetic_inst },
                    262:   {"addikc",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x38000000, OPCODE_MASK_H, addikc, arithmetic_inst },
                    263:   {"rsubikc",INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3C000000, OPCODE_MASK_H, rsubikc, arithmetic_inst },
                    264:   {"mul",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x40000000, OPCODE_MASK_H4, mul, mult_inst },
                    265:   {"idiv",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x48000000, OPCODE_MASK_H4, idiv, div_inst },
                    266:   {"idivu", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x48000002, OPCODE_MASK_H4, idivu, div_inst },
                    267:   {"bsll",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000400, OPCODE_MASK_H3, bsll, barrel_shift_inst },
                    268:   {"bsra",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000200, OPCODE_MASK_H3, bsra, barrel_shift_inst },
                    269:   {"bsrl",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x44000000, OPCODE_MASK_H3, bsrl, barrel_shift_inst },
                    270:   {"get",   INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C000000, OPCODE_MASK_H32, get, anyware_inst },
                    271:   {"put",   INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C008000, OPCODE_MASK_H32, put, anyware_inst },
                    272:   {"nget",  INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C004000, OPCODE_MASK_H32, nget, anyware_inst },
                    273:   {"nput",  INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00C000, OPCODE_MASK_H32, nput, anyware_inst },
                    274:   {"cget",  INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C002000, OPCODE_MASK_H32, cget, anyware_inst },
                    275:   {"cput",  INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00A000, OPCODE_MASK_H32, cput, anyware_inst },
                    276:   {"ncget", INST_TYPE_RD_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C006000, OPCODE_MASK_H32, ncget, anyware_inst },
                    277:   {"ncput", INST_TYPE_R1_IMM12, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x6C00E000, OPCODE_MASK_H32, ncput, anyware_inst },
                    278:   {"muli",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x60000000, OPCODE_MASK_H, muli, mult_inst },
                    279:   {"bslli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000400, OPCODE_MASK_H3, bslli, barrel_shift_inst },
                    280:   {"bsrai", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000200, OPCODE_MASK_H3, bsrai, barrel_shift_inst },
                    281:   {"bsrli", INST_TYPE_RD_R1_IMM5, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x64000000, OPCODE_MASK_H3, bsrli, barrel_shift_inst },
                    282:   {"or",    INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H4, or, logical_inst },
                    283:   {"and",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000000, OPCODE_MASK_H4, and, logical_inst },
                    284:   {"xor",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000000, OPCODE_MASK_H4, xor, logical_inst },
                    285:   {"andn",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000000, OPCODE_MASK_H4, andn, logical_inst },
                    286:   {"pcmpbf",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000400, OPCODE_MASK_H4, pcmpbf, logical_inst },
                    287:   {"pcmpbc",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x84000400, OPCODE_MASK_H4, pcmpbc, logical_inst },
                    288:   {"pcmpeq",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x88000400, OPCODE_MASK_H4, pcmpeq, logical_inst },
                    289:   {"pcmpne",INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x8C000400, OPCODE_MASK_H4, pcmpne, logical_inst },
                    290:   {"sra",   INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000001, OPCODE_MASK_H34, sra, logical_inst },
                    291:   {"src",   INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000021, OPCODE_MASK_H34, src, logical_inst },
                    292:   {"srl",   INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000041, OPCODE_MASK_H34, srl, logical_inst },
                    293:   {"sext8", INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000060, OPCODE_MASK_H34, sext8, logical_inst },
                    294:   {"sext16",INST_TYPE_RD_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000061, OPCODE_MASK_H34, sext16, logical_inst },
                    295:   {"wic",   INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
                    296:   {"wdc",   INST_TYPE_RD_R1_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
                    297:   {"mts",   INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
                    298:   {"mfs",   INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
                    299:   {"br",    INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
                    300:   {"brd",   INST_TYPE_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98100000, OPCODE_MASK_H124, brd, branch_inst },
                    301:   {"brld",  INST_TYPE_RD_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98140000, OPCODE_MASK_H24, brld, branch_inst },
                    302:   {"bra",   INST_TYPE_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98080000, OPCODE_MASK_H124, bra, branch_inst },
                    303:   {"brad",  INST_TYPE_R2, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98180000, OPCODE_MASK_H124, brad, branch_inst },
                    304:   {"brald", INST_TYPE_RD_R2, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x981C0000, OPCODE_MASK_H24, brald, branch_inst },
                    305:   {"brk",   INST_TYPE_RD_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x980C0000, OPCODE_MASK_H24, microblaze_brk, branch_inst },
                    306:   {"beq",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C000000, OPCODE_MASK_H14, beq, branch_inst },
                    307:   {"beqd",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E000000, OPCODE_MASK_H14, beqd, branch_inst },
                    308:   {"bne",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C200000, OPCODE_MASK_H14, bne, branch_inst },
                    309:   {"bned",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E200000, OPCODE_MASK_H14, bned, branch_inst },
                    310:   {"blt",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C400000, OPCODE_MASK_H14, blt, branch_inst },
                    311:   {"bltd",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E400000, OPCODE_MASK_H14, bltd, branch_inst },
                    312:   {"ble",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C600000, OPCODE_MASK_H14, ble, branch_inst },
                    313:   {"bled",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E600000, OPCODE_MASK_H14, bled, branch_inst },
                    314:   {"bgt",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9C800000, OPCODE_MASK_H14, bgt, branch_inst },
                    315:   {"bgtd",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E800000, OPCODE_MASK_H14, bgtd, branch_inst },
                    316:   {"bge",   INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9CA00000, OPCODE_MASK_H14, bge, branch_inst },
                    317:   {"bged",  INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9EA00000, OPCODE_MASK_H14, bged, branch_inst },
                    318:   {"ori",   INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, ori, logical_inst },
                    319:   {"andi",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, andi, logical_inst },
                    320:   {"xori",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, xori, logical_inst },
                    321:   {"andni", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, andni, logical_inst },
                    322:   {"imm",   INST_TYPE_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB0000000, OPCODE_MASK_H12, imm, immediate_inst },
                    323:   {"rtsd",  INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000000, OPCODE_MASK_H1, rtsd, return_inst },
                    324:   {"rtid",  INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6200000, OPCODE_MASK_H1, rtid, return_inst },
                    325:   {"rtbd",  INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6400000, OPCODE_MASK_H1, rtbd, return_inst },
                    326:   {"rted",  INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6800000, OPCODE_MASK_H1, rted, return_inst },
                    327:   {"bri",   INST_TYPE_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8000000, OPCODE_MASK_H12, bri, branch_inst },
                    328:   {"brid",  INST_TYPE_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8100000, OPCODE_MASK_H12, brid, branch_inst },
                    329:   {"brlid", INST_TYPE_RD_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8140000, OPCODE_MASK_H2, brlid, branch_inst },
                    330:   {"brai",  INST_TYPE_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8080000, OPCODE_MASK_H12, brai, branch_inst },
                    331:   {"braid", INST_TYPE_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB8180000, OPCODE_MASK_H12, braid, branch_inst },
                    332:   {"bralid",INST_TYPE_RD_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB81C0000, OPCODE_MASK_H2, bralid, branch_inst },
                    333:   {"brki",  INST_TYPE_RD_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB80C0000, OPCODE_MASK_H2, brki, branch_inst },
                    334:   {"beqi",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC000000, OPCODE_MASK_H1, beqi, branch_inst },
                    335:   {"beqid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE000000, OPCODE_MASK_H1, beqid, branch_inst },
                    336:   {"bnei",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC200000, OPCODE_MASK_H1, bnei, branch_inst },
                    337:   {"bneid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE200000, OPCODE_MASK_H1, bneid, branch_inst },
                    338:   {"blti",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC400000, OPCODE_MASK_H1, blti, branch_inst },
                    339:   {"bltid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE400000, OPCODE_MASK_H1, bltid, branch_inst },
                    340:   {"blei",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC600000, OPCODE_MASK_H1, blei, branch_inst },
                    341:   {"bleid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE600000, OPCODE_MASK_H1, bleid, branch_inst },
                    342:   {"bgti",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBC800000, OPCODE_MASK_H1, bgti, branch_inst },
                    343:   {"bgtid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBE800000, OPCODE_MASK_H1, bgtid, branch_inst },
                    344:   {"bgei",  INST_TYPE_R1_IMM, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBCA00000, OPCODE_MASK_H1, bgei, branch_inst },
                    345:   {"bgeid", INST_TYPE_R1_IMM, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xBEA00000, OPCODE_MASK_H1, bgeid, branch_inst },
                    346:   {"lbu",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC0000000, OPCODE_MASK_H4, lbu, memory_load_inst },
                    347:   {"lhu",   INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC4000000, OPCODE_MASK_H4, lhu, memory_load_inst },
                    348:   {"lw",    INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xC8000000, OPCODE_MASK_H4, lw, memory_load_inst },
                    349:   {"sb",    INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD0000000, OPCODE_MASK_H4, sb, memory_store_inst },
                    350:   {"sh",    INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD4000000, OPCODE_MASK_H4, sh, memory_store_inst },
                    351:   {"sw",    INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst },
                    352:   {"lbui",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst },
                    353:   {"lhui",  INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst },
                    354:   {"lwi",   INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, lwi, memory_load_inst },
                    355:   {"sbi",   INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF0000000, OPCODE_MASK_H, sbi, memory_store_inst },
                    356:   {"shi",   INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF4000000, OPCODE_MASK_H, shi, memory_store_inst },
                    357:   {"swi",   INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, swi, memory_store_inst },
                    358:   {"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 */
                    359:   {"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 */
                    360:   {"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 */
                    361:   {"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 */
                    362:   {"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 */
                    363:   {"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 */
                    364:   {"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 */
                    365:   {"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 },
                    366:   {"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 },
                    367:   {"msrset",INST_TYPE_RD_IMM14, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94100000, OPCODE_MASK_H23N, msrset, special_inst },
                    368:   {"msrclr",INST_TYPE_RD_IMM14, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x94110000, OPCODE_MASK_H23N, msrclr, special_inst },
                    369:   {"fadd",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000000, OPCODE_MASK_H4, fadd, arithmetic_inst },
                    370:   {"frsub",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000080, OPCODE_MASK_H4, frsub, arithmetic_inst },
                    371:   {"fmul",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000100, OPCODE_MASK_H4, fmul, arithmetic_inst },
                    372:   {"fdiv",  INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x58000180, OPCODE_MASK_H4, fdiv, arithmetic_inst },
                    373:   {"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 },
                    374:   {"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 },
                    375:   {"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 },
                    376:   {"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 },
                    377:   {"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 },
                    378:   {"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 },
                    379:   {"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 },
                    380:   {""}
                    381: };
                    382: 
                    383: /* prefix for register names */
                    384: char register_prefix[] = "r";
                    385: char special_register_prefix[] = "spr";
                    386: char fsl_register_prefix[] = "rfsl";
                    387: 
                    388: 
                    389: /* #defines for valid immediate range */
                    390: #define MIN_IMM  0x80000000
                    391: #define MAX_IMM  0x7fffffff 
                    392: 
                    393: #define MIN_IMM12  0x000
                    394: #define MAX_IMM12  0x7ff
                    395: 
                    396: #define MIN_IMM14  0x0000
                    397: #define MAX_IMM14  0x1fff
                    398: 
                    399: #endif /* MICROBLAZE_OPC */
                    400: 
                    401: #include "dis-asm.h"
                    402: #include <strings.h>
                    403: 
                    404: #define get_field_rd(instr) get_field(instr, RD_MASK, RD_LOW)
                    405: #define get_field_r1(instr) get_field(instr, RA_MASK, RA_LOW)
                    406: #define get_field_r2(instr) get_field(instr, RB_MASK, RB_LOW)
                    407: #define get_int_field_imm(instr) ((instr & IMM_MASK) >> IMM_LOW)
                    408: #define get_int_field_r1(instr) ((instr & RA_MASK) >> RA_LOW)
                    409: 
                    410: static char *
                    411: get_field (long instr, long mask, unsigned short low) 
                    412: {
                    413:   char tmpstr[25];
                    414:   sprintf(tmpstr, "%s%d", register_prefix, (int)((instr & mask) >> low));
                    415:   return(strdup(tmpstr));
                    416: }
                    417: 
                    418: static char *
                    419: get_field_imm (long instr) 
                    420: {
                    421:   char tmpstr[25];
                    422:   sprintf(tmpstr, "%d", (short)((instr & IMM_MASK) >> IMM_LOW));
                    423:   return(strdup(tmpstr));
                    424: }
                    425: 
                    426: static char *
                    427: get_field_imm5 (long instr) 
                    428: {
                    429:   char tmpstr[25];
                    430:   sprintf(tmpstr, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
                    431:   return(strdup(tmpstr));
                    432: }
                    433: 
                    434: static char *
                    435: get_field_imm12 (long instr) 
                    436: {
                    437:   char tmpstr[25];
                    438:   sprintf(tmpstr, "%s%d", fsl_register_prefix, (short)((instr & IMM12_MASK) >> IMM_LOW));
                    439:   return(strdup(tmpstr));
                    440: }
                    441: 
                    442: static char *
                    443: get_field_imm14 (long instr) 
                    444: {
                    445:   char tmpstr[25];
                    446:   sprintf(tmpstr, "%d", (short)((instr & IMM14_MASK) >> IMM_LOW));
                    447:   return(strdup(tmpstr));
                    448: }
                    449: 
                    450: #if 0
                    451: static char *
                    452: get_field_unsigned_imm (long instr) 
                    453: {
                    454:   char tmpstr[25];
                    455:   sprintf(tmpstr, "%d", (int)((instr & IMM_MASK) >> IMM_LOW));
                    456:   return(strdup(tmpstr));
                    457: }
                    458: #endif
                    459: 
                    460: /*
                    461:   char *
                    462:   get_field_special (instr) 
                    463:   long instr;
                    464:   {
                    465:   char tmpstr[25];
                    466:   
                    467:   sprintf(tmpstr, "%s%s", register_prefix, (((instr & IMM_MASK) >> IMM_LOW) & REG_MSR_MASK) == 0 ? "pc" : "msr");
                    468:   
                    469:   return(strdup(tmpstr));
                    470:   }
                    471: */
                    472: 
                    473: static char *
                    474: get_field_special (long instr, struct op_code_struct * op) 
                    475: {
                    476:    char tmpstr[25];
                    477:    char spr[5];
                    478: 
                    479:    switch ( (((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) ) {
                    480:    case REG_MSR_MASK :
                    481:       strcpy(spr, "msr");
                    482:       break;
                    483:    case REG_PC_MASK :
                    484:       strcpy(spr, "pc");
                    485:       break;
                    486:    case REG_EAR_MASK :
                    487:       strcpy(spr, "ear");
                    488:       break;
                    489:    case REG_ESR_MASK :
                    490:       strcpy(spr, "esr");
                    491:       break;
                    492:    case REG_FSR_MASK :
                    493:       strcpy(spr, "fsr");
                    494:       break;      
                    495:    default :
                    496:       strcpy(spr, "pc");
                    497:       break;
                    498:    }
                    499:    
                    500:    sprintf(tmpstr, "%s%s", register_prefix, spr);
                    501:    return(strdup(tmpstr));
                    502: }
                    503: 
                    504: static unsigned long
                    505: read_insn_microblaze(bfd_vma memaddr, struct disassemble_info *info,
                    506:                      struct op_code_struct ** opr)
                    507: {
                    508:   unsigned char       ibytes[4];
                    509:   int                 status;
                    510:   struct op_code_struct * op;
                    511:   unsigned long inst;
                    512: 
                    513:   status = info->read_memory_func (memaddr, ibytes, 4, info);
                    514: 
                    515:   if (status != 0) 
                    516:     {
                    517:       info->memory_error_func (status, memaddr, info);
                    518:       return 0;
                    519:     }
                    520: 
                    521:   if (info->endian == BFD_ENDIAN_BIG)
                    522:     inst = (ibytes[0] << 24) | (ibytes[1] << 16) | (ibytes[2] << 8) | ibytes[3];
                    523:   else if (info->endian == BFD_ENDIAN_LITTLE)
                    524:     inst = (ibytes[3] << 24) | (ibytes[2] << 16) | (ibytes[1] << 8) | ibytes[0];
                    525:   else
                    526:     abort ();
                    527: 
                    528:   /* Just a linear search of the table.  */
                    529:   for (op = opcodes; op->name != 0; op ++)
                    530:     if (op->bit_sequence == (inst & op->opcode_mask))
                    531:       break;
                    532: 
                    533:   *opr = op;
                    534:   return inst;
                    535: }
                    536: 
                    537: 
                    538: int 
                    539: print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
                    540: {
                    541:   fprintf_ftype       fprintf = info->fprintf_func;
                    542:   void *              stream = info->stream;
                    543:   unsigned long       inst, prev_inst;
                    544:   struct op_code_struct * op, *pop;
                    545:   int                 immval = 0;
                    546:   boolean             immfound = false;
                    547:   static bfd_vma prev_insn_addr = -1; /*init the prev insn addr */
                    548:   static int     prev_insn_vma = -1;  /*init the prev insn vma */
                    549:   int            curr_insn_vma = info->buffer_vma;
                    550: 
                    551:   info->bytes_per_chunk = 4;
                    552: 
                    553:   inst = read_insn_microblaze (memaddr, info, &op);
                    554:   if (inst == 0)
                    555:     return -1;
                    556:   
                    557:   if (prev_insn_vma == curr_insn_vma) {
                    558:   if (memaddr-(info->bytes_per_chunk) == prev_insn_addr) {
                    559:     prev_inst = read_insn_microblaze (prev_insn_addr, info, &pop);
                    560:     if (prev_inst == 0)
                    561:       return -1;
                    562:     if (pop->instr == imm) {
                    563:       immval = (get_int_field_imm(prev_inst) << 16) & 0xffff0000;
                    564:       immfound = true;
                    565:     }
                    566:     else {
                    567:       immval = 0;
                    568:       immfound = false;
                    569:     }
                    570:   }
                    571:   }
                    572:   /* make curr insn as prev insn */
                    573:   prev_insn_addr = memaddr;
                    574:   prev_insn_vma = curr_insn_vma;
                    575: 
                    576:   if (op->name == 0)
                    577:     fprintf (stream, ".short 0x%04x", inst);
                    578:   else
                    579:     {
                    580:       fprintf (stream, "%s", op->name);
                    581:       
                    582:       switch (op->inst_type)
                    583:        {
                    584:   case INST_TYPE_RD_R1_R2:
                    585:      fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_r2(inst));
                    586:      break;
                    587:         case INST_TYPE_RD_R1_IMM:
                    588:          fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_imm(inst));
                    589:          if (info->print_address_func && get_int_field_r1(inst) == 0 && info->symbol_at_address_func) {
                    590:            if (immfound)
                    591:              immval |= (get_int_field_imm(inst) & 0x0000ffff);
                    592:            else {
                    593:              immval = get_int_field_imm(inst);
                    594:              if (immval & 0x8000)
                    595:                immval |= 0xFFFF0000;
                    596:            }
                    597:            if (immval > 0 && info->symbol_at_address_func(immval, info)) {
                    598:              fprintf (stream, "\t// ");
                    599:              info->print_address_func (immval, info);
                    600:            }
                    601:          }
                    602:          break;
                    603:        case INST_TYPE_RD_R1_IMM5:
                    604:          fprintf(stream, "\t%s, %s, %s", get_field_rd(inst), get_field_r1(inst), get_field_imm5(inst));
                    605:          break;
                    606:        case INST_TYPE_RD_IMM12:
                    607:          fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm12(inst));
                    608:          break;
                    609:        case INST_TYPE_R1_IMM12:
                    610:          fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_imm12(inst));
                    611:          break;
                    612:        case INST_TYPE_RD_SPECIAL:
                    613:          fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_special(inst, op));
                    614:          break;
                    615:        case INST_TYPE_SPECIAL_R1:
                    616:          fprintf(stream, "\t%s, %s", get_field_special(inst, op), get_field_r1(inst));
                    617:          break;
                    618:        case INST_TYPE_RD_R1:
                    619:          fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r1(inst));
                    620:          break;
                    621:        case INST_TYPE_R1_R2:
                    622:          fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_r2(inst));
                    623:          break;
                    624:        case INST_TYPE_R1_IMM:
                    625:          fprintf(stream, "\t%s, %s", get_field_r1(inst), get_field_imm(inst));
                    626:          /* The non-pc relative instructions are returns, which shouldn't 
                    627:             have a label printed */
                    628:          if (info->print_address_func && op->inst_offset_type == INST_PC_OFFSET && info->symbol_at_address_func) {
                    629:            if (immfound)
                    630:              immval |= (get_int_field_imm(inst) & 0x0000ffff);
                    631:            else {
                    632:              immval = get_int_field_imm(inst);
                    633:              if (immval & 0x8000)
                    634:                immval |= 0xFFFF0000;
                    635:            }
                    636:            immval += memaddr;
                    637:            if (immval > 0 && info->symbol_at_address_func(immval, info)) {
                    638:              fprintf (stream, "\t// ");
                    639:              info->print_address_func (immval, info);
                    640:            } else {
                    641:              fprintf (stream, "\t\t// ");
                    642:              fprintf (stream, "%x", immval);
                    643:            }
                    644:          }
                    645:          break;
                    646:         case INST_TYPE_RD_IMM:
                    647:          fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm(inst));
                    648:          if (info->print_address_func && info->symbol_at_address_func) {
                    649:            if (immfound)
                    650:              immval |= (get_int_field_imm(inst) & 0x0000ffff);
                    651:            else {
                    652:              immval = get_int_field_imm(inst);
                    653:              if (immval & 0x8000)
                    654:                immval |= 0xFFFF0000;
                    655:            }
                    656:            if (op->inst_offset_type == INST_PC_OFFSET)
                    657:              immval += (int) memaddr;
                    658:            if (info->symbol_at_address_func(immval, info)) {
                    659:              fprintf (stream, "\t// ");
                    660:              info->print_address_func (immval, info);
                    661:            } 
                    662:          }
                    663:          break;
                    664:         case INST_TYPE_IMM:
                    665:          fprintf(stream, "\t%s", get_field_imm(inst));
                    666:          if (info->print_address_func && info->symbol_at_address_func && op->instr != imm) {
                    667:            if (immfound)
                    668:              immval |= (get_int_field_imm(inst) & 0x0000ffff);
                    669:            else {
                    670:              immval = get_int_field_imm(inst);
                    671:              if (immval & 0x8000)
                    672:                immval |= 0xFFFF0000;
                    673:            }
                    674:            if (op->inst_offset_type == INST_PC_OFFSET)
                    675:              immval += (int) memaddr;
                    676:            if (immval > 0 && info->symbol_at_address_func(immval, info)) {
                    677:              fprintf (stream, "\t// ");
                    678:              info->print_address_func (immval, info);
                    679:            } else if (op->inst_offset_type == INST_PC_OFFSET) {
                    680:              fprintf (stream, "\t\t// ");
                    681:              fprintf (stream, "%x", immval);
                    682:            }
                    683:          }
                    684:          break;
                    685:         case INST_TYPE_RD_R2:
                    686:          fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
                    687:          break;
                    688:   case INST_TYPE_R2:
                    689:      fprintf(stream, "\t%s", get_field_r2(inst));
                    690:      break;
                    691:   case INST_TYPE_R1:
                    692:      fprintf(stream, "\t%s", get_field_r1(inst));
                    693:      break;
                    694:   case INST_TYPE_RD_R1_SPECIAL:
                    695:      fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_r2(inst));
                    696:      break;
                    697:   case INST_TYPE_RD_IMM14:
                    698:      fprintf(stream, "\t%s, %s", get_field_rd(inst), get_field_imm14(inst));
                    699:      break;
                    700:      /* For tuqula instruction */
                    701:   case INST_TYPE_RD:
                    702:      fprintf(stream, "\t%s", get_field_rd(inst));
                    703:      break;
                    704:      
                    705:   default:
                    706:          /* if the disassembler lags the instruction set */
                    707:          fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
                    708:          break;
                    709:        }
                    710:     }
                    711:   
                    712:   /* Say how many bytes we consumed? */
                    713:   return 4;
                    714: }
                    715: 
                    716: #if 0
                    717: static enum microblaze_instr
                    718: get_insn_microblaze (long inst, boolean *isunsignedimm,
                    719:                      enum microblaze_instr_type *insn_type,
                    720:                      short *delay_slots ) 
                    721: {
                    722:   struct op_code_struct * op;
                    723:   *isunsignedimm = false;
                    724: 
                    725:   /* Just a linear search of the table.  */
                    726:   for (op = opcodes; op->name != 0; op ++)
                    727:     if (op->bit_sequence == (inst & op->opcode_mask))
                    728:       break;
                    729: 
                    730:   if (op->name == 0)
                    731:     return invalid_inst;
                    732:   else {
                    733:     *isunsignedimm = (op->inst_type == INST_TYPE_RD_R1_UNSIGNED_IMM);
                    734:     *insn_type = op->instr_type;
                    735:     *delay_slots = op->delay_slots;
                    736:     return op->instr;
                    737:   }
                    738: }
                    739: #endif
                    740: 
                    741: #if 0
                    742: static short
                    743: get_delay_slots_microblaze ( long inst )
                    744: {
                    745:   boolean isunsignedimm;
                    746:   enum microblaze_instr_type insn_type;
                    747:   enum microblaze_instr op;
                    748:   short delay_slots;
                    749: 
                    750:   op = get_insn_microblaze( inst, &isunsignedimm, &insn_type, &delay_slots);
                    751:   if (op == invalid_inst)
                    752:     return 0;
                    753:   else 
                    754:     return delay_slots;
                    755: }
                    756: #endif
                    757: 
                    758: #if 0
                    759: static enum microblaze_instr
                    760: microblaze_decode_insn (long insn, int *rd, int *ra, int *rb, int *imm)
                    761: {
                    762:   enum microblaze_instr op;
                    763:   boolean t1;
                    764:   enum microblaze_instr_type t2;
                    765:   short t3;
                    766: 
                    767:   op = get_insn_microblaze(insn, &t1, &t2, &t3);
                    768:   *rd = (insn & RD_MASK) >> RD_LOW;
                    769:   *ra = (insn & RA_MASK) >> RA_LOW;
                    770:   *rb = (insn & RB_MASK) >> RB_LOW;
                    771:   t3 = (insn & IMM_MASK) >> IMM_LOW;
                    772:   *imm = (int) t3;
                    773:   return (op);
                    774: }
                    775: #endif
                    776: 
                    777: #if 0
                    778: static unsigned long
                    779: microblaze_get_target_address (long inst, boolean immfound, int immval,
                    780:                                long pcval, long r1val, long r2val,
                    781:                                boolean *targetvalid,
                    782:                                boolean *unconditionalbranch)
                    783: {
                    784:   struct op_code_struct * op;
                    785:   long targetaddr = 0;
                    786: 
                    787:   *unconditionalbranch = false;
                    788:   /* Just a linear search of the table.  */
                    789:   for (op = opcodes; op->name != 0; op ++)
                    790:     if (op->bit_sequence == (inst & op->opcode_mask))
                    791:       break;
                    792: 
                    793:   if (op->name == 0) {
                    794:     *targetvalid = false;
                    795:   } else if (op->instr_type == branch_inst) {
                    796:     switch (op->inst_type) {
                    797:     case INST_TYPE_R2:
                    798:       *unconditionalbranch = true;
                    799:       /* fallthru */
                    800:     case INST_TYPE_RD_R2:
                    801:     case INST_TYPE_R1_R2:
                    802:       targetaddr = r2val;
                    803:       *targetvalid = true;
                    804:       if (op->inst_offset_type == INST_PC_OFFSET)
                    805:        targetaddr += pcval;
                    806:       break;
                    807:     case INST_TYPE_IMM:
                    808:       *unconditionalbranch = true;
                    809:       /* fallthru */
                    810:     case INST_TYPE_RD_IMM:
                    811:     case INST_TYPE_R1_IMM:
                    812:       if (immfound) {
                    813:        targetaddr = (immval << 16) & 0xffff0000;
                    814:        targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
                    815:       } else {
                    816:        targetaddr = get_int_field_imm(inst);
                    817:        if (targetaddr & 0x8000)
                    818:          targetaddr |= 0xFFFF0000;
                    819:       }
                    820:       if (op->inst_offset_type == INST_PC_OFFSET)
                    821:        targetaddr += pcval;
                    822:       *targetvalid = true;
                    823:       break;
                    824:     default:
                    825:       *targetvalid = false;
                    826:       break;
                    827:     }
                    828:   } else if (op->instr_type == return_inst) {
                    829:       if (immfound) {
                    830:        targetaddr = (immval << 16) & 0xffff0000;
                    831:        targetaddr |= (get_int_field_imm(inst) & 0x0000ffff);
                    832:       } else {
                    833:        targetaddr = get_int_field_imm(inst);
                    834:        if (targetaddr & 0x8000)
                    835:          targetaddr |= 0xFFFF0000;
                    836:       }
                    837:       targetaddr += r1val;
                    838:       *targetvalid = true;
                    839:   } else {
                    840:     *targetvalid = false;
                    841:   }
                    842:   return targetaddr;
                    843: }
                    844: #endif

unix.superglobalmegacorp.com