/* Disassemble D30V instructions.
- Copyright 1997, 1998, 2000, 2001, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU opcodes library.
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-#include <stdio.h>
#include "sysdep.h"
+#include <stdio.h>
#include "opcode/d30v.h"
-#include "dis-asm.h"
+#include "disassemble.h"
#include "opintl.h"
+#include "libiberty.h"
#define PC_MASK 0xFFFFFFFF
static int
lookup_opcode (struct d30v_insn *insn, long num, int is_long)
{
- int i = 0, index;
+ int i = 0, op_index;
struct d30v_format *f;
struct d30v_opcode *op = (struct d30v_opcode *) d30v_opcode_table;
int op1 = (num >> 25) & 0x7;
while (op->op1 == op1 && op->op2 == op2)
{
/* Scan through all the formats for the opcode. */
- index = op->format[i++];
+ op_index = op->format[i++];
do
{
- f = (struct d30v_format *) &d30v_format_table[index];
- while (f->form == index)
+ f = (struct d30v_format *) &d30v_format_table[op_index];
+ while (f->form == op_index)
{
if ((!is_long || f->form >= LONG) && (f->modifier == mod))
{
if (insn->form)
break;
}
- while ((index = op->format[i++]) != 0);
+ while ((op_index = op->format[i++]) != 0);
if (insn->form)
break;
op++;
}
static int
-extract_value (long long num, struct d30v_operand *oper, int is_long)
+extract_value (uint64_t num, const struct d30v_operand *oper, int is_long)
{
- int val;
+ unsigned int val;
int shift = 12 - oper->position;
- int mask = (0xFFFFFFFF >> (32 - oper->bits));
+ unsigned int mask = (0xFFFFFFFF >> (32 - oper->bits));
if (is_long)
{
static void
print_insn (struct disassemble_info *info,
bfd_vma memaddr,
- long long num,
+ uint64_t num,
struct d30v_insn *insn,
int is_long,
int show_ext)
{
int val, opnum, need_comma = 0;
- struct d30v_operand *oper;
- int i, match, opind = 0, need_paren = 0, found_control = 0;
+ const struct d30v_operand *oper;
+ int i, match, need_paren = 0, found_control = 0;
+ unsigned int opind = 0;
(*info->fprintf_func) (info->stream, "%s", insn->op->name);
opind++;
val =
extract_value (num,
- (struct d30v_operand *) &d30v_operand_table[insn->form->operands[0]],
+ &d30v_operand_table[insn->form->operands[0]],
is_long);
(*info->fprintf_func) (info->stream, "%s", d30v_cc_names[val]);
}
(*info->fprintf_func) (info->stream, "\t");
- while ((opnum = insn->form->operands[opind++]) != 0)
+ while (opind < ARRAY_SIZE (insn->form->operands)
+ && (opnum = insn->form->operands[opind++]) != 0)
{
int bits;
- oper = (struct d30v_operand *) &d30v_operand_table[opnum];
+ oper = &d30v_operand_table[opnum];
bits = oper->bits;
if (oper->flags & OPERAND_SHIFT)
bits += 3;
match = 0;
if (oper->flags & OPERAND_CONTROL)
{
- struct d30v_operand *oper3 =
- (struct d30v_operand *) &d30v_operand_table[insn->form->operands[2]];
+ const struct d30v_operand *oper3
+ = &d30v_operand_table[insn->form->operands[2]];
int id = extract_value (num, oper3, is_long);
found_control = 1;
val |= OPERAND_FLAG;
break;
default:
- fprintf (stderr, "illegal id (%d)\n", id);
+ /* xgettext: c-format */
+ opcodes_error_handler (_("illegal id (%d)"), id);
+ abort ();
}
}
else if (oper->flags & OPERAND_ACC)
/* IMM6S3 is unsigned. */
if (oper->flags & OPERAND_SIGNED || bits == 32)
{
- long max;
- max = (1 << (bits - 1));
- if (val & max)
+ unsigned int sign = 1u << (bits - 1);
+ if (val & sign)
{
- if (bits == 32)
- val = -val;
- else
- val = -val & ((1 << bits) - 1);
+ val = -val & (sign + sign - 1);
neg = 1;
}
}
{
if (oper->flags & OPERAND_SIGNED)
{
- int max = (1 << (bits - 1));
+ unsigned int sign = 1u << (bits - 1);
- if (val & max)
+ if (val & sign)
{
- val = -val;
- if (bits < 32)
- val &= ((1 << bits) - 1);
+ val = -val & (sign + sign - 1);
(*info->fprintf_func) (info->stream, "-");
}
}
(*info->fprintf_func) (info->stream, "0x%x", val);
}
/* If there is another operand, then write a comma and space. */
- if (insn->form->operands[opind] && !(found_control && opind == 2))
+ if (opind < ARRAY_SIZE (insn->form->operands)
+ && insn->form->operands[opind]
+ && !(found_control && opind == 2))
need_comma = 1;
}
if (need_paren)
{
int status, result;
bfd_byte buffer[12];
- unsigned long in1, in2;
+ uint32_t in1, in2;
struct d30v_insn insn;
- long long num;
+ uint64_t num;
insn.form = NULL;
{
info->bytes_per_line = 8;
if (!(result = lookup_opcode (&insn, in1, 0)))
- (*info->fprintf_func) (info->stream, ".long\t0x%lx", in1);
+ (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);
else
- print_insn (info, memaddr, (long long) in1, &insn, 0, result);
+ print_insn (info, memaddr, (uint64_t) in1, &insn, 0, result);
return 4;
}
in2 = bfd_getb32 (buffer);
/* LONG instruction. */
if (!(result = lookup_opcode (&insn, in1, 1)))
{
- (*info->fprintf_func) (info->stream, ".long\t0x%lx,0x%lx", in1, in2);
+ (*info->fprintf_func) (info->stream, ".long\t0x%x,0x%x", in1, in2);
return 8;
}
- num = (long long) in1 << 32 | in2;
+ num = (uint64_t) in1 << 32 | in2;
print_insn (info, memaddr, num, &insn, 1, result);
}
else
{
num = in1;
if (!(result = lookup_opcode (&insn, in1, 0)))
- (*info->fprintf_func) (info->stream, ".long\t0x%lx", in1);
+ (*info->fprintf_func) (info->stream, ".long\t0x%x", in1);
else
print_insn (info, memaddr, num, &insn, 0, result);
insn.form = NULL;
num = in2;
if (!(result = lookup_opcode (&insn, in2, 0)))
- (*info->fprintf_func) (info->stream, ".long\t0x%lx", in2);
+ (*info->fprintf_func) (info->stream, ".long\t0x%x", in2);
else
print_insn (info, memaddr, num, &insn, 0, result);
}