* h8300-dis.c, mips-dis.c: Don't use true and false.
[platform/upstream/binutils.git] / opcodes / h8300-dis.c
1 /* Disassemble h8300 instructions.
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 #define DEFINE_TABLE
19
20 #define h8_opcodes h8ops
21 #include "opcode/h8300.h"
22 #include "dis-asm.h"
23
24
25 /* Run through the opcodes and sort them into order to make them easy
26    to disassemble
27  */
28 static void
29 bfd_h8_disassemble_init ()
30 {
31   unsigned int i;
32
33
34   struct h8_opcode *p;
35
36   for (p = h8_opcodes; p->name; p++)
37     {
38       int n1 = 0;
39       int n2 = 0;
40
41       if ((int) p->data.nib[0] < 16)
42         {
43           n1 = (int) p->data.nib[0];
44         }
45       else
46         n1 = 0;
47       if ((int) p->data.nib[1] < 16)
48         {
49           n2 = (int) p->data.nib[1];
50         }
51       else
52         n2 = 0;
53
54       /* Just make sure there are an even number of nibbles in it, and
55          that the count is the same s the length */
56       for (i = 0; p->data.nib[i] != E; i++)
57         /*EMPTY*/ ;
58       if (i & 1)
59         abort ();
60       p->length = i / 2;
61     }
62
63 }
64
65
66 unsigned int
67 bfd_h8_disassemble (addr, info, hmode)
68      bfd_vma addr;
69      disassemble_info *info;
70      int hmode;
71 {
72   /* Find the first entry in the table for this opcode */
73   static CONST char *regnames[] =
74     {
75       "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
76       "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"};
77   
78   static CONST char *wregnames[] =
79     {
80       "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
81       "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
82       };
83   
84   static CONST char *lregnames[] =
85     {
86       "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
87       "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
88       }
89   ;
90
91   int rs = 0;
92   int rd = 0;
93   int rdisp = 0;
94   int abs = 0;
95   int plen = 0;
96   static boolean init = 0;
97   struct h8_opcode *q = h8_opcodes;
98   char CONST **pregnames = hmode ? lregnames : wregnames;
99   int status;
100   int l;
101   
102   unsigned char data[20];  
103   void *stream = info->stream;
104   fprintf_ftype fprintf = info->fprintf_func;
105
106   if (!init)
107     {
108       bfd_h8_disassemble_init ();
109       init = 1;
110     }
111
112   status = info->read_memory_func(addr, data, 2, info);
113   if (status != 0) 
114     {
115       info->memory_error_func(status, addr, info);
116       return -1;
117     }
118   for (l = 2; status == 0 && l < 10; l+=2)
119     {
120       status = info->read_memory_func(addr+l, data+l, 2, info);
121     }
122   
123   
124
125   /* Find the exact opcode/arg combo */
126   while (q->name)
127     {
128       op_type *nib;
129       unsigned int len = 0;
130
131       nib = q->data.nib;
132       
133       while (1)
134         {
135           op_type looking_for = *nib;
136           int thisnib = data[len >> 1];
137           
138           thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
139           
140           if (looking_for < 16 && looking_for >=0) 
141             {
142               
143               if (looking_for != thisnib) 
144                 goto fail;
145             }
146           
147           else 
148             {
149               
150               if ((int) looking_for & (int) B31)
151                 {
152                   if (! (((int) thisnib & 0x8) != 0)) 
153                     goto fail;
154                   looking_for = (op_type) ((int) looking_for & ~(int) B31);
155                 }
156               if ((int) looking_for & (int) B30)
157                 {
158                   if (!(((int) thisnib & 0x8) == 0)) 
159                     goto fail;
160                   looking_for = (op_type) ((int) looking_for & ~(int) B30);
161                 }
162
163               if (looking_for & DBIT)
164                 {
165                   if ((looking_for & 5) != (thisnib &5)) goto fail;
166                   abs = (thisnib & 0x8) ? 2 : 1;
167                 }                 
168               
169               else  if (looking_for & (REG | IND|INC|DEC))
170                 {
171                   if (looking_for & SRC)
172                     {
173                       rs = thisnib;
174                     }
175                   else
176                     {
177                       rd = thisnib;
178                     }
179                 }
180               else if (looking_for & L_16)
181                 {
182                   abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
183                   plen = 16;
184               
185                 }
186               else if(looking_for & ABSJMP)
187                 {
188                   abs =
189                     (data[1] << 16)
190                       | (data[2] << 8)
191                         | (data[3]);
192                 }
193               else if(looking_for & MEMIND)
194                 {
195                   abs = data[1];
196                 }
197               else if (looking_for & L_32)
198                 {
199                   int i = len >> 1;
200                   abs = (data[i] << 24)
201                     | (data[i + 1] << 16)
202                       | (data[i + 2] << 8)
203                         | (data[i+ 3]);
204
205                   plen =32;
206               
207                 }
208               else if (looking_for & L_24)
209                 {
210                   int i = len >> 1;
211                   abs = (data[i] << 16) | (data[i + 1] << 8)|  (data[i+
212                                                                      2]);
213                   plen =24;
214                 }
215               else if (looking_for & IGNORE)
216                 {
217                   
218                 }
219               else if (looking_for & DISPREG)
220                 {
221                   rdisp = thisnib;
222                 }
223               else if (looking_for & KBIT)
224                 {
225                   switch (thisnib) 
226                     {
227                     case 9:
228                       abs = 4;
229                       break;
230                     case 8:
231                       abs = 2;
232                       break;
233                     case 0:
234                       abs = 1;
235                       break;
236                     }
237                 }
238               else if (looking_for & L_8)
239                 {
240                   plen = 8;               
241                   abs = data[len >> 1];
242                 }
243               else if (looking_for & L_3)
244                 {
245                   plen = 3;
246               
247                   abs = thisnib;
248                 }
249               else if (looking_for == E)
250                 {
251
252                   {
253                     int i;
254
255                     for (i = 0; i < q->length; i++)
256                       {
257                         fprintf (stream, "%02x ", data[i]);
258                       }
259                     for (; i < 6; i++)
260                       {
261                         fprintf (stream, "   ");
262                       }
263                   }
264                   fprintf (stream, "%s\t", q->name);
265                   /* Fill in the args */
266                   {
267                     op_type *args = q->args.nib;
268                     int hadone = 0;
269
270
271                     while (*args != E)
272                       {
273                         int x = *args;
274                         if (hadone)
275                           fprintf (stream, ",");
276
277
278                         if (x & (IMM|KBIT|DBIT))
279                           {
280                         
281                             fprintf (stream, "#0x%x", (unsigned) abs);
282                           }
283                         else if (x & REG)
284                           {
285                             int rn = (x & DST) ? rd : rs;
286                             switch (x & SIZE)
287                               {
288                               case L_8:
289                                 fprintf (stream, "%s", regnames[rn]);
290                                 break;
291                               case L_16:
292                                 fprintf (stream, "%s", wregnames[rn]);
293                                 break;
294                               case L_P:
295                               case L_32:
296                                 fprintf (stream, "%s", lregnames[rn]);
297                                 break;
298                     
299                               }
300                           }
301
302                         else if (x & INC)
303                           {
304                             fprintf (stream, "@%s+", pregnames[rs]);
305                           }
306                         else if (x & DEC)
307                           {
308                             fprintf (stream, "@-%s", pregnames[rd]);
309                           }
310
311                         else if (x & IND)
312                           {
313                             int rn = (x & DST) ? rd : rs;
314                             fprintf (stream, "@%s", pregnames[rn]);
315                           }
316
317                         else if (x & (ABS|ABSJMP|ABSMOV))
318                           {
319                             fprintf (stream, "@0x%x:%d", (unsigned) abs, plen);
320                           }
321
322                         else if (x & MEMIND)
323                           {
324                             fprintf (stream, "@@%d (%x)", abs, abs);
325                           }
326
327                         else if (x & PCREL)
328                           {
329                             if (x & L_16)
330                               abs  +=2;
331                             fprintf (stream, ".%s%d (%x)", (char) abs > 0 ? "+" : "", (char) abs,
332                                      addr + (char) abs + 2);
333                           }
334                         else if (x & DISP)
335                           {
336                             fprintf (stream, "@(0x%x:%d,%s)", abs,plen, pregnames[rdisp]);
337                           }
338
339                         else if (x & CCR)
340                           {
341
342                             fprintf (stream, "ccr");
343                           }
344
345                         else
346                           fprintf (stream, "Hmmmm %x", x);
347                         hadone = 1;
348                         args++;
349                       }
350                   }
351                   return q->length;
352                 }
353
354       
355               else
356                 {
357                   fprintf (stream, "Dont understand %x \n", looking_for);
358                 }
359             }
360           
361           len++;
362           nib++;
363         }
364       
365     fail:
366       q++;
367     }
368
369   /* Fell of the end */
370   fprintf (stream, "%02x %02x        .word\tH'%x,H'%x",
371            data[0], data[1],
372            data[0], data[1]);
373   return 2;
374 }
375
376 int 
377 print_insn_h8300 (addr, info)
378 bfd_vma addr; 
379 disassemble_info *info;
380 {
381   return bfd_h8_disassemble (addr, info , 0);
382 }
383
384  int 
385 print_insn_h8300h (addr, info)
386 bfd_vma addr;
387 disassemble_info *info;
388 {
389   return bfd_h8_disassemble (addr, info , 1);
390 }
391