1 /* Disassemble D10V instructions.
2 Copyright (C) 1996 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "opcode/d10v.h"
24 static void dis_2_short PARAMS ((unsigned long insn, char *str, int order));
25 static void dis_long PARAMS ((unsigned long insn, char *str));
28 print_insn_d10v (memaddr, info)
30 struct disassemble_info *info;
37 strcpy (str, "unknown");
39 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
42 (*info->memory_error_func) (status, memaddr, info);
45 insn = bfd_getb32 (buffer);
50 dis_2_short (insn, str, 2);
53 dis_2_short (insn, str, 0);
56 dis_2_short (insn, str, 1);
62 (*info->fprintf_func) (info->stream, "\t%s", str, insn);
67 print_operand (buf, oper, insn, op)
69 struct d10v_operand *oper;
71 struct d10v_opcode *op;
75 if (oper->flags == OPERAND_ATMINUS)
80 if (oper->flags == OPERAND_MINUS)
85 if (oper->flags == OPERAND_PLUS)
90 if (oper->flags == OPERAND_ATSIGN)
95 if (oper->flags == OPERAND_ATPAR)
103 /* the LONG_L format shifts registers over by 15 */
104 if (op->format == LONG_L && (oper->flags & OPERAND_REG))
107 num = (insn >> shift) & (0x7FFFFFFF >> (31 - oper->bits));
109 if (oper->flags & OPERAND_ACC)
111 else if (oper->flags & OPERAND_CONTROL)
116 else if(oper->flags & OPERAND_REG)
119 if (oper->flags & OPERAND_REG)
120 sprintf (buf, "%d", num);
122 sprintf (buf, "0x%x", num);
133 struct d10v_opcode *op = (struct d10v_opcode *)d10v_opcodes;
134 struct d10v_operand *oper;
139 if ((op->format & LONG_OPCODE) && ((op->mask & insn) == op->opcode))
141 strcpy (str, op->name);
143 for ( i=0; op->operands[i]; i++)
145 oper = (struct d10v_operand *)&d10v_operands[op->operands[i]];
146 if (oper->flags == OPERAND_ATPAR)
148 print_operand (buf, oper, insn, op);
150 if (op->operands[i+1] && oper->bits &&
151 d10v_operands[op->operands[i+1]].flags != OPERAND_PLUS &&
152 d10v_operands[op->operands[i+1]].flags != OPERAND_MINUS)
164 dis_2_short (insn, str, order)
172 struct d10v_opcode *op;
174 int match, num_match=0;
175 struct d10v_operand *oper;
178 ins[0] = (insn & 0x3FFFFFFF) >> 15;
179 ins[1] = insn & 0x00007FFF;
185 op = (struct d10v_opcode *)d10v_opcodes;
189 if ((op->format & SHORT_OPCODE) && ((op->mask & ins[j]) == op->opcode))
191 strcat (str, op->name);
193 for (i=0; op->operands[i]; i++)
195 oper = (struct d10v_operand *)&d10v_operands[op->operands[i]];
196 if (oper->flags == OPERAND_ATPAR)
198 print_operand (buf, oper, ins[j], op);
200 if (op->operands[i+1] && oper->bits &&
201 d10v_operands[op->operands[i+1]].flags != OPERAND_PLUS &&
202 d10v_operands[op->operands[i+1]].flags != OPERAND_MINUS)
212 strcat (str, "unknown");
217 strcat ( str, "\t->\t");
221 strcat (str, "\t<-\t");
225 strcat (str, "\t||\t");
234 sprintf (str, ".long\t0x%08x", insn);