Commit | Line | Data |
---|---|---|
7499d566 NC |
1 | /* Instruction printing code for the MAXQ |
2 | ||
9b201bb5 | 3 | Copyright 2004, 2005, 2007 Free Software Foundation, Inc. |
7499d566 NC |
4 | |
5 | Written by Vineet Sharma(vineets@noida.hcltech.com) Inderpreet | |
6 | S.(inderpreetb@noida.hcltech.com) | |
7 | ||
9b201bb5 | 8 | This file is part of the GNU opcodes library. |
7499d566 | 9 | |
9b201bb5 NC |
10 | This library is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | |
12 | the Free Software Foundation; either version 3, or (at your option) | |
7499d566 NC |
13 | any later version. |
14 | ||
9b201bb5 NC |
15 | It is distributed in the hope that it will be useful, but WITHOUT |
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
17 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
18 | License for more details. | |
7499d566 NC |
19 | |
20 | You should have received a copy of the GNU General Public License along | |
f4321104 NC |
21 | with this program; if not, write to the Free Software Foundation, Inc., |
22 | 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
7499d566 NC |
23 | |
24 | #include "sysdep.h" | |
25 | #include "dis-asm.h" | |
26 | #include "opcode/maxq.h" | |
27 | ||
28 | struct _group_info | |
29 | { | |
30 | unsigned char group_no; | |
31 | unsigned char sub_opcode; | |
32 | unsigned char src; | |
33 | unsigned char dst; | |
34 | unsigned char fbit; | |
35 | unsigned char bit_no; | |
36 | unsigned char flag; | |
37 | ||
38 | }; | |
39 | ||
40 | typedef struct _group_info group_info; | |
41 | ||
42 | #define SRC 0x01 | |
43 | #define DST 0x02 | |
44 | #define FORMAT 0x04 | |
45 | #define BIT_NO 0x08 | |
46 | #define SUB_OP 0x10 | |
47 | ||
48 | #define MASK_LOW_BYTE 0x0f | |
49 | #define MASK_HIGH_BYTE 0xf0 | |
50 | ||
51 | /* Flags for retrieving the bits from the op-code. */ | |
52 | #define _DECODE_LOWNIB_LOWBYTE 0x000f | |
53 | #define _DECODE_HIGHNIB_LOWBYTE 0x00f0 | |
54 | #define _DECODE_LOWNIB_HIGHBYTE 0x0f00 | |
55 | #define _DECODE_HIGHNIB_HIGHBYTE 0xf000 | |
56 | #define _DECODE_HIGHBYTE 0xff00 | |
57 | #define _DECODE_LOWBYTE 0x00ff | |
58 | #define _DECODE_4TO6_HIGHBYTE 0x7000 | |
59 | #define _DECODE_4TO6_LOWBYTE 0x0070 | |
60 | #define _DECODE_0TO6_HIGHBYTE 0x7f00 | |
61 | #define _DECODE_0TO2_HIGHBYTE 0x0700 | |
62 | #define _DECODE_GET_F_HIGHBYTE 0x8000 | |
63 | #define _DECODE_BIT7_HIGHBYTE 0x8000 | |
64 | #define _DECODE_BIT7_LOWBYTE 0x0080 | |
65 | #define _DECODE_GET_CARRY 0x10000 | |
66 | #define _DECODE_BIT0_LOWBYTE 0x1 | |
67 | #define _DECODE_BIT6AND7_HIGHBYTE 0xc000 | |
68 | ||
69 | /* Module and Register Indexed of System Registers. */ | |
70 | #define _CURR_ACC_MODINDEX 0xa | |
71 | #define _CURR_ACC_REGINDEX 0x0 | |
72 | #define _PSF_REG_MODINDEX 0x8 | |
73 | #define _PSF_REG_REGINDEX 0x4 | |
74 | #define _PFX_REG_MODINDEX 0xb | |
75 | #define _PFX0_REG_REGINDEX 0x0 | |
76 | #define _PFX2_REG_REGINDEX 0x2 | |
77 | #define _DP_REG_MODINDEX 0xf | |
78 | #define _DP0_REG_REGINDEX 0x3 | |
79 | #define _DP1_REG_REGINDEX 0x7 | |
80 | #define _IP_REG_MODINDEX 0xc | |
81 | #define _IP_REG_REGINDEX 0x0 | |
82 | #define _IIR_REG_MODINDEX 0x8 | |
83 | #define _IIR_REG_REGINDEX 0xb | |
84 | #define _SP_REG_MODINDEX 0xd | |
85 | #define _SP_REG_REGINDEX 0x1 | |
86 | #define _IC_REG_MODINDEX 0x8 | |
87 | #define _IC_REG_REGINDEX 0x5 | |
88 | #define _LC_REG_MODINDEX 0xe | |
89 | #define _LC0_REG_REGINDEX 0x0 | |
90 | #define _LC1_REG_REGINDEX 0x1 | |
91 | #define _LC2_REG_REGINDEX 0x2 | |
92 | #define _LC3_REG_REGINDEX 0x3 | |
93 | ||
94 | /* Flags for finding the bits in PSF Register. */ | |
95 | #define SIM_ALU_DECODE_CARRY_BIT_POS 0x2 | |
96 | #define SIM_ALU_DECODE_SIGN_BIT_POS 0x40 | |
97 | #define SIM_ALU_DECODE_ZERO_BIT_POS 0x80 | |
98 | #define SIM_ALU_DECODE_EQUAL_BIT_POS 0x1 | |
99 | #define SIM_ALU_DECODE_IGE_BIT_POS 0x1 | |
100 | ||
101 | /* Number Of Op-code Groups. */ | |
102 | unsigned char const SIM_ALU_DECODE_OPCODE_GROUPS = 11; | |
103 | ||
104 | /* Op-code Groups. */ | |
105 | unsigned char const SIM_ALU_DECODE_LOGICAL_XCHG_OP_GROUP = 1; | |
106 | ||
107 | /* Group1: AND/OR/XOR/ADD/SUB Operations: fxxx 1010 ssss ssss. */ | |
108 | unsigned char const SIM_ALU_DECODE_AND_OR_ADD_SUB_OP_GROUP = 2; | |
109 | ||
110 | /* Group2: Logical Operations: 1000 1010 xxxx 1010. */ | |
111 | unsigned char const SIM_ALU_DECODE_BIT_OP_GROUP = 3; | |
112 | ||
113 | /* XCHG/Bit Operations: 1xxx 1010 xxxx 1010. */ | |
114 | unsigned char const SIM_ALU_DECODE_SET_DEST_BIT_GROUP = 4; | |
115 | ||
116 | /* Move value in bit of destination register: 1ddd dddd xbbb 0111. */ | |
117 | unsigned char const SIM_ALU_DECODE_JUMP_OP_GROUP = 5; | |
118 | ||
119 | #define JUMP_CHECK(insn) \ | |
120 | ( ((insn & _DECODE_4TO6_HIGHBYTE) == 0x0000) \ | |
121 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x2000) \ | |
122 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x6000) \ | |
123 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x1000) \ | |
124 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x5000) \ | |
125 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x3000) \ | |
126 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x7000) \ | |
127 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x4000) ) | |
128 | ||
129 | /* JUMP operations: fxxx 1100 ssss ssss */ | |
130 | unsigned char const SIM_ALU_DECODE_RET_OP_GROUP = 6; | |
131 | ||
132 | /* RET Operations: 1xxx 1100 0000 1101 */ | |
133 | unsigned char const SIM_ALU_DECODE_MOVE_SRC_DST_GROUP = 7; | |
134 | ||
135 | /* Move src into dest register: fddd dddd ssss ssss */ | |
136 | unsigned char const SIM_ALU_DECODE_SET_SRC_BIT_GROUP = 8; | |
137 | ||
138 | /* Move value in bit of source register: fbbb 0111 ssss ssss */ | |
139 | unsigned char const SIM_ALU_DECODE_DJNZ_CALL_PUSH_OP_GROUP = 9; | |
140 | ||
141 | /* PUSH, DJNZ and CALL operations: fxxx 1101 ssss ssss */ | |
142 | unsigned char const SIM_ALU_DECODE_POP_OP_GROUP = 10; | |
143 | ||
144 | /* POP operation: 1ddd dddd 0000 1101 */ | |
145 | unsigned char const SIM_ALU_DECODE_CMP_SRC_OP_GROUP = 11; | |
146 | ||
147 | /* GLOBAL */ | |
53c9ebc5 | 148 | char unres_reg_name[20]; |
7499d566 | 149 | |
53c9ebc5 | 150 | static char * |
7499d566 NC |
151 | get_reg_name (unsigned char reg_code, type1 arg_pos) |
152 | { | |
153 | unsigned char module; | |
154 | unsigned char index; | |
155 | int ix = 0; | |
156 | reg_entry const *reg_x; | |
157 | mem_access_syntax const *syntax; | |
158 | mem_access *mem_acc; | |
159 | ||
160 | module = 0; | |
161 | index = 0; | |
162 | module = (reg_code & MASK_LOW_BYTE); | |
163 | index = (reg_code & MASK_HIGH_BYTE); | |
164 | index = index >> 4; | |
165 | ||
166 | /* Search the system register table. */ | |
167 | for (reg_x = &system_reg_table[0]; reg_x->reg_name != NULL; ++reg_x) | |
168 | if ((reg_x->Mod_name == module) && (reg_x->Mod_index == index)) | |
169 | return reg_x->reg_name; | |
170 | ||
171 | /* Serch pheripheral table. */ | |
172 | for (ix = 0; ix < num_of_reg; ix++) | |
173 | { | |
174 | reg_x = &new_reg_table[ix]; | |
175 | ||
176 | if ((reg_x->Mod_name == module) && (reg_x->Mod_index == index)) | |
177 | return reg_x->reg_name; | |
178 | } | |
179 | ||
180 | for (mem_acc = &mem_table[0]; mem_acc->name != NULL || !mem_acc; ++mem_acc) | |
181 | { | |
182 | if (reg_code == mem_acc->opcode) | |
183 | { | |
184 | for (syntax = mem_access_syntax_table; | |
c908d778 | 185 | syntax != NULL && syntax->name; |
7499d566 NC |
186 | ++syntax) |
187 | if (!strcmp (mem_acc->name, syntax->name)) | |
188 | { | |
189 | if ((arg_pos == syntax->type) || (syntax->type == BOTH)) | |
190 | return mem_acc->name; | |
191 | ||
192 | break; | |
193 | } | |
194 | } | |
195 | } | |
196 | ||
197 | memset (unres_reg_name, 0, 20); | |
198 | sprintf (unres_reg_name, "%01x%01xh", index, module); | |
199 | ||
200 | return unres_reg_name; | |
201 | } | |
202 | ||
203 | static bfd_boolean | |
204 | check_move (unsigned char insn0, unsigned char insn8) | |
205 | { | |
206 | bfd_boolean first = FALSE; | |
207 | bfd_boolean second = FALSE; | |
208 | char *first_reg; | |
209 | char *second_reg; | |
210 | reg_entry const *reg_x; | |
211 | const unsigned char module1 = insn0 & MASK_LOW_BYTE; | |
212 | const unsigned char index1 = ((insn0 & 0x70) >> 4); | |
213 | const unsigned char module2 = insn8 & MASK_LOW_BYTE; | |
214 | const unsigned char index2 = ((insn8 & MASK_HIGH_BYTE) >> 4); | |
215 | ||
216 | /* DST */ | |
217 | if (((insn0 & MASK_LOW_BYTE) == MASK_LOW_BYTE) | |
218 | && ((index1 == 0) || (index1 == 1) || (index1 == 2) || (index1 == 5) | |
219 | || (index1 == 4) || (index1 == 6))) | |
220 | first = TRUE; | |
221 | ||
222 | else if (((insn0 & MASK_LOW_BYTE) == 0x0D) && (index1 == 0)) | |
223 | first = TRUE; | |
224 | ||
225 | else if ((module1 == 0x0E) | |
226 | && ((index1 == 0) || (index1 == 1) || (index1 == 2))) | |
227 | first = TRUE; | |
228 | ||
229 | else | |
230 | { | |
231 | for (reg_x = &system_reg_table[0]; reg_x->reg_name != NULL && reg_x; | |
232 | ++reg_x) | |
233 | { | |
234 | if ((reg_x->Mod_name == module1) && (reg_x->Mod_index == index1) | |
235 | && ((reg_x->rtype == Reg_16W) || (reg_x->rtype == Reg_8W))) | |
236 | { | |
237 | /* IP not allowed. */ | |
238 | if ((reg_x->Mod_name == 0x0C) && (reg_x->Mod_index == 0x00)) | |
239 | continue; | |
240 | ||
241 | /* A[AP] not allowed. */ | |
242 | if ((reg_x->Mod_name == 0x0A) && (reg_x->Mod_index == 0x01)) | |
243 | continue; | |
244 | first_reg = reg_x->reg_name; | |
245 | first = TRUE; | |
246 | break; | |
247 | } | |
248 | } | |
249 | } | |
250 | ||
251 | if (!first) | |
252 | /* No need to check further. */ | |
253 | return FALSE; | |
254 | ||
255 | if (insn0 & 0x80) | |
256 | { | |
257 | /* SRC */ | |
258 | if (((insn8 & MASK_LOW_BYTE) == MASK_LOW_BYTE) | |
259 | && ((index2 == 0) || (index2 == 1) || (index2 == 2) || (index2 == 4) | |
260 | || (index2 == 5) || (index2 == 6))) | |
261 | second = TRUE; | |
262 | ||
263 | else if (((insn8 & MASK_LOW_BYTE) == 0x0D) && (index2 == 0)) | |
264 | second = TRUE; | |
265 | ||
266 | else if ((module2 == 0x0E) | |
267 | && ((index2 == 0) || (index2 == 1) || (index2 == 2))) | |
268 | second = TRUE; | |
269 | ||
270 | else | |
271 | { | |
272 | for (reg_x = &system_reg_table[0]; | |
273 | reg_x->reg_name != NULL && reg_x; | |
274 | ++reg_x) | |
275 | { | |
276 | if ((reg_x->Mod_name == (insn8 & MASK_LOW_BYTE)) | |
277 | && (reg_x->Mod_index == (((insn8 & 0xf0) >> 4)))) | |
278 | { | |
279 | second = TRUE; | |
280 | second_reg = reg_x->reg_name; | |
281 | break; | |
282 | } | |
283 | } | |
284 | } | |
285 | ||
286 | if (second) | |
287 | { | |
288 | if ((module1 == 0x0A && index1 == 0x0) | |
289 | && (module2 == 0x0A && index2 == 0x01)) | |
290 | return FALSE; | |
291 | ||
292 | return TRUE; | |
293 | } | |
294 | ||
295 | return FALSE; | |
296 | } | |
297 | ||
298 | return first; | |
299 | } | |
300 | ||
301 | static void | |
302 | maxq_print_arg (MAX_ARG_TYPE arg, | |
303 | struct disassemble_info * info, | |
304 | group_info grp) | |
305 | { | |
306 | switch (arg) | |
307 | { | |
308 | case FLAG_C: | |
309 | info->fprintf_func (info->stream, "C"); | |
310 | break; | |
311 | case FLAG_NC: | |
312 | info->fprintf_func (info->stream, "NC"); | |
313 | break; | |
314 | ||
315 | case FLAG_Z: | |
316 | info->fprintf_func (info->stream, "Z"); | |
317 | break; | |
318 | ||
319 | case FLAG_NZ: | |
320 | info->fprintf_func (info->stream, "NZ"); | |
321 | break; | |
322 | ||
323 | case FLAG_S: | |
324 | info->fprintf_func (info->stream, "S"); | |
325 | break; | |
326 | ||
327 | case FLAG_E: | |
328 | info->fprintf_func (info->stream, "E"); | |
329 | break; | |
330 | ||
331 | case FLAG_NE: | |
332 | info->fprintf_func (info->stream, "NE"); | |
333 | break; | |
334 | ||
335 | case ACC_BIT: | |
336 | info->fprintf_func (info->stream, "Acc"); | |
337 | if ((grp.flag & BIT_NO) == BIT_NO) | |
338 | info->fprintf_func (info->stream, ".%d", grp.bit_no); | |
339 | break; | |
340 | ||
341 | case A_BIT_0: | |
342 | info->fprintf_func (info->stream, "#0"); | |
343 | break; | |
344 | case A_BIT_1: | |
345 | info->fprintf_func (info->stream, "#1"); | |
346 | break; | |
347 | ||
348 | default: | |
349 | break; | |
350 | } | |
351 | } | |
352 | ||
353 | static unsigned char | |
354 | get_group (const unsigned int insn) | |
355 | { | |
356 | if (check_move ((insn >> 8), (insn & _DECODE_LOWBYTE))) | |
357 | return 8; | |
358 | ||
359 | if ((insn & _DECODE_LOWNIB_HIGHBYTE) == 0x0A00) | |
360 | { | |
ca4f2377 AM |
361 | /* && condition with sec part added on 26 May for resolving 2 & 3 grp |
362 | conflict. */ | |
7499d566 NC |
363 | if (((insn & _DECODE_LOWNIB_LOWBYTE) == 0x000A) |
364 | && ((insn & _DECODE_GET_F_HIGHBYTE) == 0x8000)) | |
365 | { | |
366 | if ((insn & _DECODE_HIGHNIB_HIGHBYTE) == 0x8000) | |
367 | return 2; | |
368 | else | |
369 | return 3; | |
370 | } | |
371 | ||
372 | return 1; | |
373 | } | |
374 | else if ((insn & _DECODE_LOWNIB_HIGHBYTE) == 0x0C00) | |
375 | { | |
376 | if (((insn & _DECODE_LOWBYTE) == 0x000D) && JUMP_CHECK (insn) | |
377 | && ((insn & _DECODE_GET_F_HIGHBYTE) == 0x8000)) | |
378 | return 6; | |
379 | else if ((insn & _DECODE_LOWBYTE) == 0x008D) | |
380 | return 7; | |
381 | ||
382 | return 5; | |
383 | } | |
384 | else if (((insn & _DECODE_LOWNIB_HIGHBYTE) == 0x0D00) | |
385 | && (((insn & _DECODE_4TO6_HIGHBYTE) == 0x3000) | |
386 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x4000) | |
387 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x5000) | |
388 | || ((insn & _DECODE_4TO6_HIGHBYTE) == 0x0000))) | |
389 | return 10; | |
390 | ||
391 | else if ((insn & _DECODE_LOWBYTE) == 0x000D) | |
392 | return 11; | |
393 | ||
394 | else if ((insn & _DECODE_LOWBYTE) == 0x008D) | |
395 | return 12; | |
396 | ||
397 | else if ((insn & _DECODE_0TO6_HIGHBYTE) == 0x7800) | |
398 | return 13; | |
399 | ||
400 | else if ((insn & _DECODE_LOWNIB_HIGHBYTE) == 0x0700) | |
401 | return 9; | |
402 | ||
403 | else if (((insn & _DECODE_LOWNIB_LOWBYTE) == 0x0007) | |
404 | && ((insn & _DECODE_GET_F_HIGHBYTE) == 0x8000)) | |
405 | return 4; | |
406 | ||
407 | return 8; | |
408 | } | |
409 | ||
410 | static void | |
411 | get_insn_opcode (const unsigned int insn, group_info *i) | |
412 | { | |
413 | static unsigned char pfx_flag = 0; | |
414 | static unsigned char count_for_pfx = 0; | |
415 | ||
416 | i->flag ^= i->flag; | |
417 | i->bit_no ^= i->bit_no; | |
418 | i->dst ^= i->dst; | |
419 | i->fbit ^= i->fbit; | |
420 | i->group_no ^= i->group_no; | |
421 | i->src ^= i->src; | |
422 | i->sub_opcode ^= i->sub_opcode; | |
423 | ||
424 | if (count_for_pfx > 0) | |
425 | count_for_pfx++; | |
426 | ||
427 | if (((insn >> 8) == 0x0b) || ((insn >> 8) == 0x2b)) | |
428 | { | |
429 | pfx_flag = 1; | |
430 | count_for_pfx = 1; | |
431 | } | |
432 | ||
433 | i->group_no = get_group (insn); | |
434 | ||
435 | if (pfx_flag && (i->group_no == 0x0D) && (count_for_pfx == 2) | |
436 | && ((insn & _DECODE_0TO6_HIGHBYTE) == 0x7800)) | |
437 | { | |
438 | i->group_no = 0x08; | |
439 | count_for_pfx = 0; | |
440 | pfx_flag ^= pfx_flag; | |
441 | } | |
442 | ||
443 | switch (i->group_no) | |
444 | { | |
445 | case 1: | |
446 | i->sub_opcode = ((insn & _DECODE_4TO6_HIGHBYTE) >> 12); | |
447 | i->flag |= SUB_OP; | |
448 | i->src = ((insn & _DECODE_LOWBYTE)); | |
449 | i->flag |= SRC; | |
450 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
451 | i->flag |= FORMAT; | |
452 | break; | |
453 | ||
454 | case 2: | |
455 | i->sub_opcode = ((insn & _DECODE_HIGHNIB_LOWBYTE) >> 4); | |
456 | i->flag |= SUB_OP; | |
457 | break; | |
458 | ||
459 | case 3: | |
460 | i->sub_opcode = ((insn & _DECODE_HIGHNIB_HIGHBYTE) >> 12); | |
461 | i->flag |= SUB_OP; | |
462 | i->bit_no = ((insn & _DECODE_HIGHNIB_LOWBYTE) >> 4); | |
463 | i->flag |= BIT_NO; | |
464 | break; | |
465 | ||
466 | case 4: | |
467 | i->sub_opcode = ((insn & _DECODE_BIT7_LOWBYTE) >> 7); | |
468 | i->flag |= SUB_OP; | |
469 | i->dst = ((insn & _DECODE_0TO6_HIGHBYTE) >> 8); | |
470 | i->flag |= DST; | |
471 | i->bit_no = ((insn & _DECODE_4TO6_LOWBYTE) >> 4); | |
472 | i->flag |= BIT_NO; | |
473 | break; | |
474 | ||
475 | case 5: | |
476 | i->sub_opcode = ((insn & _DECODE_4TO6_HIGHBYTE) >> 12); | |
477 | i->flag |= SUB_OP; | |
478 | i->src = ((insn & _DECODE_LOWBYTE)); | |
479 | i->flag |= SRC; | |
480 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
481 | i->flag |= FORMAT; | |
482 | break; | |
483 | ||
484 | case 6: | |
485 | i->sub_opcode = ((insn & _DECODE_HIGHNIB_HIGHBYTE) >> 12); | |
486 | i->flag |= SUB_OP; | |
487 | break; | |
488 | ||
489 | case 7: | |
490 | i->sub_opcode = ((insn & _DECODE_HIGHNIB_HIGHBYTE) >> 12); | |
491 | i->flag |= SUB_OP; | |
492 | break; | |
493 | ||
494 | case 8: | |
495 | i->dst = ((insn & _DECODE_0TO6_HIGHBYTE) >> 8); | |
496 | i->flag |= DST; | |
497 | i->src = ((insn & _DECODE_LOWBYTE)); | |
498 | i->flag |= SRC; | |
499 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
500 | i->flag |= FORMAT; | |
501 | break; | |
502 | ||
503 | case 9: | |
504 | i->sub_opcode = ((insn & _DECODE_0TO2_HIGHBYTE) >> 8); | |
505 | i->flag |= SUB_OP; | |
506 | i->bit_no = ((insn & _DECODE_4TO6_HIGHBYTE) >> 12); | |
507 | i->flag |= BIT_NO; | |
508 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
509 | i->flag |= FORMAT; | |
510 | i->src = ((insn & _DECODE_LOWBYTE)); | |
511 | i->flag |= SRC; | |
512 | break; | |
513 | ||
514 | case 10: | |
515 | i->sub_opcode = ((insn & _DECODE_4TO6_HIGHBYTE) >> 12); | |
516 | i->flag |= SUB_OP; | |
517 | i->src = ((insn & _DECODE_LOWBYTE)); | |
518 | i->flag |= SRC; | |
519 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
520 | i->flag |= FORMAT; | |
521 | break; | |
522 | ||
523 | case 11: | |
524 | i->dst = ((insn & _DECODE_0TO6_HIGHBYTE) >> 8); | |
525 | i->flag |= DST; | |
526 | break; | |
527 | ||
528 | case 12: | |
529 | i->dst = ((insn & _DECODE_0TO6_HIGHBYTE) >> 8); | |
530 | i->flag |= DST; | |
531 | break; | |
532 | ||
533 | case 13: | |
534 | i->sub_opcode = ((insn & _DECODE_4TO6_HIGHBYTE) >> 12); | |
535 | i->flag |= SUB_OP; | |
536 | i->src = ((insn & _DECODE_LOWBYTE)); | |
537 | i->flag |= SRC; | |
538 | i->fbit = ((insn & _DECODE_GET_F_HIGHBYTE) >> 15); | |
539 | i->flag |= FORMAT; | |
540 | break; | |
541 | ||
542 | } | |
543 | return; | |
544 | } | |
545 | ||
546 | ||
547 | /* Print one instruction from MEMADDR on INFO->STREAM. Return the size of the | |
548 | instruction (always 2 on MAXQ20). */ | |
549 | ||
550 | static int | |
551 | print_insn (bfd_vma memaddr, struct disassemble_info *info, | |
552 | enum bfd_endian endianess) | |
553 | { | |
554 | /* The raw instruction. */ | |
555 | unsigned char insn[2], insn0, insn8, derived_code; | |
556 | unsigned int format; | |
557 | unsigned int actual_operands; | |
558 | unsigned int i; | |
559 | /* The group_info collected/decoded. */ | |
560 | group_info grp; | |
561 | MAXQ20_OPCODE_INFO const *opcode; | |
562 | int status; | |
563 | ||
564 | format = 0; | |
565 | ||
566 | status = info->read_memory_func (memaddr, (bfd_byte *) & insn[0], 2, info); | |
567 | ||
568 | if (status != 0) | |
569 | { | |
570 | info->memory_error_func (status, memaddr, info); | |
571 | return -1; | |
572 | } | |
573 | ||
574 | insn8 = insn[1]; | |
575 | insn0 = insn[0]; | |
576 | ||
577 | /* FIXME: Endianness always little. */ | |
578 | if (endianess == BFD_ENDIAN_BIG) | |
579 | get_insn_opcode (((insn[0] << 8) | (insn[1])), &grp); | |
580 | else | |
581 | get_insn_opcode (((insn[1] << 8) | (insn[0])), &grp); | |
582 | ||
583 | derived_code = ((grp.group_no << 4) | grp.sub_opcode); | |
584 | ||
585 | if (insn[0] == 0 && insn[1] == 0) | |
586 | { | |
587 | info->fprintf_func (info->stream, "00 00"); | |
588 | return 2; | |
589 | } | |
590 | ||
591 | /* The opcode is always in insn0. */ | |
592 | for (opcode = &op_table[0]; opcode->name != NULL; ++opcode) | |
593 | { | |
594 | if (opcode->instr_id == derived_code) | |
595 | { | |
596 | if (opcode->instr_id == 0x3D) | |
597 | { | |
598 | if ((grp.bit_no == 0) && (opcode->arg[1] != A_BIT_0)) | |
599 | continue; | |
600 | if ((grp.bit_no == 1) && (opcode->arg[1] != A_BIT_1)) | |
601 | continue; | |
602 | if ((grp.bit_no == 3) && (opcode->arg[0] != 0)) | |
603 | continue; | |
604 | } | |
605 | ||
606 | info->fprintf_func (info->stream, "%s ", opcode->name); | |
607 | ||
608 | actual_operands = 0; | |
609 | ||
610 | if ((grp.flag & SRC) == SRC) | |
611 | actual_operands++; | |
612 | ||
613 | if ((grp.flag & DST) == DST) | |
614 | actual_operands++; | |
615 | ||
616 | /* If Implict FLAG in the Instruction. */ | |
617 | if ((opcode->op_number > actual_operands) | |
618 | && !((grp.flag & SRC) == SRC) && !((grp.flag & DST) == DST)) | |
619 | { | |
620 | for (i = 0; i < opcode->op_number; i++) | |
621 | { | |
622 | if (i == 1 && (opcode->arg[1] != NO_ARG)) | |
623 | info->fprintf_func (info->stream, ","); | |
624 | maxq_print_arg (opcode->arg[i], info, grp); | |
625 | } | |
626 | } | |
627 | ||
628 | /* DST is ABSENT in the grp. */ | |
629 | if ((opcode->op_number > actual_operands) | |
630 | && ((grp.flag & SRC) == SRC)) | |
631 | { | |
632 | maxq_print_arg (opcode->arg[0], info, grp); | |
633 | info->fprintf_func (info->stream, " "); | |
634 | ||
635 | if (opcode->instr_id == 0xA4) | |
636 | info->fprintf_func (info->stream, "LC[0]"); | |
637 | ||
638 | if (opcode->instr_id == 0xA5) | |
639 | info->fprintf_func (info->stream, "LC[1]"); | |
640 | ||
641 | if ((grp.flag & SRC) == SRC) | |
642 | info->fprintf_func (info->stream, ","); | |
643 | } | |
644 | ||
645 | if ((grp.flag & DST) == DST) | |
646 | { | |
647 | if ((grp.flag & BIT_NO) == BIT_NO) | |
648 | { | |
649 | info->fprintf_func (info->stream, " %s.%d", | |
650 | get_reg_name (grp.dst, | |
651 | (type1) 0 /*DST*/), | |
652 | grp.bit_no); | |
653 | } | |
654 | else | |
ca4f2377 AM |
655 | info->fprintf_func (info->stream, " %s", |
656 | get_reg_name (grp.dst, (type1) 0)); | |
7499d566 NC |
657 | } |
658 | ||
659 | /* SRC is ABSENT in the grp. */ | |
660 | if ((opcode->op_number > actual_operands) | |
661 | && ((grp.flag & DST) == DST)) | |
662 | { | |
663 | info->fprintf_func (info->stream, ","); | |
664 | maxq_print_arg (opcode->arg[1], info, grp); | |
665 | info->fprintf_func (info->stream, " "); | |
666 | } | |
667 | ||
668 | if ((grp.flag & SRC) == SRC) | |
669 | { | |
670 | if ((grp.flag & DST) == DST) | |
671 | info->fprintf_func (info->stream, ","); | |
672 | ||
673 | if ((grp.flag & BIT_NO) == BIT_NO) | |
674 | { | |
675 | format = opcode->format; | |
676 | ||
677 | if ((grp.flag & FORMAT) == FORMAT) | |
678 | format = grp.fbit; | |
679 | if (format == 1) | |
680 | info->fprintf_func (info->stream, " %s.%d", | |
681 | get_reg_name (grp.src, | |
682 | (type1) 1 /*SRC*/), | |
683 | grp.bit_no); | |
684 | if (format == 0) | |
685 | info->fprintf_func (info->stream, " #%02xh.%d", | |
ca4f2377 | 686 | grp.src, grp.bit_no); |
7499d566 NC |
687 | } |
688 | else | |
689 | { | |
690 | format = opcode->format; | |
691 | ||
692 | if ((grp.flag & FORMAT) == FORMAT) | |
693 | format = grp.fbit; | |
694 | if (format == 1) | |
695 | info->fprintf_func (info->stream, " %s", | |
ca4f2377 AM |
696 | get_reg_name (grp.src, |
697 | (type1) 1 /*SRC*/)); | |
7499d566 NC |
698 | if (format == 0) |
699 | info->fprintf_func (info->stream, " #%02xh", | |
ca4f2377 | 700 | (grp.src)); |
7499d566 NC |
701 | } |
702 | } | |
703 | ||
704 | return 2; | |
705 | } | |
706 | } | |
707 | ||
708 | info->fprintf_func (info->stream, "Unable to Decode : %02x %02x", | |
ca4f2377 | 709 | insn[0], insn[1]); |
7499d566 NC |
710 | return 2; |
711 | } | |
712 | ||
713 | int | |
714 | print_insn_maxq_little (bfd_vma memaddr, struct disassemble_info *info) | |
715 | { | |
716 | return print_insn (memaddr, info, BFD_ENDIAN_LITTLE); | |
717 | } |