/* Disassemble ADI Blackfin Instructions.
- Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
This file is part of libopcodes.
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
+#include "sysdep.h"
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "opcode/bfin.h"
typedef long TIword;
-#define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
-#define XFIELD(w,p,s) (((w) & ((1 << (s)) - 1) << (p)) >> (p))
-#define SIGNEXTEND(v, n) ((v << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
-#define MASKBITS(val, bits) (val & ((1 << bits) - 1))
+#define SIGNBIT(bits) (1ul << ((bits) - 1))
+#define MASKBITS(val, bits) ((val) & ((1ul << (bits)) - 1))
+#define SIGNEXTEND(v, n) ((MASKBITS (v, n) ^ SIGNBIT (n)) - SIGNBIT (n))
-#include "dis-asm.h"
+#include "disassemble.h"
typedef unsigned int bu32;
-static char comment = 0;
-static char parallel = 0;
+struct private
+{
+ TIword iw0;
+ bfd_boolean comment, parallel;
+};
typedef enum
{
if (constant_formats[cf].reloc)
{
- bfd_vma ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
- : x) + constant_formats[cf].offset) << constant_formats[cf].scale);
+ bfd_vma ea;
+
+ if (constant_formats[cf].pcrel)
+ x = SIGNEXTEND (x, constant_formats[cf].nbits);
+ ea = x + constant_formats[cf].offset;
+ ea = ea << constant_formats[cf].scale;
if (constant_formats[cf].pcrel)
ea += pc;
{
int nb = constant_formats[cf].nbits + 1;
- x = x | (1 << constant_formats[cf].nbits);
+ x = x | (1ul << constant_formats[cf].nbits);
x = SIGNEXTEND (x, nb);
}
- else
- x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbits) : x;
-
- if (constant_formats[cf].offset)
- x += constant_formats[cf].offset;
+ else if (constant_formats[cf].issigned)
+ x = SIGNEXTEND (x, constant_formats[cf].nbits);
- if (constant_formats[cf].scale)
- x <<= constant_formats[cf].scale;
+ x += constant_formats[cf].offset;
+ x = (unsigned long) x << constant_formats[cf].scale;
if (constant_formats[cf].decimal)
- {
- if (constant_formats[cf].leading)
- {
- char ps[10];
- sprintf (ps, "%%%ii", constant_formats[cf].leading);
- sprintf (buf, ps, x);
- }
- else
- sprintf (buf, "%li", x);
- }
+ sprintf (buf, "%*li", constant_formats[cf].leading, x);
else
{
if (constant_formats[cf].issigned && x < 0)
- sprintf (buf, "-0x%x", abs (x));
+ sprintf (buf, "-0x%lx", (unsigned long)(- x));
else
sprintf (buf, "0x%lx", (unsigned long) x);
}
{
if (0 && constant_formats[cf].reloc)
{
- bu32 ea = (((constant_formats[cf].pcrel
- ? SIGNEXTEND (x, constant_formats[cf].nbits)
- : x) + constant_formats[cf].offset)
- << constant_formats[cf].scale);
+ bu32 ea;
+
+ if (constant_formats[cf].pcrel)
+ x = SIGNEXTEND (x, constant_formats[cf].nbits);
+ ea = x + constant_formats[cf].offset;
+ ea = ea << constant_formats[cf].scale;
if (constant_formats[cf].pcrel)
ea += pc;
if (constant_formats[cf].negative)
{
int nb = constant_formats[cf].nbits + 1;
- x = x | (1 << constant_formats[cf].nbits);
+ x = x | (1ul << constant_formats[cf].nbits);
x = SIGNEXTEND (x, nb);
}
else if (constant_formats[cf].issigned)
REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
};
-#define gregs(x, i) REGNAME (decode_gregs[((i) << 3) | (x)])
+#define gregs(x, i) REGNAME (decode_gregs[(((i) << 3) | (x)) & 15])
/* [dregs pregs (iregs mregs) (bregs lregs)]. */
static const enum machine_registers decode_regs[] =
REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
};
-#define regs(x, i) REGNAME (decode_regs[((i) << 3) | (x)])
+#define regs(x, i) REGNAME (decode_regs[(((i) << 3) | (x)) & 31])
/* [dregs pregs (iregs mregs) (bregs lregs) Low Half]. */
static const enum machine_registers decode_regs_lo[] =
REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3,
};
-#define regs_lo(x, i) REGNAME (decode_regs_lo[((i) << 3) | (x)])
+#define regs_lo(x, i) REGNAME (decode_regs_lo[(((i) << 3) | (x)) & 31])
/* [dregs pregs (iregs mregs) (bregs lregs) High Half]. */
static const enum machine_registers decode_regs_hi[] =
REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3,
};
-#define regs_hi(x, i) REGNAME (decode_regs_hi[((i) << 3) | (x)])
+#define regs_hi(x, i) REGNAME (decode_regs_hi[(((i) << 3) | (x)) & 31])
static const enum machine_registers decode_statbits[] =
{
/* (arch.pm)arch_disassembler_functions. */
#ifndef OUTS
-#define OUTS(p, txt) ((p) ? (((txt)[0]) ? (p->fprintf_func)(p->stream, "%s", txt) :0) :0)
+#define OUTS(p, txt) (p)->fprintf_func ((p)->stream, "%s", txt)
#endif
+#define OUT(p, txt, ...) (p)->fprintf_func ((p)->stream, txt, ## __VA_ARGS__)
static void
amod0 (int s0, int x0, disassemble_info *outf)
static int
decode_ProgCtrl_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* ProgCtrl
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
if (prgfunc == 0 && poprnd == 0)
OUTS (outf, "NOP");
- else if (parallel)
+ else if (priv->parallel)
return 0;
else if (prgfunc == 1 && poprnd == 0)
OUTS (outf, "RTS");
static int
decode_CaCTRL_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* CaCTRL
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (a == 0 && op == 0)
static int
decode_PushPopReg_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* PushPopReg
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (W == 0 && mostreg (reg, grp))
static int
decode_PushPopMultiple_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* PushPopMultiple
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (pr > 5)
static int
decode_ccMV_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* ccMV
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (T == 1)
static int
decode_CCflag_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* CCflag
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (opc == 0 && I == 0 && G == 0)
static int
decode_CC2dreg_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* CC2dreg
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (op == 0)
static int
decode_CC2stat_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* CC2stat
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
const char *bitname = statbits (cbit);
+ const char * const op_names[] = { "", "|", "&", "^" } ;
- if (parallel)
+ if (priv->parallel)
return 0;
if (decode_statbits[cbit] == REG_LASTREG)
bitname = bitnames;
}
- if (op == 0 && D == 0)
- {
- OUTS (outf, "CC = ");
- OUTS (outf, bitname);
- }
- else if (op == 1 && D == 0)
- {
- OUTS (outf, "CC |= ");
- OUTS (outf, bitname);
- }
- else if (op == 2 && D == 0)
- {
- OUTS (outf, "CC &= ");
- OUTS (outf, bitname);
- }
- else if (op == 3 && D == 0)
- {
- OUTS (outf, "CC ^= ");
- OUTS (outf, bitname);
- }
- else if (op == 0 && D == 1)
- {
- OUTS (outf, bitname);
- OUTS (outf, " = CC");
- }
- else if (op == 1 && D == 1)
- {
- OUTS (outf, bitname);
- OUTS (outf, " |= CC");
- }
- else if (op == 2 && D == 1)
- {
- OUTS (outf, bitname);
- OUTS (outf, " &= CC");
- }
- else if (op == 3 && D == 1)
- {
- OUTS (outf, bitname);
- OUTS (outf, " ^= CC");
- }
+ if (D == 0)
+ OUT (outf, "CC %s= %s", op_names[op], bitname);
else
- return 0;
+ OUT (outf, "%s %s= CC", bitname, op_names[op]);
return 2;
}
static int
decode_BRCC_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* BRCC
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (T == 1 && B == 1)
static int
decode_UJUMP_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* UJUMP
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 0 | 1 | 0 |.offset........................................|
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
OUTS (outf, "JUMP.S 0x");
static int
decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* LOGI2op
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (opc == 0)
OUTS (outf, ");\t\t/* bit");
OUTS (outf, imm7d (src));
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (opc == 1)
{
OUTS (outf, ");\t\t/* bit");
OUTS (outf, imm7d (src));
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (opc == 2)
{
OUTS (outf, ");\t\t/* bit");
OUTS (outf, imm7d (src));
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (opc == 3)
{
OUTS (outf, ");\t\t/* bit");
OUTS (outf, imm7d (src));
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (opc == 4)
{
OUTS (outf, ");\t\t/* bit");
OUTS (outf, imm7d (src));
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (opc == 5)
{
static int
decode_COMPI2opD_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* COMPI2opD
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
bu32 *pval = get_allreg (0, dst);
- if (parallel)
+ if (priv->parallel)
return 0;
/* Since we don't have 32-bit immediate loads, we allow the disassembler
OUTS (outf, "(");
OUTS (outf, imm32 (*pval));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (op == 1)
{
OUTS (outf, ";\t\t/* (");
OUTS (outf, imm7d (src));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
else
return 0;
static int
decode_COMPI2opP_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* COMPI2opP
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
bu32 *pval = get_allreg (1, dst);
- if (parallel)
+ if (priv->parallel)
return 0;
if (op == 0)
OUTS (outf, "(");
OUTS (outf, imm32 (*pval));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (op == 1)
{
OUTS (outf, ";\t\t/* (");
OUTS (outf, imm7d (src));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
else
return 0;
static int
decode_dagMODik_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* dagMODik
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
else
return 0;
- if (! parallel)
+ if (!priv->parallel)
{
OUTS (outf, ";\t\t/* ( ");
if (op == 0 || op == 1)
else if (op == 2 || op == 3)
OUTS (outf, "4");
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
return 2;
static int
decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* LoopSetup
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (reg > 7)
static int
decode_LDIMMhalf_0 (TIword iw0, TIword iw1, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* LDIMMhalf
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
bu32 *pval = get_allreg (grp, reg);
- if (parallel)
+ if (priv->parallel)
return 0;
/* Since we don't have 32-bit immediate loads, we allow the disassembler
}
OUTS (outf, " */");
- comment = 1;
+ priv->comment = TRUE;
}
if (S == 1 || Z == 1)
{
OUTS (outf, "(");
OUTS (outf, imm32 (*pval));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
return 4;
}
static int
decode_CALLa_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* CALLa
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
int lsw = ((iw1 >> 0) & 0xffff);
int msw = ((iw0 >> 0) & 0xff);
- if (parallel)
+ if (priv->parallel)
return 0;
if (S == 1)
static int
decode_linkage_0 (TIword iw0, TIword iw1, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* linkage
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (R == 0)
OUTS (outf, ";\t\t/* (");
OUTS (outf, uimm16s4d (framesize));
OUTS (outf, ") */");
- comment = 1;
+ priv->comment = TRUE;
}
else if (R == 1)
OUTS (outf, "UNLINK");
{
if (MM)
OUTS (outf, " (M)");
- MM = 0;
OUTS (outf, ", ");
}
}
if (w0 == 1 || op0 != 3)
{
+ /* Clear MM option since it only matters for MAC1, and if we made
+ it this far, we've already shown it or we want to ignore it. */
+ MM = 0;
+
if (w0)
OUTS (outf, P ? dregs (dst) : dregs_lo (dst));
static int
decode_pseudoDEBUG_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* pseudoDEBUG
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (reg == 0 && fn == 3)
static int
decode_pseudoOChar_0 (TIword iw0, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* psedoOChar
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
OUTS (outf, "OUTC ");
static int
decode_pseudodbg_assert_0 (TIword iw0, TIword iw1, disassemble_info *outf)
{
+ struct private *priv = outf->private_data;
/* pseudodbg_assert
+---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
| 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
int grp = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
int regtest = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
- if (parallel)
+ if (priv->parallel)
return 0;
if (dbgop == 0)
return 4;
}
+static int
+ifetch (bfd_vma pc, disassemble_info *outf, TIword *iw)
+{
+ bfd_byte buf[2];
+ int status;
+
+ status = (*outf->read_memory_func) (pc, buf, 2, outf);
+ if (status != 0)
+ {
+ (*outf->memory_error_func) (status, pc, outf);
+ return -1;
+ }
+
+ *iw = bfd_getl16 (buf);
+ return 0;
+}
+
static int
_print_insn_bfin (bfd_vma pc, disassemble_info *outf)
{
- bfd_byte buf[4];
+ struct private *priv = outf->private_data;
TIword iw0;
TIword iw1;
- int status;
int rv = 0;
- status = (*outf->read_memory_func) (pc & ~0x1, buf, 2, outf);
- /* FIXME */
- (void) status;
- status = (*outf->read_memory_func) ((pc + 2) & ~0x1, buf + 2, 2, outf);
- /* FIXME */
- (void) status;
+ /* The PC must be 16-bit aligned. */
+ if (pc & 1)
+ {
+ OUTS (outf, "ILLEGAL (UNALIGNED)");
+ /* For people dumping data, just re-align the return value. */
+ return 1;
+ }
+
+ if (ifetch (pc, outf, &iw0))
+ return -1;
+ priv->iw0 = iw0;
- iw0 = bfd_getl16 (buf);
- iw1 = bfd_getl16 (buf + 2);
+ if (((iw0 & 0xc000) == 0xc000) && ((iw0 & 0xff00) != 0xf800))
+ {
+ /* 32-bit insn. */
+ if (ifetch (pc + 2, outf, &iw1))
+ return -1;
+ }
+ else
+ /* 16-bit insn. */
+ iw1 = 0;
if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
{
- if (parallel)
+ if (priv->parallel)
{
OUTS (outf, "ILLEGAL");
return 0;
int
print_insn_bfin (bfd_vma pc, disassemble_info *outf)
{
- bfd_byte buf[2];
- unsigned short iw0;
- int status;
- int count = 0;
+ struct private priv;
+ int count;
- status = (*outf->read_memory_func) (pc & ~0x01, buf, 2, outf);
- /* FIXME */
- (void) status;
- iw0 = bfd_getl16 (buf);
+ priv.parallel = FALSE;
+ priv.comment = FALSE;
+ outf->private_data = &priv;
- count += _print_insn_bfin (pc, outf);
+ count = _print_insn_bfin (pc, outf);
+ if (count == -1)
+ return -1;
/* Proper display of multiple issue instructions. */
- if (count == 4 && (iw0 & 0xc000) == 0xc000 && (iw0 & BIT_MULTI_INS)
- && ((iw0 & 0xe800) != 0xe800 /* Not Linkage. */ ))
+ if (count == 4 && (priv.iw0 & 0xc000) == 0xc000 && (priv.iw0 & BIT_MULTI_INS)
+ && ((priv.iw0 & 0xe800) != 0xe800 /* Not Linkage. */ ))
{
- int legal = 1;
+ bfd_boolean legal = TRUE;
int len;
- parallel = 1;
+ priv.parallel = TRUE;
OUTS (outf, " || ");
len = _print_insn_bfin (pc + 4, outf);
+ if (len == -1)
+ return -1;
OUTS (outf, " || ");
if (len != 2)
- legal = 0;
+ legal = FALSE;
len = _print_insn_bfin (pc + 6, outf);
+ if (len == -1)
+ return -1;
if (len != 2)
- legal = 0;
+ legal = FALSE;
if (legal)
count = 8;
else
{
OUTS (outf, ";\t\t/* ILLEGAL PARALLEL INSTRUCTION */");
- comment = 1;
+ priv.comment = TRUE;
count = 0;
}
- parallel = 0;
}
- if (!comment)
+ if (!priv.comment)
OUTS (outf, ";");
if (count == 0)
return 2;
- comment = 0;
-
return count;
}