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 if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON_R_C
))
131 (*info
->fprintf_func
)(info
->stream
, " R%x, CCR",
132 (raw_code
>> 8) & 0x7);
134 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON_C_R
))
136 (*info
->fprintf_func
)(info
->stream
, " CCR, R%x",
137 (raw_code
>> 8) & 0x7);
139 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON_R_P
))
141 (*info
->fprintf_func
)(info
->stream
, " R%x, PC",
142 (raw_code
>> 8) & 0x7);
144 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_TRI
))
146 (*info
->fprintf_func
)(info
->stream
, " R%x, R%x, R%x",
147 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
148 (raw_code
>> 2) & 0x7);
150 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDR
))
154 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x+)",
155 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
156 (raw_code
>> 2) & 0x7);
158 else if (raw_code
& 0x02)
160 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, -R%x)",
161 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
162 (raw_code
>> 2) & 0x7);
166 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, R%x)",
167 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7,
168 (raw_code
>> 2) & 0x7);
171 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_DYA
))
173 operandOne
= ripBits (&operMaskReg
, 3, opcodePTR
, raw_code
);
174 operandTwo
= ripBits (&operMaskReg
, 3, opcodePTR
, raw_code
);
175 ( *info
->fprintf_func
)(info
->stream
, " R%x, R%x", operandOne
,
178 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IDO5
))
180 (*info
->fprintf_func
)(info
->stream
, " R%x, (R%x, #0x%x)",
181 (raw_code
>> 8) & 0x7, (raw_code
>> 5) & 0x7, raw_code
& 0x1f);
183 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_MON
))
185 operandOne
= ripBits (&operMaskReg
, 3, decodePTR
->opcodePTR
,
187 (*info
->fprintf_func
)(info
->stream
, " R%x", operandOne
);
189 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL9
))
191 /* If address is negative handle it accordingly. */
192 if (raw_code
& XGATE_NINE_SIGNBIT
)
194 relAddr
= XGATE_NINE_BITS
>> 1; /* Clip sign bit. */
195 relAddr
= ~relAddr
; /* Make signed. */
196 relAddr
|= (raw_code
& 0xFF) + 1; /* Apply our value. */
197 relAddr
<<= 1; /* Multiply by two as per processor docs. */
201 relAddr
= raw_code
& 0xff;
202 relAddr
= (relAddr
<< 1) + 2;
204 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
205 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
206 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
208 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_REL10
))
210 /* If address is negative handle it accordingly. */
211 if (raw_code
& XGATE_TEN_SIGNBIT
)
213 relAddr
= XGATE_TEN_BITS
>> 1; /* Clip sign bit. */
214 relAddr
= ~relAddr
; /* Make signed. */
215 relAddr
|= (raw_code
& 0x1FF) + 1; /* Apply our value. */
216 relAddr
<<= 1; /* Multiply by two as per processor docs. */
220 relAddr
= raw_code
& 0x1FF;
221 relAddr
= (relAddr
<< 1) + 2;
223 (*info
->fprintf_func
)(info
->stream
, " *%d", relAddr
);
224 (*info
->fprintf_func
)(info
->stream
, " Abs* 0x");
225 (*info
->print_address_func
)(memaddr
+ relAddr
, info
);
227 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM4
))
229 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
230 (raw_code
>> 8) & 0x7, (raw_code
>> 4) & 0xF);
232 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM8
))
234 if (macro_search (decodePTR
->opcodePTR
->name
, previousOpName
) &&
237 absAddress
= (0xFF & raw_code
) << 8;
238 absAddress
|= perviousBin
& 0xFF;
239 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x Abs* 0x",
240 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
241 (*info
->print_address_func
)(absAddress
, info
);
242 previousOpName
[0] = 0;
246 strcpy (previousOpName
, decodePTR
->opcodePTR
->name
);
247 (*info
->fprintf_func
)(info
->stream
, " R%x, #0x%02x",
248 (raw_code
>> 8) & 0x7, raw_code
& 0xff);
251 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_IMM3
))
253 (*info
->fprintf_func
)(info
->stream
, " #0x%x",
254 (raw_code
>> 8) & 0x7);
256 else if (!strcmp (decodePTR
->opcodePTR
->constraints
, XGATE_OP_INH
))
262 (*info
->fprintf_func
)(info
->stream
, " unhandled mode %s",
263 opcodePTR
->constraints
);
265 perviousBin
= raw_code
;
269 (*info
->fprintf_func
)(info
->stream
,
270 " unable to find opcode match #0%x", raw_code
);
277 print_insn_xgate (bfd_vma memaddr
, struct disassemble_info
* info
)
279 return print_insn (memaddr
, info
);
283 read_memory (bfd_vma memaddr
, bfd_byte
* buffer
, int size
,
284 struct disassemble_info
* info
)
287 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
290 (*info
->memory_error_func
) (status
, memaddr
, info
);
297 ripBits (unsigned int *operandBitsRemaining
,
298 int numBitsRequested
,
299 struct xgate_opcode
*opcodePTR
,
302 unsigned int currentBit
;
306 for (operand
= 0, numBitsFound
= 0, currentBit
= 1
307 << ((opcodePTR
->size
* 8) - 1);
308 (numBitsFound
< numBitsRequested
) && currentBit
; currentBit
>>= 1)
310 if (currentBit
& *operandBitsRemaining
)
312 *operandBitsRemaining
&= ~(currentBit
); /* Consume the current bit. */
313 operand
<<= 1; /* Make room for our next bit. */
315 operand
|= (currentBit
& memory
) > 0;
322 macro_search (char *currentName
, char *lastName
)
328 for (i
= 0; i
< xgate_num_opcodes
; i
++)
330 where
= strstr (xgate_opcodes
[i
].constraints
, lastName
);
334 length
= strlen (where
);
338 where
= strstr (xgate_opcodes
[i
].constraints
, currentName
);
341 length
= strlen (where
);
349 static struct decodeInfo
*
350 find_match (unsigned int raw_code
)
352 struct decodeInfo
*decodeTablePTR
= 0;
355 for (i
= 0, decodeTablePTR
= decodeTable
; i
< xgate_num_opcodes
;
356 i
++, decodeTablePTR
++)
358 if ((raw_code
& decodeTablePTR
->operMask
)
359 == decodeTablePTR
->opcodePTR
->bin_opcode
)
361 /* Make sure we didn't run into a macro or alias. */
362 if (decodeTablePTR
->opcodePTR
->cycles_min
!= 0)
364 return decodeTablePTR
;
This page took 0.051627 seconds and 4 git commands to generate.