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