1 /* xgate-dis.c -- Freescale XGATE disassembly
2 Copyright 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Written by Sean Keys (skeys@ipdatasys.com)
6 This file is part of the GNU opcodes library.
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)
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.
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,
28 #include "libiberty.h"
30 #include "opcode/xgate.h"
32 #define XGATE_TWO_BYTES 0x02
33 #define XGATE_NINE_BITS 0x1FF
34 #define XGATE_TEN_BITS 0x3FF
35 #define XGATE_NINE_SIGNBIT 0x100
36 #define XGATE_TEN_SIGNBIT 0x200
40 unsigned int operMask
;
41 unsigned int operMasksRegisterBits
;
42 struct xgate_opcode
*opcodePTR
;
45 /* Prototypes for local functions. */
47 print_insn( bfd_vma
, struct disassemble_info
*);
49 read_memory( bfd_vma
, bfd_byte
*, int, struct disassemble_info
*);
51 ripBits(unsigned int *, int,
52 struct xgate_opcode
*, unsigned int);
54 macro_search(char *, char *);
56 find_match(unsigned int raw_code
);
59 static struct decodeInfo
*decodeTable
;
60 static int initialized
;
61 static char previousOpName
[10];
62 static unsigned int perviousBin
;
64 /* Disassemble one instruction at address 'memaddr'. Returns the number
65 of bytes used by that instruction. */
67 print_insn (bfd_vma memaddr
, struct disassemble_info
* info
)
70 unsigned int raw_code
;
74 struct xgate_opcode
*opcodePTR
= (struct xgate_opcode
*) xgate_opcodes
;
75 struct decodeInfo
*decodeTablePTR
= 0;
76 struct decodeInfo
*decodePTR
= 0;
77 unsigned int operandRegisterBits
= 0;
78 signed int relAddr
= 0;
79 signed int operandOne
= 0;
80 signed int operandTwo
= 0;
84 unsigned int operMaskReg
= 0;
85 /* initialize our array of opcode masks and check them against our constant
89 decodeTable
= xmalloc(sizeof(struct decodeInfo
) * xgate_num_opcodes
);
90 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
91 i
++, decodeTablePTR
++, opcodePTR
++)
94 unsigned int mask
= 0;
95 for (s
= opcodePTR
->format
; *s
; s
++)
99 operandRegisterBits
<<= 1;
101 mask
|= (*s
== '0' || *s
== '1');
102 operandRegisterBits
|= (*s
== 'r');
104 /* asserting will uncover inconsistencies in our table */
106 (s
- opcodePTR
->format
) == 16 || (s
- opcodePTR
->format
) == 32);
107 assert(opcodePTR
->bin_opcode
== bin
);
108 decodeTablePTR
->operMask
= mask
;
109 decodeTablePTR
->operMasksRegisterBits
= operandRegisterBits
;
110 decodeTablePTR
->opcodePTR
= opcodePTR
;
115 bytesRead
+= XGATE_TWO_BYTES
;
116 status
= read_memory(memaddr
, buffer
, XGATE_TWO_BYTES
, info
);
119 raw_code
= buffer
[0];
121 raw_code
+= buffer
[1];
123 decodePTR
= find_match(raw_code
);
126 operMaskReg
= decodePTR
->operMasksRegisterBits
;
127 (*info
->fprintf_func
)(info
->stream
, "%s", decodePTR
->opcodePTR
->name
);
128 /* First we compare the shorthand format of the constraints. If we
129 still are unable to pinpoint the operands
130 we analyze the opcodes constraint string. */
131 switch (decodePTR
->opcodePTR
->sh_format
)
134 (*info
->fprintf_func
)(info
->stream
, " R%x, CCR",
135 (raw_code
>> 8) & 0x7);
138 (*info
->fprintf_func
)(info
->stream
, " CCR, R%x",
139 (raw_code
>> 8) & 0x7);
142 (*info
->fprintf_func
)(info
->stream
, " R%x, PC",
143 (raw_code
>> 8) & 0x7);
148 if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_TRI
))
150 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x, R%x",
151 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
152 (raw_code
>> 2) & 0x7);
154 else if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDR
))
158 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x+)",
159 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
160 (raw_code
>> 2) & 0x7);
162 else if (raw_code
& 0x02)
164 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, -R%x)",
165 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
166 (raw_code
>> 2) & 0x7);
170 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x)",
171 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
172 (raw_code
>> 2) & 0x7);
177 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
178 decodePTR
->opcodePTR
->constraints
);
182 if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_DYA_MON
))
184 operandOne
= ripBits(&operMaskReg
, 3, decodePTR
->opcodePTR
,
186 operandTwo
= ripBits(&operMaskReg
, 3, decodePTR
->opcodePTR
,
188 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x", operandOne
,
191 else if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_DYA
))
193 operandOne
= ripBits(&operMaskReg
, 3, opcodePTR
, raw_code
);
194 operandTwo
= ripBits(&operMaskReg
, 3, opcodePTR
, raw_code
);
195 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x", operandOne
,
200 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
201 opcodePTR
->constraints
);
205 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, #0x%x)",
206 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7, raw_code
& 0x1f);
209 operandOne
= ripBits(&operMaskReg
, 3, decodePTR
->opcodePTR
,
211 (*info
->fprintf_func
)(info
->stream
, " R%x", operandOne
);
213 case XG_I
| XG_PCREL
:
214 if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL9
))
216 /* if address is negative handle it accordingly */
217 if (raw_code
& XGATE_NINE_SIGNBIT
)
219 relAddr
= XGATE_NINE_BITS
>> 1; /* clip sign bit */
220 relAddr
= ~relAddr
; /* make signed */
221 relAddr
|= (raw_code
& 0xFF) + 1; /* apply our value */
222 relAddr
<<= 1; /* multiply by two as per processor docs */
226 relAddr
= raw_code
& 0xff;
227 relAddr
= (relAddr
<< 1) + 2;
229 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
230 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
231 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
233 else if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL10
))
235 /* if address is negative handle it accordingly */
236 if (raw_code
& XGATE_TEN_SIGNBIT
)
238 relAddr
= XGATE_TEN_BITS
>> 1; /* clip sign bit */
239 relAddr
= ~relAddr
; /* make signed */
240 relAddr
|= (raw_code
& 0x1FF) + 1; /* apply our value */
241 relAddr
<<= 1; /* multiply by two as per processor docs */
245 relAddr
= raw_code
& 0x1FF;
246 relAddr
= (relAddr
<< 1) + 2;
248 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
249 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
250 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
254 (*info
->fprintf_func
)(info
->stream
,
255 " Can't disassemble for mode) %s",
256 decodePTR
->opcodePTR
->constraints
);
260 if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM4
))
262 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
263 (raw_code
>> 8) & 0x7, (raw_code
>> 4) & 0xF);
265 else if (!strcmp(decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM8
))
267 if (macro_search(decodePTR
->opcodePTR
->name
, previousOpName
) &&
270 absAddress
= (0xFF & raw_code
) << 8;
271 absAddress
|= perviousBin
& 0xFF;
272 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x Abs* 0x",
273 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
274 (*info
->print_address_func
)(absAddress
, info
);
275 previousOpName
[0] = 0;
279 strcpy(previousOpName
, decodePTR
->opcodePTR
->name
);
280 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
281 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
286 (*info
->fprintf_func
)(info
->stream
,
287 " Can't disassemble for mode %s",
288 decodePTR
->opcodePTR
->constraints
);
292 (*info
->fprintf_func
)(info
->stream
, " #0x%x",
293 (raw_code
>> 8) & 0x7);
296 (*info
->fprintf_func
)(info
->stream
, "address mode not found\t %x",
297 opcodePTR
->bin_opcode
);
300 perviousBin
= raw_code
;
304 (*info
->fprintf_func
)(info
->stream
,
305 " unable to find opcode match #0%x", raw_code
);
312 print_insn_xgate (bfd_vma memaddr
, struct disassemble_info
* info
)
314 return print_insn (memaddr
, info
);
318 read_memory (bfd_vma memaddr
, bfd_byte
* buffer
, int size
,
319 struct disassemble_info
* info
)
322 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
325 (*info
->memory_error_func
) (status
, memaddr
, info
);
332 ripBits(unsigned int *operandBitsRemaining
, int numBitsRequested
,
333 struct xgate_opcode
*opcodePTR
, unsigned int memory
)
335 unsigned int currentBit
;
338 for (operand
= 0, numBitsFound
= 0, currentBit
= 1
339 << ((opcodePTR
->size
* 8) - 1);
340 (numBitsFound
< numBitsRequested
) && currentBit
; currentBit
>>= 1)
342 if(currentBit
& *operandBitsRemaining
) {
343 *operandBitsRemaining
&= ~(currentBit
); /* consume the current bit */
344 operand
<<= 1; /* make room for our next bit */
346 operand
|= (currentBit
& memory
) > 0;
353 macro_search(char *currentName
, char *lastName
)
358 for (i
= 0; i
< xgate_num_opcodes
; i
++)
360 where
= strstr(xgate_opcodes
[i
].constraints
, lastName
);
363 length
= strlen(where
);
367 where
= strstr(xgate_opcodes
[i
].constraints
, currentName
);
370 length
= strlen(where
);
379 find_match(unsigned int raw_code
)
381 struct decodeInfo
*decodeTablePTR
= 0;
384 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
385 i
++, decodeTablePTR
++)
387 if ((raw_code
& decodeTablePTR
->operMask
)
388 == decodeTablePTR
->opcodePTR
->bin_opcode
)
390 /* make sure we didn't run into a macro or alias */
391 if (decodeTablePTR
->opcodePTR
->cycles_min
!= 0)
393 return decodeTablePTR
;
This page took 0.052235 seconds and 4 git commands to generate.