[gdb/testsuite] Fix regexp for reg value in jit-reader.exp
[deliverable/binutils-gdb.git] / opcodes / rx-dis.c
1 /* Disassembler code for Renesas RX.
2 Copyright (C) 2008-2019 Free Software Foundation, Inc.
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
23 #include "sysdep.h"
24 #include <stdio.h>
25
26 #include "bfd.h"
27 #include "dis-asm.h"
28 #include "opcode/rx.h"
29 #include "libiberty.h"
30 #include "opintl.h"
31
32 #include <setjmp.h>
33
34 typedef struct
35 {
36 bfd_vma pc;
37 disassemble_info * dis;
38 } RX_Data;
39
40 struct private
41 {
42 OPCODES_SIGJMP_BUF bailout;
43 };
44
45 static int
46 rx_get_byte (void * vdata)
47 {
48 bfd_byte buf[1];
49 RX_Data *rx_data = (RX_Data *) vdata;
50 int status;
51
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 }
64
65 rx_data->pc ++;
66 return buf[0];
67 }
68
69 static char const * size_names[RX_MAX_SIZE] =
70 {
71 "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l", "", "<error>"
72 };
73
74 static char const * opsize_names[RX_MAX_SIZE] =
75 {
76 "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l", ".d", "<error>"
77 };
78
79 static char const * register_names[] =
80 {
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,
89 };
90
91 static char const * condition_names[] =
92 {
93 /* Condition codes. */
94 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
95 "ge", "lt", "gt", "le", "o", "no", "<invalid>", "<invalid>"
96 };
97
98 static const char * flag_names[] =
99 {
100 "c", "z", "s", "o", "", "", "", "",
101 "", "", "", "", "", "", "", "",
102 "i", "u", "", "", "", "", "", ""
103 "", "", "", "", "", "", "", "",
104 };
105
106 static 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
112 static 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
118 static 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
124 static const char * double_control_register_names[] =
125 {
126 "dpsw", "dcmr", "decnt", "depc",
127 };
128
129 static const char * double_condition_names[] =
130 {
131 "", "un", "eq", "", "lt", "", "le",
132 };
133
134 static inline const char *
135 get_register_name (unsigned int reg)
136 {
137 if (reg < ARRAY_SIZE (register_names))
138 return register_names[reg];
139 return _("<inavlid register number>");
140 }
141
142 static inline const char *
143 get_condition_name (unsigned int cond)
144 {
145 if (cond < ARRAY_SIZE (condition_names))
146 return condition_names[cond];
147 return _("<inavlid condition code>");
148 }
149
150 static inline const char *
151 get_flag_name (unsigned int flag)
152 {
153 if (flag < ARRAY_SIZE (flag_names))
154 return flag_names[flag];
155 return _("<inavlid flag>");
156 }
157
158 static inline const char *
159 get_double_register_name (unsigned int reg)
160 {
161 if (reg < ARRAY_SIZE (double_register_names))
162 return double_register_names[reg];
163 return _("<inavlid register number>");
164 }
165
166 static inline const char *
167 get_double_register_high_name (unsigned int reg)
168 {
169 if (reg < ARRAY_SIZE (double_register_high_names))
170 return double_register_high_names[reg];
171 return _("<inavlid register number>");
172 }
173
174 static inline const char *
175 get_double_register_low_name (unsigned int reg)
176 {
177 if (reg < ARRAY_SIZE (double_register_low_names))
178 return double_register_low_names[reg];
179 return _("<inavlid register number>");
180 }
181
182 static inline const char *
183 get_double_control_register_name (unsigned int reg)
184 {
185 if (reg < ARRAY_SIZE (double_control_register_names))
186 return double_control_register_names[reg];
187 return _("<inavlid register number>");
188 }
189
190 static inline const char *
191 get_double_condition_name (unsigned int cond)
192 {
193 if (cond < ARRAY_SIZE (double_condition_names))
194 return double_condition_names[cond];
195 return _("<inavlid condition code>");
196 }
197
198
199 int
200 print_insn_rx (bfd_vma addr, disassemble_info * dis)
201 {
202 int rv;
203 RX_Data rx_data;
204 RX_Opcode_Decoded opcode;
205 const char * s;
206 struct private priv;
207
208 dis->private_data = (PTR) &priv;
209 rx_data.pc = addr;
210 rx_data.dis = dis;
211
212 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
213 {
214 /* Error return. */
215 return -1;
216 }
217
218 rv = rx_decode_opcode (addr, &opcode, rx_get_byte, &rx_data);
219
220 dis->bytes_per_line = 10;
221
222 #define PR (dis->fprintf_func)
223 #define PS (dis->stream)
224 #define PC(c) PR (PS, "%c", c)
225
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)
231 {
232 bfd_byte buf[10];
233 int i;
234
235 PR (PS, ".byte ");
236 rx_data.dis->read_memory_func (rx_data.pc - rv, buf, rv, rx_data.dis);
237
238 for (i = 0 ; i < rv; i++)
239 PR (PS, "0x%02x ", buf[i]);
240 return rv;
241 }
242
243 for (s = opcode.syntax; *s; s++)
244 {
245 if (*s != '%')
246 {
247 PC (*s);
248 }
249 else
250 {
251 RX_Opcode_Operand * oper;
252 int do_size = 0;
253 int do_hex = 0;
254 int do_addr = 0;
255
256 s ++;
257
258 if (*s == 'S')
259 {
260 do_size = 1;
261 s++;
262 }
263 if (*s == 'x')
264 {
265 do_hex = 1;
266 s++;
267 }
268 if (*s == 'a')
269 {
270 do_addr = 1;
271 s++;
272 }
273
274 switch (*s)
275 {
276 case '%':
277 PC ('%');
278 break;
279
280 case 's':
281 PR (PS, "%s", opsize_names[opcode.size]);
282 break;
283
284 case 'b':
285 s ++;
286 if (*s == 'f') {
287 int imm = opcode.op[2].addend;
288 int slsb, dlsb, width;
289 dlsb = (imm >> 5) & 0x1f;
290 slsb = (imm & 0x1f);
291 slsb = (slsb >= 0x10?(slsb ^ 0x1f) + 1:slsb);
292 slsb = dlsb - slsb;
293 slsb = (slsb < 0?-slsb:slsb);
294 width = ((imm >> 10) & 0x1f) - dlsb;
295 PR (PS, "#%d, #%d, #%d, %s, %s",
296 slsb, dlsb, width,
297 register_names[opcode.op[1].reg],
298 register_names[opcode.op[0].reg]);
299 }
300 break;
301 case '0':
302 case '1':
303 case '2':
304 oper = opcode.op + *s - '0';
305 if (do_size)
306 {
307 if (oper->type == RX_Operand_Indirect || oper->type == RX_Operand_Zero_Indirect)
308 PR (PS, "%s", size_names[oper->size]);
309 }
310 else
311 switch (oper->type)
312 {
313 case RX_Operand_Immediate:
314 if (do_addr)
315 dis->print_address_func (oper->addend, dis);
316 else if (do_hex
317 || oper->addend > 999
318 || oper->addend < -999)
319 PR (PS, "%#x", oper->addend);
320 else
321 PR (PS, "%d", oper->addend);
322 break;
323 case RX_Operand_Register:
324 case RX_Operand_TwoReg:
325 PR (PS, "%s", get_register_name (oper->reg));
326 break;
327 case RX_Operand_Indirect:
328 PR (PS, "%d[%s]", oper->addend, get_register_name (oper->reg));
329 break;
330 case RX_Operand_Zero_Indirect:
331 PR (PS, "[%s]", get_register_name (oper->reg));
332 break;
333 case RX_Operand_Postinc:
334 PR (PS, "[%s+]", get_register_name (oper->reg));
335 break;
336 case RX_Operand_Predec:
337 PR (PS, "[-%s]", get_register_name (oper->reg));
338 break;
339 case RX_Operand_Condition:
340 PR (PS, "%s", get_condition_name (oper->reg));
341 break;
342 case RX_Operand_Flag:
343 PR (PS, "%s", get_flag_name (oper->reg));
344 break;
345 case RX_Operand_DoubleReg:
346 PR (PS, "%s", get_double_register_name (oper->reg));
347 break;
348 case RX_Operand_DoubleRegH:
349 PR (PS, "%s", get_double_register_high_name (oper->reg));
350 break;
351 case RX_Operand_DoubleRegL:
352 PR (PS, "%s", get_double_register_low_name (oper->reg));
353 break;
354 case RX_Operand_DoubleCReg:
355 PR (PS, "%s", get_double_control_register_name (oper->reg));
356 break;
357 case RX_Operand_DoubleCond:
358 PR (PS, "%s", get_double_condition_name (oper->reg));
359 break;
360 default:
361 PR (PS, "[???]");
362 break;
363 }
364 }
365 }
366 }
367
368 return rv;
369 }
This page took 0.037049 seconds and 4 git commands to generate.