1 /* xgate-dis.c -- Freescale XGATE disassembly
2 Copyright (C) 2009-2021 Free Software Foundation, Inc.
3 Written by Sean Keys (skeys@ipdatasys.com)
5 This file is part of the GNU opcodes library.
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)
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.
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,
20 MA 02110-1301, USA. */
24 #include "disassemble.h"
26 #include "libiberty.h"
28 #include "opcode/xgate.h"
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
39 unsigned int operMask
;
40 unsigned int operMasksRegisterBits
;
41 struct xgate_opcode
*opcodePTR
;
44 /* Prototypes for local functions. */
45 static int print_insn (bfd_vma
, struct disassemble_info
*);
46 static int read_memory (bfd_vma
, bfd_byte
*, int, struct disassemble_info
*);
47 static int ripBits (unsigned int *, int,
48 struct xgate_opcode
*, unsigned int);
49 static int macro_search (char *, char *);
50 static struct decodeInfo
* find_match (unsigned int);
53 static struct decodeInfo
*decodeTable
;
54 static int initialized
;
55 static char previousOpName
[10];
56 static unsigned int perviousBin
;
58 /* Disassemble one instruction at address 'memaddr'. Returns the number
59 of bytes used by that instruction. */
62 print_insn (bfd_vma memaddr
, struct disassemble_info
* info
)
65 unsigned int raw_code
;
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;
79 unsigned int operMaskReg
= 0;
80 /* Initialize our array of opcode masks and check them against our constant
84 decodeTable
= xmalloc (sizeof (struct decodeInfo
) * xgate_num_opcodes
);
85 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
86 i
++, decodeTablePTR
++, opcodePTR
++)
89 unsigned int mask
= 0;
90 for (s
= opcodePTR
->format
; *s
; s
++)
94 operandRegisterBits
<<= 1;
96 mask
|= (*s
== '0' || *s
== '1');
97 operandRegisterBits
|= (*s
== 'r');
99 /* Asserting will uncover inconsistencies in our table. */
100 assert ((s
- opcodePTR
->format
) == 16 || (s
- opcodePTR
->format
) == 32);
101 assert (opcodePTR
->bin_opcode
== bin
);
103 decodeTablePTR
->operMask
= mask
;
104 decodeTablePTR
->operMasksRegisterBits
= operandRegisterBits
;
105 decodeTablePTR
->opcodePTR
= opcodePTR
;
111 bytesRead
+= XGATE_TWO_BYTES
;
112 status
= read_memory (memaddr
, buffer
, XGATE_TWO_BYTES
, info
);
115 raw_code
= buffer
[0];
117 raw_code
+= buffer
[1];
119 decodePTR
= find_match (raw_code
);
122 operMaskReg
= decodePTR
->operMasksRegisterBits
;
123 (*info
->fprintf_func
)(info
->stream
, "%s", decodePTR
->opcodePTR
->name
);
125 /* First we compare the shorthand format of the constraints. If we
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
))
130 (*info
->fprintf_func
)(info
->stream
, " R%x, CCR",
131 (raw_code
>> 8) & 0x7);
133 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON_C_R
))
135 (*info
->fprintf_func
)(info
->stream
, " CCR, R%x",
136 (raw_code
>> 8) & 0x7);
138 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON_R_P
))
140 (*info
->fprintf_func
)(info
->stream
, " R%x, PC",
141 (raw_code
>> 8) & 0x7);
143 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_TRI
))
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);
149 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDR
))
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);
157 else if (raw_code
& 0x02)
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);
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);
170 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_DYA
))
172 operandOne
= ripBits (&operMaskReg
, 3, decodePTR
->opcodePTR
, raw_code
);
173 operandTwo
= ripBits (&operMaskReg
, 3, decodePTR
->opcodePTR
, raw_code
);
174 ( *info
->fprintf_func
)(info
->stream
, " R%x, R%x", operandOne
,
177 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDO5
))
179 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, #0x%x)",
180 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7, raw_code
& 0x1f);
182 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON
))
184 operandOne
= ripBits (&operMaskReg
, 3, decodePTR
->opcodePTR
,
186 (*info
->fprintf_func
)(info
->stream
, " R%x", operandOne
);
188 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL9
))
190 /* If address is negative handle it accordingly. */
191 if (raw_code
& XGATE_NINE_SIGNBIT
)
193 relAddr
= XGATE_NINE_BITS
>> 1; /* Clip sign bit. */
194 relAddr
= ~relAddr
; /* Make signed. */
195 relAddr
|= (raw_code
& 0xFF) + 1; /* Apply our value. */
196 relAddr
*= 2; /* Multiply by two as per processor docs. */
200 relAddr
= raw_code
& 0xff;
201 relAddr
= relAddr
* 2 + 2;
203 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
204 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
205 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
207 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL10
))
209 /* If address is negative handle it accordingly. */
210 if (raw_code
& XGATE_TEN_SIGNBIT
)
212 relAddr
= XGATE_TEN_BITS
>> 1; /* Clip sign bit. */
213 relAddr
= ~relAddr
; /* Make signed. */
214 relAddr
|= (raw_code
& 0x1FF) + 1; /* Apply our value. */
215 relAddr
*= 2; /* Multiply by two as per processor docs. */
219 relAddr
= raw_code
& 0x1FF;
220 relAddr
= relAddr
* 2 + 2;
222 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
223 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
224 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
226 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM4
))
228 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
229 (raw_code
>> 8) & 0x7, (raw_code
>> 4) & 0xF);
231 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM8
))
233 if (macro_search (decodePTR
->opcodePTR
->name
, previousOpName
) &&
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;
245 strcpy (previousOpName
, decodePTR
->opcodePTR
->name
);
246 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
247 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
250 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM3
))
252 (*info
->fprintf_func
)(info
->stream
, " #0x%x",
253 (raw_code
>> 8) & 0x7);
255 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_INH
))
260 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
261 decodePTR
->opcodePTR
->constraints
);
263 perviousBin
= raw_code
;
267 (*info
->fprintf_func
)(info
->stream
,
268 " unable to find opcode match #0%x", raw_code
);
275 print_insn_xgate (bfd_vma memaddr
, struct disassemble_info
* info
)
277 return print_insn (memaddr
, info
);
281 read_memory (bfd_vma memaddr
, bfd_byte
* buffer
, int size
,
282 struct disassemble_info
* info
)
285 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
288 (*info
->memory_error_func
) (status
, memaddr
, info
);
295 ripBits (unsigned int *operandBitsRemaining
,
296 int numBitsRequested
,
297 struct xgate_opcode
*opcodePTR
,
300 unsigned int currentBit
;
301 unsigned int operand
= 0;
304 for (numBitsFound
= 0, currentBit
= 1u << ((opcodePTR
->size
* 8) - 1);
305 numBitsFound
< numBitsRequested
&& currentBit
!= 0;
308 if (currentBit
& *operandBitsRemaining
)
310 *operandBitsRemaining
&= ~(currentBit
); /* Consume the current bit. */
311 operand
<<= 1; /* Make room for our next bit. */
313 operand
|= (currentBit
& memory
) > 0;
320 macro_search (char *currentName
, char *lastName
)
326 for (i
= 0; i
< xgate_num_opcodes
; i
++)
328 where
= strstr (xgate_opcodes
[i
].constraints
, lastName
);
332 length
= strlen (where
);
336 where
= strstr (xgate_opcodes
[i
].constraints
, currentName
);
339 length
= strlen (where
);
347 static struct decodeInfo
*
348 find_match (unsigned int raw_code
)
350 struct decodeInfo
*decodeTablePTR
= 0;
353 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
354 i
++, decodeTablePTR
++)
356 if ((raw_code
& decodeTablePTR
->operMask
)
357 == decodeTablePTR
->opcodePTR
->bin_opcode
)
359 /* Make sure we didn't run into a macro or alias. */
360 if (decodeTablePTR
->opcodePTR
->cycles_min
!= 0)
362 return decodeTablePTR
;