version 1.1.1.7, 2018/11/06 21:19:16 |
version 1.1.1.8, 2020/04/03 23:39:48 |
|
|
/* Disassemble D30V instructions. |
/* Disassemble D30V instructions. |
Copyright (C) 1997-2018 Free Software Foundation, Inc. |
Copyright (C) 1997-2020 Free Software Foundation, Inc. |
|
|
This file is part of the GNU opcodes library. |
This file is part of the GNU opcodes library. |
|
|
|
|
#include "opcode/d30v.h" |
#include "opcode/d30v.h" |
#include "disassemble.h" |
#include "disassemble.h" |
#include "opintl.h" |
#include "opintl.h" |
|
#include "libiberty.h" |
|
|
#define PC_MASK 0xFFFFFFFF |
#define PC_MASK 0xFFFFFFFF |
|
|
Line 89 lookup_opcode (struct d30v_insn *insn, l |
|
Line 90 lookup_opcode (struct d30v_insn *insn, l |
|
} |
} |
|
|
static int |
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 shift = 12 - oper->position; |
int mask = (0xFFFFFFFF >> (32 - oper->bits)); |
unsigned int mask = (0xFFFFFFFF >> (32 - oper->bits)); |
|
|
if (is_long) |
if (is_long) |
{ |
{ |
Line 117 extract_value (long long num, struct d30 |
|
Line 118 extract_value (long long num, struct d30 |
|
static void |
static void |
print_insn (struct disassemble_info *info, |
print_insn (struct disassemble_info *info, |
bfd_vma memaddr, |
bfd_vma memaddr, |
long long num, |
uint64_t num, |
struct d30v_insn *insn, |
struct d30v_insn *insn, |
int is_long, |
int is_long, |
int show_ext) |
int show_ext) |
{ |
{ |
int val, opnum, need_comma = 0; |
int val, opnum, need_comma = 0; |
struct d30v_operand *oper; |
const struct d30v_operand *oper; |
int i, match, opind = 0, need_paren = 0, found_control = 0; |
int i, match, need_paren = 0, found_control = 0; |
|
unsigned int opind = 0; |
|
|
(*info->fprintf_func) (info->stream, "%s", insn->op->name); |
(*info->fprintf_func) (info->stream, "%s", insn->op->name); |
|
|
Line 134 print_insn (struct disassemble_info *inf |
|
Line 136 print_insn (struct disassemble_info *inf |
|
opind++; |
opind++; |
val = |
val = |
extract_value (num, |
extract_value (num, |
(struct d30v_operand *) &d30v_operand_table[insn->form->operands[0]], |
&d30v_operand_table[insn->form->operands[0]], |
is_long); |
is_long); |
(*info->fprintf_func) (info->stream, "%s", d30v_cc_names[val]); |
(*info->fprintf_func) (info->stream, "%s", d30v_cc_names[val]); |
} |
} |
Line 153 print_insn (struct disassemble_info *inf |
|
Line 155 print_insn (struct disassemble_info *inf |
|
|
|
(*info->fprintf_func) (info->stream, "\t"); |
(*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; |
int bits; |
|
|
oper = (struct d30v_operand *) &d30v_operand_table[opnum]; |
oper = &d30v_operand_table[opnum]; |
bits = oper->bits; |
bits = oper->bits; |
if (oper->flags & OPERAND_SHIFT) |
if (oper->flags & OPERAND_SHIFT) |
bits += 3; |
bits += 3; |
Line 207 print_insn (struct disassemble_info *inf |
|
Line 210 print_insn (struct disassemble_info *inf |
|
match = 0; |
match = 0; |
if (oper->flags & OPERAND_CONTROL) |
if (oper->flags & OPERAND_CONTROL) |
{ |
{ |
struct d30v_operand *oper3 = |
const struct d30v_operand *oper3 |
(struct d30v_operand *) &d30v_operand_table[insn->form->operands[2]]; |
= &d30v_operand_table[insn->form->operands[2]]; |
int id = extract_value (num, oper3, is_long); |
int id = extract_value (num, oper3, is_long); |
|
|
found_control = 1; |
found_control = 1; |
Line 268 print_insn (struct disassemble_info *inf |
|
Line 271 print_insn (struct disassemble_info *inf |
|
/* IMM6S3 is unsigned. */ |
/* IMM6S3 is unsigned. */ |
if (oper->flags & OPERAND_SIGNED || bits == 32) |
if (oper->flags & OPERAND_SIGNED || bits == 32) |
{ |
{ |
long max; |
unsigned int sign = 1u << (bits - 1); |
max = (1 << (bits - 1)); |
if (val & sign) |
if (val & max) |
|
{ |
{ |
if (bits == 32) |
val = -val & (sign + sign - 1); |
val = -val; |
|
else |
|
val = -val & ((1 << bits) - 1); |
|
neg = 1; |
neg = 1; |
} |
} |
} |
} |
Line 300 print_insn (struct disassemble_info *inf |
|
Line 299 print_insn (struct disassemble_info *inf |
|
{ |
{ |
if (oper->flags & OPERAND_SIGNED) |
if (oper->flags & OPERAND_SIGNED) |
{ |
{ |
int max = (1 << (bits - 1)); |
unsigned int sign = 1u << (bits - 1); |
|
|
if (val & max) |
if (val & sign) |
{ |
{ |
val = -val; |
val = -val & (sign + sign - 1); |
if (bits < 32) |
|
val &= ((1 << bits) - 1); |
|
(*info->fprintf_func) (info->stream, "-"); |
(*info->fprintf_func) (info->stream, "-"); |
} |
} |
} |
} |
(*info->fprintf_func) (info->stream, "0x%x", val); |
(*info->fprintf_func) (info->stream, "0x%x", val); |
} |
} |
/* If there is another operand, then write a comma and space. */ |
/* 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; |
need_comma = 1; |
} |
} |
if (need_paren) |
if (need_paren) |
Line 325 print_insn_d30v (bfd_vma memaddr, struct |
|
Line 324 print_insn_d30v (bfd_vma memaddr, struct |
|
{ |
{ |
int status, result; |
int status, result; |
bfd_byte buffer[12]; |
bfd_byte buffer[12]; |
unsigned long in1, in2; |
uint32_t in1, in2; |
struct d30v_insn insn; |
struct d30v_insn insn; |
long long num; |
uint64_t num; |
|
|
insn.form = NULL; |
insn.form = NULL; |
|
|
Line 348 print_insn_d30v (bfd_vma memaddr, struct |
|
Line 347 print_insn_d30v (bfd_vma memaddr, struct |
|
{ |
{ |
info->bytes_per_line = 8; |
info->bytes_per_line = 8; |
if (!(result = lookup_opcode (&insn, in1, 0))) |
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 |
else |
print_insn (info, memaddr, (long long) in1, &insn, 0, result); |
print_insn (info, memaddr, (uint64_t) in1, &insn, 0, result); |
return 4; |
return 4; |
} |
} |
in2 = bfd_getb32 (buffer); |
in2 = bfd_getb32 (buffer); |
Line 360 print_insn_d30v (bfd_vma memaddr, struct |
|
Line 359 print_insn_d30v (bfd_vma memaddr, struct |
|
/* LONG instruction. */ |
/* LONG instruction. */ |
if (!(result = lookup_opcode (&insn, in1, 1))) |
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; |
return 8; |
} |
} |
num = (long long) in1 << 32 | in2; |
num = (uint64_t) in1 << 32 | in2; |
print_insn (info, memaddr, num, &insn, 1, result); |
print_insn (info, memaddr, num, &insn, 1, result); |
} |
} |
else |
else |
{ |
{ |
num = in1; |
num = in1; |
if (!(result = lookup_opcode (&insn, in1, 0))) |
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 |
else |
print_insn (info, memaddr, num, &insn, 0, result); |
print_insn (info, memaddr, num, &insn, 0, result); |
|
|
Line 391 print_insn_d30v (bfd_vma memaddr, struct |
|
Line 390 print_insn_d30v (bfd_vma memaddr, struct |
|
insn.form = NULL; |
insn.form = NULL; |
num = in2; |
num = in2; |
if (!(result = lookup_opcode (&insn, in2, 0))) |
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 |
else |
print_insn (info, memaddr, num, &insn, 0, result); |
print_insn (info, memaddr, num, &insn, 0, result); |
} |
} |