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