/* Disassemble D10V instructions.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <stdio.h>
+#include "sysdep.h"
#include "opcode/d10v.h"
#include "dis-asm.h"
/* the PC wraps at 18 bits, except for the segment number */
/* so use this mask to keep the parts we want */
-#define PC_MASK 0x03003FFF
+#define PC_MASK 0x0303FFFF
static void dis_2_short PARAMS ((unsigned long insn, bfd_vma memaddr,
struct disassemble_info *info, int order));
{
int i;
int match=0;
- num += oper->flags & (OPERAND_ACC|OPERAND_FLAG|OPERAND_CONTROL);
- for (i=0;i<reg_name_cnt();i++)
+ num += (oper->flags
+ & (OPERAND_GPR|OPERAND_FFLAG|OPERAND_CFLAG|OPERAND_CONTROL));
+ if (oper->flags & (OPERAND_ACC0|OPERAND_ACC1))
+ num += num ? OPERAND_ACC1 : OPERAND_ACC0;
+ for (i = 0; i < d10v_reg_name_cnt(); i++)
{
- if (num == pre_defined_registers[i].value)
+ if (num == d10v_predefined_registers[i].value)
{
- if (pre_defined_registers[i].pname)
- (*info->fprintf_func) (info->stream, "%s",pre_defined_registers[i].pname);
+ if (d10v_predefined_registers[i].pname)
+ (*info->fprintf_func) (info->stream, "%s",d10v_predefined_registers[i].pname);
else
- (*info->fprintf_func) (info->stream, "%s",pre_defined_registers[i].name);
+ (*info->fprintf_func) (info->stream, "%s",d10v_predefined_registers[i].name);
match=1;
break;
}
}
- if (match==0)
+ if (match == 0)
{
/* this would only get executed if a register was not in the
register table */
- if (oper->flags & OPERAND_ACC)
+ if (oper->flags & (OPERAND_ACC0|OPERAND_ACC1))
(*info->fprintf_func) (info->stream, "a");
else if (oper->flags & OPERAND_CONTROL)
(*info->fprintf_func) (info->stream, "cr");
neg = 1;
}
num = num<<2;
- if (neg)
- (*info->print_address_func) ((memaddr - num) & PC_MASK, info);
+ if (info->flags & INSN_HAS_RELOC)
+ (*info->print_address_func) (num & PC_MASK, info);
else
- (*info->print_address_func) ((memaddr + num) & PC_MASK, info);
+ {
+ if (neg)
+ (*info->print_address_func) ((memaddr - num) & PC_MASK, info);
+ else
+ (*info->print_address_func) ((memaddr + num) & PC_MASK, info);
+ }
}
else
{