1 /* xgate-dis.c -- Freescale XGATE disassembly
2 Copyright 2009, 2010, 2011, 2012
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,
21 MA 02110-1301, USA. */
27 #include "libiberty.h"
29 #include "opcode/xgate.h"
31 #define XGATE_TWO_BYTES 0x02
32 #define XGATE_NINE_BITS 0x1FF
33 #define XGATE_TEN_BITS 0x3FF
34 #define XGATE_NINE_SIGNBIT 0x100
35 #define XGATE_TEN_SIGNBIT 0x200
40 unsigned int operMask
;
41 unsigned int operMasksRegisterBits
;
42 struct xgate_opcode
*opcodePTR
;
45 /* Prototypes for local functions. */
46 static int print_insn (bfd_vma
, struct disassemble_info
*);
47 static int read_memory (bfd_vma
, bfd_byte
*, int, struct disassemble_info
*);
48 static int ripBits (unsigned int *, int,
49 struct xgate_opcode
*, unsigned int);
50 static int macro_search (char *, char *);
51 static struct decodeInfo
* find_match (unsigned int);
54 static struct decodeInfo
*decodeTable
;
55 static int initialized
;
56 static char previousOpName
[10];
57 static unsigned int perviousBin
;
59 /* Disassemble one instruction at address 'memaddr'. Returns the number
60 of bytes used by that instruction. */
63 print_insn (bfd_vma memaddr
, struct disassemble_info
* info
)
66 unsigned int raw_code
;
70 struct xgate_opcode
*opcodePTR
= (struct xgate_opcode
*) xgate_opcodes
;
71 struct decodeInfo
*decodeTablePTR
= 0;
72 struct decodeInfo
*decodePTR
= 0;
73 unsigned int operandRegisterBits
= 0;
74 signed int relAddr
= 0;
75 signed int operandOne
= 0;
76 signed int operandTwo
= 0;
80 unsigned int operMaskReg
= 0;
81 /* Initialize our array of opcode masks and check them against our constant
85 decodeTable
= xmalloc (sizeof (struct decodeInfo
) * xgate_num_opcodes
);
86 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
87 i
++, decodeTablePTR
++, opcodePTR
++)
90 unsigned int mask
= 0;
91 for (s
= opcodePTR
->format
; *s
; s
++)
95 operandRegisterBits
<<= 1;
97 mask
|= (*s
== '0' || *s
== '1');
98 operandRegisterBits
|= (*s
== 'r');
100 /* Asserting will uncover inconsistencies in our table. */
101 assert ((s
- opcodePTR
->format
) == 16 || (s
- opcodePTR
->format
) == 32);
102 assert (opcodePTR
->bin_opcode
== bin
);
104 decodeTablePTR
->operMask
= mask
;
105 decodeTablePTR
->operMasksRegisterBits
= operandRegisterBits
;
106 decodeTablePTR
->opcodePTR
= opcodePTR
;
112 bytesRead
+= XGATE_TWO_BYTES
;
113 status
= read_memory (memaddr
, buffer
, XGATE_TWO_BYTES
, info
);
116 raw_code
= buffer
[0];
118 raw_code
+= buffer
[1];
120 decodePTR
= find_match (raw_code
);
123 operMaskReg
= decodePTR
->operMasksRegisterBits
;
124 (*info
->fprintf_func
)(info
->stream
, "%s", decodePTR
->opcodePTR
->name
);
126 /* First we compare the shorthand format of the constraints. If we
127 still are unable to pinpoint the operands
128 we analyze the opcodes constraint string. */
129 switch (decodePTR
->opcodePTR
->sh_format
)
132 (*info
->fprintf_func
)(info
->stream
, " R%x, CCR",
133 (raw_code
>> 8) & 0x7);
136 (*info
->fprintf_func
)(info
->stream
, " CCR, R%x",
137 (raw_code
>> 8) & 0x7);
140 (*info
->fprintf_func
)(info
->stream
, " R%x, PC",
141 (raw_code
>> 8) & 0x7);
146 if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_TRI
))
148 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x, R%x",
149 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
150 (raw_code
>> 2) & 0x7);
152 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDR
))
156 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x+)",
157 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
158 (raw_code
>> 2) & 0x7);
160 else if (raw_code
& 0x02)
162 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, -R%x)",
163 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
164 (raw_code
>> 2) & 0x7);
168 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x)",
169 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
170 (raw_code
>> 2) & 0x7);
175 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
176 decodePTR
->opcodePTR
->constraints
);
180 if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_DYA
))
182 operandOne
= ripBits (&operMaskReg
, 3, opcodePTR
, raw_code
);
183 operandTwo
= ripBits (&operMaskReg
, 3, opcodePTR
, raw_code
);
184 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x", operandOne
,
189 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
190 opcodePTR
->constraints
);
194 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, #0x%x)",
195 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7, raw_code
& 0x1f);
198 operandOne
= ripBits (&operMaskReg
, 3, decodePTR
->opcodePTR
,
200 (*info
->fprintf_func
)(info
->stream
, " R%x", operandOne
);
202 case XG_I
| XG_PCREL
:
203 if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL9
))
205 /* If address is negative handle it accordingly. */
206 if (raw_code
& XGATE_NINE_SIGNBIT
)
208 relAddr
= XGATE_NINE_BITS
>> 1; /* Clip sign bit. */
209 relAddr
= ~relAddr
; /* Make signed. */
210 relAddr
|= (raw_code
& 0xFF) + 1; /* Apply our value. */
211 relAddr
<<= 1; /* Multiply by two as per processor docs. */
215 relAddr
= raw_code
& 0xff;
216 relAddr
= (relAddr
<< 1) + 2;
218 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
219 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
220 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
222 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL10
))
224 /* If address is negative handle it accordingly. */
225 if (raw_code
& XGATE_TEN_SIGNBIT
)
227 relAddr
= XGATE_TEN_BITS
>> 1; /* Clip sign bit. */
228 relAddr
= ~relAddr
; /* Make signed. */
229 relAddr
|= (raw_code
& 0x1FF) + 1; /* Apply our value. */
230 relAddr
<<= 1; /* Multiply by two as per processor docs. */
234 relAddr
= raw_code
& 0x1FF;
235 relAddr
= (relAddr
<< 1) + 2;
237 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
238 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
239 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
243 (*info
->fprintf_func
)(info
->stream
,
244 " Can't disassemble for mode) %s",
245 decodePTR
->opcodePTR
->constraints
);
249 if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM4
))
251 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
252 (raw_code
>> 8) & 0x7, (raw_code
>> 4) & 0xF);
254 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM8
))
256 if (macro_search (decodePTR
->opcodePTR
->name
, previousOpName
) &&
259 absAddress
= (0xFF & raw_code
) << 8;
260 absAddress
|= perviousBin
& 0xFF;
261 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x Abs* 0x",
262 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
263 (*info
->print_address_func
)(absAddress
, info
);
264 previousOpName
[0] = 0;
268 strcpy (previousOpName
, decodePTR
->opcodePTR
->name
);
269 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
270 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
275 (*info
->fprintf_func
)(info
->stream
,
276 " Can't disassemble for mode %s",
277 decodePTR
->opcodePTR
->constraints
);
281 (*info
->fprintf_func
)(info
->stream
, " #0x%x",
282 (raw_code
>> 8) & 0x7);
285 (*info
->fprintf_func
)(info
->stream
, "address mode not found\t %x",
286 opcodePTR
->bin_opcode
);
289 perviousBin
= raw_code
;
293 (*info
->fprintf_func
)(info
->stream
,
294 " unable to find opcode match #0%x", raw_code
);
301 print_insn_xgate (bfd_vma memaddr
, struct disassemble_info
* info
)
303 return print_insn (memaddr
, info
);
307 read_memory (bfd_vma memaddr
, bfd_byte
* buffer
, int size
,
308 struct disassemble_info
* info
)
311 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
314 (*info
->memory_error_func
) (status
, memaddr
, info
);
321 ripBits (unsigned int *operandBitsRemaining
,
322 int numBitsRequested
,
323 struct xgate_opcode
*opcodePTR
,
326 unsigned int currentBit
;
330 for (operand
= 0, numBitsFound
= 0, currentBit
= 1
331 << ((opcodePTR
->size
* 8) - 1);
332 (numBitsFound
< numBitsRequested
) && currentBit
; currentBit
>>= 1)
334 if (currentBit
& *operandBitsRemaining
)
336 *operandBitsRemaining
&= ~(currentBit
); /* Consume the current bit. */
337 operand
<<= 1; /* Make room for our next bit. */
339 operand
|= (currentBit
& memory
) > 0;
346 macro_search (char *currentName
, char *lastName
)
352 for (i
= 0; i
< xgate_num_opcodes
; i
++)
354 where
= strstr (xgate_opcodes
[i
].constraints
, lastName
);
358 length
= strlen (where
);
362 where
= strstr (xgate_opcodes
[i
].constraints
, currentName
);
365 length
= strlen (where
);
373 static struct decodeInfo
*
374 find_match (unsigned int raw_code
)
376 struct decodeInfo
*decodeTablePTR
= 0;
379 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
380 i
++, decodeTablePTR
++)
382 if ((raw_code
& decodeTablePTR
->operMask
)
383 == decodeTablePTR
->opcodePTR
->bin_opcode
)
385 /* Make sure we didn't run into a macro or alias. */
386 if (decodeTablePTR
->opcodePTR
->cycles_min
!= 0)
388 return decodeTablePTR
;
This page took 0.04429 seconds and 4 git commands to generate.