btrace: async support
[deliverable/binutils-gdb.git] / opcodes / rx-dis.c
CommitLineData
c7927a3c 1/* Disassembler code for Renesas RX.
4b95cf5c 2 Copyright (C) 2008-2014 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"
29
30typedef struct
31{
32 bfd_vma pc;
33 disassemble_info * dis;
34} RX_Data;
35
36static int
37rx_get_byte (void * vdata)
38{
39 bfd_byte buf[1];
40 RX_Data *rx_data = (RX_Data *) vdata;
41
42 rx_data->dis->read_memory_func (rx_data->pc,
43 buf,
44 1,
45 rx_data->dis);
46
47 rx_data->pc ++;
48 return buf[0];
49}
50
51static char const * size_names[] =
52{
53 "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l"
54};
55
56static char const * opsize_names[] =
57{
58 "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l"
59};
60
61static char const * register_names[] =
62{
63 /* general registers */
64 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
65 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
66 /* control register */
0d734b5d 67 "psw", "pc", "usp", "fpsw", "", "", "", "wr",
c7927a3c
NC
68 "bpsw", "bpc", "isp", "fintv", "intb", "", "", "",
69 "pbp", "pben", "", "", "", "", "", "",
70 "bbpsw", "bbpc", "", "", "", "", "", ""
71};
72
73static char const * condition_names[] =
74{
75 /* condition codes */
76 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
77 "ge", "lt", "gt", "le", "o", "no", "always", "never"
78};
79
80static const char * flag_names[] =
81{
82 "c", "z", "s", "o", "", "", "", "",
83 "", "", "", "", "", "", "", "",
84 "i", "u", "", "", "", "", "", ""
85 "", "", "", "", "", "", "", "",
86};
87
88int
89print_insn_rx (bfd_vma addr, disassemble_info * dis)
90{
91 int rv;
92 RX_Data rx_data;
93 RX_Opcode_Decoded opcode;
94 const char * s;
95
96 rx_data.pc = addr;
97 rx_data.dis = dis;
98
99 rv = rx_decode_opcode (addr, &opcode, rx_get_byte, &rx_data);
100
101 dis->bytes_per_line = 10;
102
103#define PR (dis->fprintf_func)
104#define PS (dis->stream)
105#define PC(c) PR (PS, "%c", c)
106
107 for (s = opcode.syntax; *s; s++)
108 {
109 if (*s != '%')
110 {
111 PC (*s);
112 }
113 else
114 {
115 RX_Opcode_Operand * oper;
116 int do_size = 0;
117 int do_hex = 0;
118 int do_addr = 0;
119
120 s ++;
121
122 if (*s == 'S')
123 {
124 do_size = 1;
125 s++;
126 }
127 if (*s == 'x')
128 {
129 do_hex = 1;
130 s++;
131 }
132 if (*s == 'a')
133 {
134 do_addr = 1;
135 s++;
136 }
137
138 switch (*s)
139 {
140 case '%':
141 PC ('%');
142 break;
143
144 case 's':
145 PR (PS, "%s", opsize_names[opcode.size]);
146 break;
147
148 case '0':
149 case '1':
150 case '2':
151 oper = opcode.op + *s - '0';
152 if (do_size)
153 {
154 if (oper->type == RX_Operand_Indirect)
155 PR (PS, "%s", size_names[oper->size]);
156 }
157 else
158 switch (oper->type)
159 {
160 case RX_Operand_Immediate:
161 if (do_addr)
162 dis->print_address_func (oper->addend, dis);
163 else if (do_hex
164 || oper->addend > 999
165 || oper->addend < -999)
166 PR (PS, "%#x", oper->addend);
167 else
168 PR (PS, "%d", oper->addend);
169 break;
170 case RX_Operand_Register:
90d6ff62 171 case RX_Operand_TwoReg:
c7927a3c
NC
172 PR (PS, "%s", register_names[oper->reg]);
173 break;
174 case RX_Operand_Indirect:
175 if (oper->addend)
176 PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]);
177 else
178 PR (PS, "[%s]", register_names[oper->reg]);
179 break;
180 case RX_Operand_Postinc:
181 PR (PS, "[%s+]", register_names[oper->reg]);
182 break;
183 case RX_Operand_Predec:
184 PR (PS, "[-%s]", register_names[oper->reg]);
185 break;
186 case RX_Operand_Condition:
187 PR (PS, "%s", condition_names[oper->reg]);
188 break;
189 case RX_Operand_Flag:
190 PR (PS, "%s", flag_names[oper->reg]);
191 break;
192 default:
193 PR (PS, "[???]");
194 break;
195 }
196 }
197 }
198 }
199
200 return rv;
201}
This page took 0.249745 seconds and 4 git commands to generate.