* ppc-opc.c (powerpc_macros): Add entries for e_extlwi to e_clrlslwi.
[deliverable/binutils-gdb.git] / opcodes / i860-dis.c
CommitLineData
9d751335 1/* Disassembler for the i860.
aa820537 2 Copyright 2000, 2003, 2005, 2007 Free Software Foundation, Inc.
9d751335
JE
3
4 Contributed by Jason Eckhardt <jle@cygnus.com>.
5
9b201bb5 6 This file is part of the GNU opcodes library.
9d751335 7
9b201bb5
NC
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.
9d751335 12
9b201bb5
NC
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. */
9d751335
JE
22
23#include "dis-asm.h"
24#include "opcode/i860.h"
25
26/* Later we should probably choose the prefix based on which OS flavor. */
27#define I860_REG_PREFIX "%"
28
29/* Integer register names (encoded as 0..31 in the instruction). */
30static const char *const grnames[] =
31 {"r0", "r1", "sp", "fp", "r4", "r5", "r6", "r7",
32 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
34 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"};
35
36/* FP register names (encoded as 0..31 in the instruction). */
37static const char *const frnames[] =
38 {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
39 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
40 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
41 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
42
14218d5f
JE
43/* Control/status register names (encoded as 0..11 in the instruction).
44 Registers bear, ccr, p0, p1, p2 and p3 are XP only. */
9d751335 45static const char *const crnames[] =
14218d5f
JE
46 {"fir", "psr", "dirbase", "db", "fsr", "epsr", "bear", "ccr",
47 "p0", "p1", "p2", "p3", "--", "--", "--", "--" };
9d751335
JE
48
49
9d751335
JE
50
51/* True if opcode is xor, xorh, and, andh, or, orh, andnot, andnoth. */
52#define BITWISE_OP(op) ((op) == 0x30 || (op) == 0x31 \
53 || (op) == 0x34 || (op) == 0x35 \
54 || (op) == 0x38 || (op) == 0x39 \
55 || (op) == 0x3c || (op) == 0x3d \
56 || (op) == 0x33 || (op) == 0x37 \
57 || (op) == 0x3b || (op) == 0x3f)
58
59
60/* Sign extend N-bit number. */
61static int
7f8a68cd 62sign_ext (unsigned int x, int n)
9d751335
JE
63{
64 int t;
65 t = x >> (n - 1);
66 t = ((-t) << n) | x;
67 return t;
68}
69
70
71/* Print a PC-relative branch offset. VAL is the sign extended value
72 from the branch instruction. */
73static void
7f8a68cd 74print_br_address (disassemble_info *info, bfd_vma memaddr, long val)
9d751335
JE
75{
76
305d537e 77 long adj = (long)memaddr + 4 + (val << 2);
9d751335 78
0fd3a477 79 (*info->fprintf_func) (info->stream, "0x%08lx", adj);
9d751335
JE
80
81 /* Attempt to obtain a symbol for the target address. */
82
83 if (info->print_address_func && adj != 0)
84 {
85 (*info->fprintf_func) (info->stream, "\t// ");
86 (*info->print_address_func) (adj, info);
87 }
88}
89
90
91/* Print one instruction. */
92int
7f8a68cd 93print_insn_i860 (bfd_vma memaddr, disassemble_info *info)
9d751335
JE
94{
95 bfd_byte buff[4];
96 unsigned int insn, i;
97 int status;
98 const struct i860_opcode *opcode = 0;
99
100 status = (*info->read_memory_func) (memaddr, buff, sizeof (buff), info);
101 if (status != 0)
102 {
103 (*info->memory_error_func) (status, memaddr, info);
104 return -1;
105 }
106
107 /* Note that i860 instructions are always accessed as little endian
108 data, regardless of the endian mode of the i860. */
109 insn = bfd_getl32 (buff);
110
111 status = 0;
112 i = 0;
113 while (i860_opcodes[i].name != NULL)
114 {
115 opcode = &i860_opcodes[i];
116 if ((insn & opcode->match) == opcode->match
117 && (insn & opcode->lose) == 0)
118 {
119 status = 1;
120 break;
121 }
122 ++i;
123 }
124
125 if (status == 0)
126 {
127 /* Instruction not in opcode table. */
128 (*info->fprintf_func) (info->stream, ".long %#08x", insn);
129 }
130 else
131 {
132 const char *s;
133 int val;
134
b645cb17
JE
135 /* If this a flop (or a shrd) and its dual bit is set,
136 prefix with 'd.'. */
137 if (((insn & 0xfc000000) == 0x48000000
138 || (insn & 0xfc000000) == 0xb0000000)
139 && (insn & 0x200))
9d751335
JE
140 (*info->fprintf_func) (info->stream, "d.%s\t", opcode->name);
141 else
142 (*info->fprintf_func) (info->stream, "%s\t", opcode->name);
143
144 for (s = opcode->args; *s; s++)
145 {
146 switch (*s)
147 {
148 /* Integer register (src1). */
149 case '1':
150 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
151 grnames[(insn >> 11) & 0x1f]);
152 break;
153
154 /* Integer register (src2). */
155 case '2':
156 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
157 grnames[(insn >> 21) & 0x1f]);
158 break;
159
160 /* Integer destination register. */
161 case 'd':
162 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
163 grnames[(insn >> 16) & 0x1f]);
164 break;
165
166 /* Floating-point register (src1). */
167 case 'e':
168 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
169 frnames[(insn >> 11) & 0x1f]);
170 break;
171
172 /* Floating-point register (src2). */
173 case 'f':
174 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
175 frnames[(insn >> 21) & 0x1f]);
176 break;
177
178 /* Floating-point destination register. */
179 case 'g':
180 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
181 frnames[(insn >> 16) & 0x1f]);
182 break;
183
184 /* Control register. */
185 case 'c':
186 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
14218d5f 187 crnames[(insn >> 21) & 0xf]);
9d751335
JE
188 break;
189
190 /* 16-bit immediate (sign extend, except for bitwise ops). */
191 case 'i':
192 if (BITWISE_OP ((insn & 0xfc000000) >> 26))
193 (*info->fprintf_func) (info->stream, "0x%04x",
194 (unsigned int) (insn & 0xffff));
195 else
196 (*info->fprintf_func) (info->stream, "%d",
197 sign_ext ((insn & 0xffff), 16));
198 break;
199
200 /* 16-bit immediate, aligned (2^0, ld.b). */
201 case 'I':
202 (*info->fprintf_func) (info->stream, "%d",
203 sign_ext ((insn & 0xffff), 16));
204 break;
205
206 /* 16-bit immediate, aligned (2^1, ld.s). */
207 case 'J':
208 (*info->fprintf_func) (info->stream, "%d",
209 sign_ext ((insn & 0xfffe), 16));
210 break;
211
212 /* 16-bit immediate, aligned (2^2, ld.l, {p}fld.l, fst.l). */
213 case 'K':
214 (*info->fprintf_func) (info->stream, "%d",
215 sign_ext ((insn & 0xfffc), 16));
216 break;
217
218 /* 16-bit immediate, aligned (2^3, {p}fld.d, fst.d). */
219 case 'L':
220 (*info->fprintf_func) (info->stream, "%d",
221 sign_ext ((insn & 0xfff8), 16));
222 break;
223
224 /* 16-bit immediate, aligned (2^4, {p}fld.q, fst.q). */
225 case 'M':
226 (*info->fprintf_func) (info->stream, "%d",
227 sign_ext ((insn & 0xfff0), 16));
228 break;
229
230 /* 5-bit immediate (zero extend). */
231 case '5':
232 (*info->fprintf_func) (info->stream, "%d",
233 ((insn >> 11) & 0x1f));
234 break;
235
236 /* Split 16 bit immediate (20..16:10..0). */
237 case 's':
238 val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);
239 (*info->fprintf_func) (info->stream, "%d",
240 sign_ext (val, 16));
241 break;
242
243 /* Split 16 bit immediate, aligned. (2^0, st.b). */
244 case 'S':
245 val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);
246 (*info->fprintf_func) (info->stream, "%d",
247 sign_ext (val, 16));
248 break;
249
250 /* Split 16 bit immediate, aligned. (2^1, st.s). */
251 case 'T':
252 val = ((insn >> 5) & 0xf800) | (insn & 0x07fe);
253 (*info->fprintf_func) (info->stream, "%d",
254 sign_ext (val, 16));
255 break;
256
257 /* Split 16 bit immediate, aligned. (2^2, st.l). */
258 case 'U':
259 val = ((insn >> 5) & 0xf800) | (insn & 0x07fc);
260 (*info->fprintf_func) (info->stream, "%d",
261 sign_ext (val, 16));
262 break;
263
264 /* 26-bit PC relative immediate (lbroff). */
265 case 'l':
266 val = sign_ext ((insn & 0x03ffffff), 26);
267 print_br_address (info, memaddr, val);
268 break;
269
270 /* 16-bit PC relative immediate (sbroff). */
271 case 'r':
272 val = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
273 print_br_address (info, memaddr, val);
274 break;
275
276 default:
277 (*info->fprintf_func) (info->stream, "%c", *s);
278 break;
279 }
280 }
281 }
282
283 return sizeof (insn);
284}
285
This page took 0.581882 seconds and 4 git commands to generate.