ubsan: m32r: left shift of negative value
[deliverable/binutils-gdb.git] / opcodes / rx-dis.c
CommitLineData
c7927a3c 1/* Disassembler code for Renesas RX.
b3adc24a 2 Copyright (C) 2008-2020 Free Software Foundation, Inc.
c7927a3c
NC
3 Contributed by Red Hat.
4 Written by DJ Delorie.
5
6 This file is part of the GNU opcodes library.
7
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)
11 any later version.
12
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.
17
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. */
22
5eb3690e 23#include "sysdep.h"
c7927a3c
NC
24#include <stdio.h>
25
26#include "bfd.h"
27#include "dis-asm.h"
28#include "opcode/rx.h"
12234dfd
NC
29#include "libiberty.h"
30#include "opintl.h"
c7927a3c 31
029e9d52
YQ
32#include <setjmp.h>
33
c7927a3c
NC
34typedef struct
35{
36 bfd_vma pc;
37 disassemble_info * dis;
38} RX_Data;
39
029e9d52
YQ
40struct private
41{
42 OPCODES_SIGJMP_BUF bailout;
43};
44
c7927a3c
NC
45static int
46rx_get_byte (void * vdata)
47{
48 bfd_byte buf[1];
49 RX_Data *rx_data = (RX_Data *) vdata;
029e9d52 50 int status;
c7927a3c 51
029e9d52
YQ
52 status = rx_data->dis->read_memory_func (rx_data->pc,
53 buf,
54 1,
55 rx_data->dis);
56 if (status != 0)
57 {
58 struct private *priv = (struct private *) rx_data->dis->private_data;
59
60 rx_data->dis->memory_error_func (status, rx_data->pc,
61 rx_data->dis);
62 OPCODES_SIGLONGJMP (priv->bailout, 1);
63 }
c7927a3c
NC
64
65 rx_data->pc ++;
66 return buf[0];
67}
68
f04265ec 69static char const * size_names[RX_MAX_SIZE] =
c7927a3c 70{
4ce8c66d 71 "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l", "", "<error>"
c7927a3c
NC
72};
73
f04265ec 74static char const * opsize_names[RX_MAX_SIZE] =
c7927a3c 75{
4ce8c66d 76 "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l", ".d", "<error>"
c7927a3c
NC
77};
78
79static char const * register_names[] =
80{
12234dfd 81 /* General registers. */
c7927a3c
NC
82 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
12234dfd 84 /* Control registers. */
f04265ec 85 "psw", "pc", "usp", "fpsw", NULL, NULL, NULL, NULL,
a117b0a5
YS
86 "bpsw", "bpc", "isp", "fintv", "intb", "extb", NULL, NULL,
87 "a0", "a1", NULL, NULL, NULL, NULL, NULL, NULL,
f04265ec 88 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
c7927a3c
NC
89};
90
91static char const * condition_names[] =
92{
12234dfd 93 /* Condition codes. */
c7927a3c 94 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
e7286c56 95 "ge", "lt", "gt", "le", "o", "no", "<invalid>", "<invalid>"
c7927a3c
NC
96};
97
98static const char * flag_names[] =
99{
100 "c", "z", "s", "o", "", "", "", "",
101 "", "", "", "", "", "", "", "",
102 "i", "u", "", "", "", "", "", ""
103 "", "", "", "", "", "", "", "",
104};
105
4ce8c66d
YS
106static const char * double_register_names[] =
107{
108 "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7",
109 "dr8", "dr9", "dr10", "dr11", "dr12", "dr13", "dr14", "dr15",
110};
111
112static const char * double_register_high_names[] =
113{
114 "drh0", "drh1", "drh2", "drh3", "drh4", "drh5", "drh6", "drh7",
115 "drh8", "drh9", "drh10", "drh11", "drh12", "drh13", "drh14", "drh15",
116};
117
118static const char * double_register_low_names[] =
119{
120 "drl0", "drl1", "drl2", "drl3", "drl4", "drl5", "drl6", "drl7",
121 "drl8", "drl9", "drl10", "drl11", "drl12", "drl13", "drl14", "drl15",
122};
123
124static const char * double_control_register_names[] =
125{
126 "dpsw", "dcmr", "decnt", "depc",
127};
128
129static const char * double_condition_names[] =
130{
131 "", "un", "eq", "", "lt", "", "le",
132};
133
12234dfd
NC
134static inline const char *
135get_register_name (unsigned int reg)
136{
137 if (reg < ARRAY_SIZE (register_names))
138 return register_names[reg];
de6d8dc2 139 return _("<invalid register number>");
12234dfd
NC
140}
141
142static inline const char *
143get_condition_name (unsigned int cond)
144{
145 if (cond < ARRAY_SIZE (condition_names))
146 return condition_names[cond];
de6d8dc2 147 return _("<invalid condition code>");
12234dfd
NC
148}
149
150static inline const char *
151get_flag_name (unsigned int flag)
152{
153 if (flag < ARRAY_SIZE (flag_names))
154 return flag_names[flag];
de6d8dc2 155 return _("<invalid flag>");
12234dfd
NC
156}
157
158static inline const char *
159get_double_register_name (unsigned int reg)
160{
161 if (reg < ARRAY_SIZE (double_register_names))
162 return double_register_names[reg];
de6d8dc2 163 return _("<invalid register number>");
12234dfd
NC
164}
165
166static inline const char *
167get_double_register_high_name (unsigned int reg)
168{
169 if (reg < ARRAY_SIZE (double_register_high_names))
170 return double_register_high_names[reg];
de6d8dc2 171 return _("<invalid register number>");
12234dfd
NC
172}
173
174static inline const char *
175get_double_register_low_name (unsigned int reg)
176{
177 if (reg < ARRAY_SIZE (double_register_low_names))
178 return double_register_low_names[reg];
de6d8dc2 179 return _("<invalid register number>");
12234dfd
NC
180}
181
182static inline const char *
183get_double_control_register_name (unsigned int reg)
184{
185 if (reg < ARRAY_SIZE (double_control_register_names))
186 return double_control_register_names[reg];
de6d8dc2 187 return _("<invalid register number>");
12234dfd
NC
188}
189
190static inline const char *
191get_double_condition_name (unsigned int cond)
192{
193 if (cond < ARRAY_SIZE (double_condition_names))
194 return double_condition_names[cond];
de6d8dc2 195 return _("<invalid condition code>");
12234dfd
NC
196}
197
6207ed28
NC
198static inline const char *
199get_opsize_name (unsigned int opsize)
200{
201 if (opsize < ARRAY_SIZE (opsize_names))
202 return opsize_names[opsize];
de6d8dc2 203 return _("<invalid opsize>");
6207ed28
NC
204}
205
206static inline const char *
207get_size_name (unsigned int size)
208{
209 if (size < ARRAY_SIZE (size_names))
210 return size_names[size];
de6d8dc2 211 return _("<invalid size>");
6207ed28
NC
212}
213
12234dfd 214
c7927a3c
NC
215int
216print_insn_rx (bfd_vma addr, disassemble_info * dis)
217{
218 int rv;
219 RX_Data rx_data;
220 RX_Opcode_Decoded opcode;
221 const char * s;
029e9d52 222 struct private priv;
c7927a3c 223
029e9d52 224 dis->private_data = (PTR) &priv;
c7927a3c
NC
225 rx_data.pc = addr;
226 rx_data.dis = dis;
227
029e9d52
YQ
228 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
229 {
230 /* Error return. */
231 return -1;
232 }
233
c7927a3c
NC
234 rv = rx_decode_opcode (addr, &opcode, rx_get_byte, &rx_data);
235
236 dis->bytes_per_line = 10;
237
238#define PR (dis->fprintf_func)
239#define PS (dis->stream)
240#define PC(c) PR (PS, "%c", c)
241
f04265ec
NC
242 /* Detect illegal instructions. */
243 if (opcode.op[0].size == RX_Bad_Size
244 || register_names [opcode.op[0].reg] == NULL
245 || register_names [opcode.op[1].reg] == NULL
246 || register_names [opcode.op[2].reg] == NULL)
247 {
248 bfd_byte buf[10];
249 int i;
250
251 PR (PS, ".byte ");
252 rx_data.dis->read_memory_func (rx_data.pc - rv, buf, rv, rx_data.dis);
253
254 for (i = 0 ; i < rv; i++)
255 PR (PS, "0x%02x ", buf[i]);
256 return rv;
257 }
258
c7927a3c
NC
259 for (s = opcode.syntax; *s; s++)
260 {
261 if (*s != '%')
262 {
263 PC (*s);
264 }
265 else
266 {
267 RX_Opcode_Operand * oper;
268 int do_size = 0;
269 int do_hex = 0;
270 int do_addr = 0;
271
272 s ++;
273
274 if (*s == 'S')
275 {
276 do_size = 1;
277 s++;
278 }
279 if (*s == 'x')
280 {
281 do_hex = 1;
282 s++;
283 }
284 if (*s == 'a')
285 {
286 do_addr = 1;
287 s++;
288 }
289
290 switch (*s)
291 {
292 case '%':
293 PC ('%');
294 break;
295
296 case 's':
6207ed28 297 PR (PS, "%s", get_opsize_name (opcode.size));
c7927a3c
NC
298 break;
299
4ce8c66d
YS
300 case 'b':
301 s ++;
6207ed28
NC
302 if (*s == 'f')
303 {
304 int imm = opcode.op[2].addend;
305 int slsb, dlsb, width;
306
307 dlsb = (imm >> 5) & 0x1f;
308 slsb = (imm & 0x1f);
309 slsb = (slsb >= 0x10?(slsb ^ 0x1f) + 1:slsb);
310 slsb = dlsb - slsb;
311 slsb = (slsb < 0?-slsb:slsb);
312 width = ((imm >> 10) & 0x1f) - dlsb;
313 PR (PS, "#%d, #%d, #%d, %s, %s",
314 slsb, dlsb, width,
315 get_register_name (opcode.op[1].reg),
316 get_register_name (opcode.op[0].reg));
317 }
4ce8c66d 318 break;
c7927a3c
NC
319 case '0':
320 case '1':
321 case '2':
27cee81d 322 oper = opcode.op + (*s - '0');
c7927a3c
NC
323 if (do_size)
324 {
e292aa7a 325 if (oper->type == RX_Operand_Indirect || oper->type == RX_Operand_Zero_Indirect)
6207ed28 326 PR (PS, "%s", get_size_name (oper->size));
c7927a3c
NC
327 }
328 else
329 switch (oper->type)
330 {
331 case RX_Operand_Immediate:
332 if (do_addr)
333 dis->print_address_func (oper->addend, dis);
334 else if (do_hex
335 || oper->addend > 999
336 || oper->addend < -999)
337 PR (PS, "%#x", oper->addend);
338 else
339 PR (PS, "%d", oper->addend);
340 break;
341 case RX_Operand_Register:
90d6ff62 342 case RX_Operand_TwoReg:
12234dfd 343 PR (PS, "%s", get_register_name (oper->reg));
c7927a3c
NC
344 break;
345 case RX_Operand_Indirect:
12234dfd 346 PR (PS, "%d[%s]", oper->addend, get_register_name (oper->reg));
e292aa7a
NC
347 break;
348 case RX_Operand_Zero_Indirect:
12234dfd 349 PR (PS, "[%s]", get_register_name (oper->reg));
c7927a3c
NC
350 break;
351 case RX_Operand_Postinc:
12234dfd 352 PR (PS, "[%s+]", get_register_name (oper->reg));
c7927a3c
NC
353 break;
354 case RX_Operand_Predec:
12234dfd 355 PR (PS, "[-%s]", get_register_name (oper->reg));
c7927a3c
NC
356 break;
357 case RX_Operand_Condition:
12234dfd 358 PR (PS, "%s", get_condition_name (oper->reg));
c7927a3c
NC
359 break;
360 case RX_Operand_Flag:
12234dfd 361 PR (PS, "%s", get_flag_name (oper->reg));
c7927a3c 362 break;
4ce8c66d 363 case RX_Operand_DoubleReg:
12234dfd 364 PR (PS, "%s", get_double_register_name (oper->reg));
4ce8c66d
YS
365 break;
366 case RX_Operand_DoubleRegH:
12234dfd 367 PR (PS, "%s", get_double_register_high_name (oper->reg));
4ce8c66d
YS
368 break;
369 case RX_Operand_DoubleRegL:
12234dfd 370 PR (PS, "%s", get_double_register_low_name (oper->reg));
4ce8c66d
YS
371 break;
372 case RX_Operand_DoubleCReg:
12234dfd 373 PR (PS, "%s", get_double_control_register_name (oper->reg));
4ce8c66d
YS
374 break;
375 case RX_Operand_DoubleCond:
12234dfd 376 PR (PS, "%s", get_double_condition_name (oper->reg));
4ce8c66d 377 break;
c7927a3c
NC
378 default:
379 PR (PS, "[???]");
380 break;
381 }
382 }
383 }
384 }
385
386 return rv;
387}
This page took 0.506391 seconds and 4 git commands to generate.