]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/xgate-dis.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / opcodes / xgate-dis.c
CommitLineData
f6c1a2d5 1/* xgate-dis.c -- Freescale XGATE disassembly
b3adc24a 2 Copyright (C) 2009-2020 Free Software Foundation, Inc.
f6c1a2d5
NC
3 Written by Sean Keys (skeys@ipdatasys.com)
4
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
df7b86aa 20 MA 02110-1301, USA. */
f6c1a2d5 21
f6c1a2d5 22#include "sysdep.h"
df7b86aa 23#include <assert.h>
88c1242d 24#include "disassemble.h"
f6c1a2d5
NC
25#include "opintl.h"
26#include "libiberty.h"
27#include "ansidecl.h"
28#include "opcode/xgate.h"
29
30#define XGATE_TWO_BYTES 0x02
31#define XGATE_NINE_BITS 0x1FF
32#define XGATE_TEN_BITS 0x3FF
33#define XGATE_NINE_SIGNBIT 0x100
34#define XGATE_TEN_SIGNBIT 0x200
35
df7b86aa
NC
36/* Structures. */
37struct decodeInfo
38{
f6c1a2d5
NC
39 unsigned int operMask;
40 unsigned int operMasksRegisterBits;
41 struct xgate_opcode *opcodePTR;
42};
43
44/* Prototypes for local functions. */
df7b86aa
NC
45static int print_insn (bfd_vma, struct disassemble_info *);
46static int read_memory (bfd_vma, bfd_byte*, int, struct disassemble_info *);
47static int ripBits (unsigned int *, int,
48 struct xgate_opcode *, unsigned int);
49static int macro_search (char *, char *);
50static struct decodeInfo * find_match (unsigned int);
f6c1a2d5 51
df7b86aa 52/* Statics. */
f6c1a2d5
NC
53static struct decodeInfo *decodeTable;
54static int initialized;
55static char previousOpName[10];
56static unsigned int perviousBin;
57
58/* Disassemble one instruction at address 'memaddr'. Returns the number
df7b86aa
NC
59 of bytes used by that instruction. */
60
f6c1a2d5
NC
61static int
62print_insn (bfd_vma memaddr, struct disassemble_info* info)
63{
64 int status;
65 unsigned int raw_code;
66 char *s = 0;
67 long bytesRead = 0;
68 int i = 0;
69 struct xgate_opcode *opcodePTR = (struct xgate_opcode*) xgate_opcodes;
70 struct decodeInfo *decodeTablePTR = 0;
71 struct decodeInfo *decodePTR = 0;
72 unsigned int operandRegisterBits = 0;
73 signed int relAddr = 0;
74 signed int operandOne = 0;
75 signed int operandTwo = 0;
76 bfd_byte buffer[4];
77 bfd_vma absAddress;
78
79 unsigned int operMaskReg = 0;
df7b86aa
NC
80 /* Initialize our array of opcode masks and check them against our constant
81 table. */
f6c1a2d5
NC
82 if (!initialized)
83 {
df7b86aa 84 decodeTable = xmalloc (sizeof (struct decodeInfo) * xgate_num_opcodes);
f6c1a2d5
NC
85 for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
86 i++, decodeTablePTR++, opcodePTR++)
87 {
88 unsigned int bin = 0;
89 unsigned int mask = 0;
90 for (s = opcodePTR->format; *s; s++)
91 {
92 bin <<= 1;
93 mask <<= 1;
94 operandRegisterBits <<= 1;
95 bin |= (*s == '1');
96 mask |= (*s == '0' || *s == '1');
97 operandRegisterBits |= (*s == 'r');
98 }
df7b86aa
NC
99 /* Asserting will uncover inconsistencies in our table. */
100 assert ((s - opcodePTR->format) == 16 || (s - opcodePTR->format) == 32);
101 assert (opcodePTR->bin_opcode == bin);
102
f6c1a2d5
NC
103 decodeTablePTR->operMask = mask;
104 decodeTablePTR->operMasksRegisterBits = operandRegisterBits;
105 decodeTablePTR->opcodePTR = opcodePTR;
106 }
107 initialized = 1;
108 }
df7b86aa
NC
109
110 /* Read 16 bits. */
f6c1a2d5 111 bytesRead += XGATE_TWO_BYTES;
df7b86aa 112 status = read_memory (memaddr, buffer, XGATE_TWO_BYTES, info);
f6c1a2d5
NC
113 if (status == 0)
114 {
115 raw_code = buffer[0];
116 raw_code <<= 8;
117 raw_code += buffer[1];
118
df7b86aa 119 decodePTR = find_match (raw_code);
f6c1a2d5
NC
120 if (decodePTR)
121 {
122 operMaskReg = decodePTR->operMasksRegisterBits;
123 (*info->fprintf_func)(info->stream, "%s", decodePTR->opcodePTR->name);
df7b86aa 124
f6c1a2d5 125 /* First we compare the shorthand format of the constraints. If we
0e1c2434
SK
126 still are unable to pinpoint the operands
127 we analyze the opcodes constraint string. */
128 if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_R_C))
129 {
130 (*info->fprintf_func)(info->stream, " R%x, CCR",
131 (raw_code >> 8) & 0x7);
132 }
133 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_C_R))
134 {
135 (*info->fprintf_func)(info->stream, " CCR, R%x",
136 (raw_code >> 8) & 0x7);
137 }
138 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON_R_P))
139 {
140 (*info->fprintf_func)(info->stream, " R%x, PC",
141 (raw_code >> 8) & 0x7);
142 }
143 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_TRI))
144 {
145 (*info->fprintf_func)(info->stream, " R%x, R%x, R%x",
146 (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
147 (raw_code >> 2) & 0x7);
148 }
149 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IDR))
150 {
151 if (raw_code & 0x01)
152 {
153 (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x+)",
154 (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
155 (raw_code >> 2) & 0x7);
156 }
157 else if (raw_code & 0x02)
158 {
159 (*info->fprintf_func)(info->stream, " R%x, (R%x, -R%x)",
160 (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
161 (raw_code >> 2) & 0x7);
162 }
163 else
164 {
165 (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x)",
166 (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
167 (raw_code >> 2) & 0x7);
168 }
169 }
170 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_DYA))
171 {
dee33451
NC
172 operandOne = ripBits (&operMaskReg, 3, decodePTR->opcodePTR, raw_code);
173 operandTwo = ripBits (&operMaskReg, 3, decodePTR->opcodePTR, raw_code);
0e1c2434
SK
174 ( *info->fprintf_func)(info->stream, " R%x, R%x", operandOne,
175 operandTwo);
176 }
177 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IDO5))
178 {
179 (*info->fprintf_func)(info->stream, " R%x, (R%x, #0x%x)",
180 (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, raw_code & 0x1f);
181 }
182 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_MON))
183 {
184 operandOne = ripBits (&operMaskReg, 3, decodePTR->opcodePTR,
185 raw_code);
186 (*info->fprintf_func)(info->stream, " R%x", operandOne);
187 }
188 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_REL9))
f6c1a2d5 189 {
df7b86aa 190 /* If address is negative handle it accordingly. */
f6c1a2d5
NC
191 if (raw_code & XGATE_NINE_SIGNBIT)
192 {
df7b86aa
NC
193 relAddr = XGATE_NINE_BITS >> 1; /* Clip sign bit. */
194 relAddr = ~relAddr; /* Make signed. */
195 relAddr |= (raw_code & 0xFF) + 1; /* Apply our value. */
7ef412cf 196 relAddr *= 2; /* Multiply by two as per processor docs. */
f6c1a2d5
NC
197 }
198 else
199 {
200 relAddr = raw_code & 0xff;
7ef412cf 201 relAddr = relAddr * 2 + 2;
f6c1a2d5 202 }
0e1c2434
SK
203 (*info->fprintf_func)(info->stream, " *%d", relAddr);
204 (*info->fprintf_func)(info->stream, " Abs* 0x");
205 (*info->print_address_func)(memaddr + relAddr, info);
206 }
df7b86aa 207 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_REL10))
f6c1a2d5 208 {
df7b86aa 209 /* If address is negative handle it accordingly. */
f6c1a2d5
NC
210 if (raw_code & XGATE_TEN_SIGNBIT)
211 {
df7b86aa
NC
212 relAddr = XGATE_TEN_BITS >> 1; /* Clip sign bit. */
213 relAddr = ~relAddr; /* Make signed. */
214 relAddr |= (raw_code & 0x1FF) + 1; /* Apply our value. */
7ef412cf 215 relAddr *= 2; /* Multiply by two as per processor docs. */
f6c1a2d5
NC
216 }
217 else
218 {
219 relAddr = raw_code & 0x1FF;
7ef412cf 220 relAddr = relAddr * 2 + 2;
f6c1a2d5
NC
221 }
222 (*info->fprintf_func)(info->stream, " *%d", relAddr);
223 (*info->fprintf_func)(info->stream, " Abs* 0x");
224 (*info->print_address_func)(memaddr + relAddr, info);
225 }
0e1c2434
SK
226 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM4))
227 {
228 (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
229 (raw_code >> 8) & 0x7, (raw_code >> 4) & 0xF);
230 }
231 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM8))
232 {
233 if (macro_search (decodePTR->opcodePTR->name, previousOpName) &&
234 previousOpName[0])
235 {
236 absAddress = (0xFF & raw_code) << 8;
237 absAddress |= perviousBin & 0xFF;
238 (*info->fprintf_func)(info->stream, " R%x, #0x%02x Abs* 0x",
239 (raw_code >> 8) & 0x7, raw_code & 0xff);
240 (*info->print_address_func)(absAddress, info);
241 previousOpName[0] = 0;
242 }
243 else
244 {
245 strcpy (previousOpName, decodePTR->opcodePTR->name);
246 (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
247 (raw_code >> 8) & 0x7, raw_code & 0xff);
248 }
249 }
250 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_IMM3))
251 {
252 (*info->fprintf_func)(info->stream, " #0x%x",
253 (raw_code >> 8) & 0x7);
254 }
255 else if (!strcmp (decodePTR->opcodePTR->constraints, XGATE_OP_INH))
256 {
257 //
258 }
f6c1a2d5
NC
259 else
260 {
0e1c2434 261 (*info->fprintf_func)(info->stream, " unhandled mode %s",
dee33451 262 decodePTR->opcodePTR->constraints);
f6c1a2d5 263 }
f6c1a2d5
NC
264 perviousBin = raw_code;
265 }
266 else
267 {
268 (*info->fprintf_func)(info->stream,
df7b86aa 269 " unable to find opcode match #0%x", raw_code);
f6c1a2d5
NC
270 }
271 }
272 return bytesRead;
273}
274
275int
276print_insn_xgate (bfd_vma memaddr, struct disassemble_info* info)
277{
278 return print_insn (memaddr, info);
279}
280
281static int
282read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
283 struct disassemble_info* info)
284{
285 int status;
286 status = (*info->read_memory_func) (memaddr, buffer, size, info);
287 if (status != 0)
288 {
289 (*info->memory_error_func) (status, memaddr, info);
290 return -1;
291 }
292 return 0;
293}
294
295static int
df7b86aa
NC
296ripBits (unsigned int *operandBitsRemaining,
297 int numBitsRequested,
298 struct xgate_opcode *opcodePTR,
299 unsigned int memory)
f6c1a2d5
NC
300{
301 unsigned int currentBit;
7ef412cf 302 unsigned int operand = 0;
f6c1a2d5 303 int numBitsFound;
df7b86aa 304
7ef412cf
AM
305 for (numBitsFound = 0, currentBit = 1u << ((opcodePTR->size * 8) - 1);
306 numBitsFound < numBitsRequested && currentBit != 0;
307 currentBit >>= 1)
f6c1a2d5 308 {
df7b86aa
NC
309 if (currentBit & *operandBitsRemaining)
310 {
311 *operandBitsRemaining &= ~(currentBit); /* Consume the current bit. */
312 operand <<= 1; /* Make room for our next bit. */
313 numBitsFound++;
314 operand |= (currentBit & memory) > 0;
315 }
316 }
f6c1a2d5
NC
317 return operand;
318}
319
df7b86aa
NC
320static int
321macro_search (char *currentName, char *lastName)
f6c1a2d5
NC
322{
323 int i;
324 int length = 0;
325 char *where;
df7b86aa 326
f6c1a2d5
NC
327 for (i = 0; i < xgate_num_opcodes; i++)
328 {
df7b86aa
NC
329 where = strstr (xgate_opcodes[i].constraints, lastName);
330
f6c1a2d5
NC
331 if (where)
332 {
df7b86aa 333 length = strlen (where);
f6c1a2d5
NC
334 }
335 if (length)
336 {
df7b86aa 337 where = strstr (xgate_opcodes[i].constraints, currentName);
f6c1a2d5
NC
338 if (where)
339 {
df7b86aa 340 length = strlen (where);
f6c1a2d5
NC
341 return 1;
342 }
343 }
344 }
345 return 0;
346}
347
df7b86aa
NC
348static struct decodeInfo *
349find_match (unsigned int raw_code)
f6c1a2d5
NC
350{
351 struct decodeInfo *decodeTablePTR = 0;
352 int i;
353
354 for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
355 i++, decodeTablePTR++)
356 {
357 if ((raw_code & decodeTablePTR->operMask)
358 == decodeTablePTR->opcodePTR->bin_opcode)
359 {
df7b86aa 360 /* Make sure we didn't run into a macro or alias. */
f6c1a2d5
NC
361 if (decodeTablePTR->opcodePTR->cycles_min != 0)
362 {
363 return decodeTablePTR;
364 break;
365 }
366 else
df7b86aa 367 continue;
f6c1a2d5
NC
368 }
369 }
370 return 0;
371}