1 /* Disassembler code for Renesas RX.
2 Copyright (C) 2008-2019 Free Software Foundation, Inc.
3 Contributed by Red Hat.
6 This file is part of the GNU opcodes library.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
28 #include "opcode/rx.h"
29 #include "libiberty.h"
37 disassemble_info
* dis
;
42 OPCODES_SIGJMP_BUF bailout
;
46 rx_get_byte (void * vdata
)
49 RX_Data
*rx_data
= (RX_Data
*) vdata
;
52 status
= rx_data
->dis
->read_memory_func (rx_data
->pc
,
58 struct private *priv
= (struct private *) rx_data
->dis
->private_data
;
60 rx_data
->dis
->memory_error_func (status
, rx_data
->pc
,
62 OPCODES_SIGLONGJMP (priv
->bailout
, 1);
69 static char const * size_names
[RX_MAX_SIZE
] =
71 "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l", "", "<error>"
74 static char const * opsize_names
[RX_MAX_SIZE
] =
76 "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l", ".d", "<error>"
79 static char const * register_names
[] =
81 /* General registers. */
82 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
84 /* Control registers. */
85 "psw", "pc", "usp", "fpsw", NULL
, NULL
, NULL
, NULL
,
86 "bpsw", "bpc", "isp", "fintv", "intb", "extb", NULL
, NULL
,
87 "a0", "a1", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
88 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
91 static char const * condition_names
[] =
93 /* Condition codes. */
94 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
95 "ge", "lt", "gt", "le", "o", "no", "<invalid>", "<invalid>"
98 static const char * flag_names
[] =
100 "c", "z", "s", "o", "", "", "", "",
101 "", "", "", "", "", "", "", "",
102 "i", "u", "", "", "", "", "", ""
103 "", "", "", "", "", "", "", "",
106 static const char * double_register_names
[] =
108 "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7",
109 "dr8", "dr9", "dr10", "dr11", "dr12", "dr13", "dr14", "dr15",
112 static const char * double_register_high_names
[] =
114 "drh0", "drh1", "drh2", "drh3", "drh4", "drh5", "drh6", "drh7",
115 "drh8", "drh9", "drh10", "drh11", "drh12", "drh13", "drh14", "drh15",
118 static const char * double_register_low_names
[] =
120 "drl0", "drl1", "drl2", "drl3", "drl4", "drl5", "drl6", "drl7",
121 "drl8", "drl9", "drl10", "drl11", "drl12", "drl13", "drl14", "drl15",
124 static const char * double_control_register_names
[] =
126 "dpsw", "dcmr", "decnt", "depc",
129 static const char * double_condition_names
[] =
131 "", "un", "eq", "", "lt", "", "le",
134 static inline const char *
135 get_register_name (unsigned int reg
)
137 if (reg
< ARRAY_SIZE (register_names
))
138 return register_names
[reg
];
139 return _("<inavlid register number>");
142 static inline const char *
143 get_condition_name (unsigned int cond
)
145 if (cond
< ARRAY_SIZE (condition_names
))
146 return condition_names
[cond
];
147 return _("<inavlid condition code>");
150 static inline const char *
151 get_flag_name (unsigned int flag
)
153 if (flag
< ARRAY_SIZE (flag_names
))
154 return flag_names
[flag
];
155 return _("<inavlid flag>");
158 static inline const char *
159 get_double_register_name (unsigned int reg
)
161 if (reg
< ARRAY_SIZE (double_register_names
))
162 return double_register_names
[reg
];
163 return _("<inavlid register number>");
166 static inline const char *
167 get_double_register_high_name (unsigned int reg
)
169 if (reg
< ARRAY_SIZE (double_register_high_names
))
170 return double_register_high_names
[reg
];
171 return _("<inavlid register number>");
174 static inline const char *
175 get_double_register_low_name (unsigned int reg
)
177 if (reg
< ARRAY_SIZE (double_register_low_names
))
178 return double_register_low_names
[reg
];
179 return _("<inavlid register number>");
182 static inline const char *
183 get_double_control_register_name (unsigned int reg
)
185 if (reg
< ARRAY_SIZE (double_control_register_names
))
186 return double_control_register_names
[reg
];
187 return _("<inavlid register number>");
190 static inline const char *
191 get_double_condition_name (unsigned int cond
)
193 if (cond
< ARRAY_SIZE (double_condition_names
))
194 return double_condition_names
[cond
];
195 return _("<inavlid condition code>");
200 print_insn_rx (bfd_vma addr
, disassemble_info
* dis
)
204 RX_Opcode_Decoded opcode
;
208 dis
->private_data
= (PTR
) &priv
;
212 if (OPCODES_SIGSETJMP (priv
.bailout
) != 0)
218 rv
= rx_decode_opcode (addr
, &opcode
, rx_get_byte
, &rx_data
);
220 dis
->bytes_per_line
= 10;
222 #define PR (dis->fprintf_func)
223 #define PS (dis->stream)
224 #define PC(c) PR (PS, "%c", c)
226 /* Detect illegal instructions. */
227 if (opcode
.op
[0].size
== RX_Bad_Size
228 || register_names
[opcode
.op
[0].reg
] == NULL
229 || register_names
[opcode
.op
[1].reg
] == NULL
230 || register_names
[opcode
.op
[2].reg
] == NULL
)
236 rx_data
.dis
->read_memory_func (rx_data
.pc
- rv
, buf
, rv
, rx_data
.dis
);
238 for (i
= 0 ; i
< rv
; i
++)
239 PR (PS
, "0x%02x ", buf
[i
]);
243 for (s
= opcode
.syntax
; *s
; s
++)
251 RX_Opcode_Operand
* oper
;
281 PR (PS
, "%s", opsize_names
[opcode
.size
]);
287 int imm
= opcode
.op
[2].addend
;
288 int slsb
, dlsb
, width
;
289 dlsb
= (imm
>> 5) & 0x1f;
291 slsb
= (slsb
>= 0x10?(slsb
^ 0x1f) + 1:slsb
);
293 slsb
= (slsb
< 0?-slsb
:slsb
);
294 width
= ((imm
>> 10) & 0x1f) - dlsb
;
295 PR (PS
, "#%d, #%d, #%d, %s, %s",
297 register_names
[opcode
.op
[1].reg
],
298 register_names
[opcode
.op
[0].reg
]);
304 oper
= opcode
.op
+ *s
- '0';
307 if (oper
->type
== RX_Operand_Indirect
|| oper
->type
== RX_Operand_Zero_Indirect
)
308 PR (PS
, "%s", size_names
[oper
->size
]);
313 case RX_Operand_Immediate
:
315 dis
->print_address_func (oper
->addend
, dis
);
317 || oper
->addend
> 999
318 || oper
->addend
< -999)
319 PR (PS
, "%#x", oper
->addend
);
321 PR (PS
, "%d", oper
->addend
);
323 case RX_Operand_Register
:
324 case RX_Operand_TwoReg
:
325 PR (PS
, "%s", get_register_name (oper
->reg
));
327 case RX_Operand_Indirect
:
328 PR (PS
, "%d[%s]", oper
->addend
, get_register_name (oper
->reg
));
330 case RX_Operand_Zero_Indirect
:
331 PR (PS
, "[%s]", get_register_name (oper
->reg
));
333 case RX_Operand_Postinc
:
334 PR (PS
, "[%s+]", get_register_name (oper
->reg
));
336 case RX_Operand_Predec
:
337 PR (PS
, "[-%s]", get_register_name (oper
->reg
));
339 case RX_Operand_Condition
:
340 PR (PS
, "%s", get_condition_name (oper
->reg
));
342 case RX_Operand_Flag
:
343 PR (PS
, "%s", get_flag_name (oper
->reg
));
345 case RX_Operand_DoubleReg
:
346 PR (PS
, "%s", get_double_register_name (oper
->reg
));
348 case RX_Operand_DoubleRegH
:
349 PR (PS
, "%s", get_double_register_high_name (oper
->reg
));
351 case RX_Operand_DoubleRegL
:
352 PR (PS
, "%s", get_double_register_low_name (oper
->reg
));
354 case RX_Operand_DoubleCReg
:
355 PR (PS
, "%s", get_double_control_register_name (oper
->reg
));
357 case RX_Operand_DoubleCond
:
358 PR (PS
, "%s", get_double_condition_name (oper
->reg
));