More portability patches. Include sysdep.h everywhere.
[external/binutils.git] / opcodes / h8500-dis.c
1 /* Disassemble h8500 instructions.
2    Copyright (C) 1993, 94, 95, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #include <stdio.h>
19
20 #define DISASSEMBLER_TABLE
21 #define DEFINE_TABLE
22
23 #include "sysdep.h"
24 #include "h8500-opc.h"
25 #include "dis-asm.h"
26 #include "opintl.h"
27
28 /* Maximum length of an instruction.  */
29 #define MAXLEN 8
30
31 #include <setjmp.h>
32
33 struct private
34 {
35   /* Points to first byte not fetched.  */
36   bfd_byte *max_fetched;
37   bfd_byte the_buffer[MAXLEN];
38   bfd_vma insn_start;
39   jmp_buf bailout;
40 };
41
42 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
43    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
44    on error.  */
45 #define FETCH_DATA(info, addr) \
46   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
47    ? 1 : fetch_data ((info), (addr)))
48
49 static int
50 fetch_data (info, addr)
51      struct disassemble_info *info;
52      bfd_byte *addr;
53 {
54   int status;
55   struct private *priv = (struct private *) info->private_data;
56   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
57
58   status = (*info->read_memory_func) (start,
59                                       priv->max_fetched,
60                                       addr - priv->max_fetched,
61                                       info);
62   if (status != 0)
63     {
64       (*info->memory_error_func) (status, start, info);
65       longjmp (priv->bailout, 1);
66     }
67   else
68     priv->max_fetched = addr;
69   return 1;
70 }
71
72 static char *crname[] =
73 {"sr", "ccr", "*", "br", "ep", "dp", "*", "tp"};
74
75 int
76 print_insn_h8500 (addr, info)
77      bfd_vma addr;
78      disassemble_info *info;
79 {
80   h8500_opcode_info *opcode;
81   void *stream = info->stream;
82   fprintf_ftype func = info->fprintf_func;
83
84   struct private priv;
85   bfd_byte *buffer = priv.the_buffer;
86
87   info->private_data = (PTR) & priv;
88   priv.max_fetched = priv.the_buffer;
89   priv.insn_start = addr;
90   if (setjmp (priv.bailout) != 0)
91     /* Error return.  */
92     return -1;
93
94 if (0)  {
95     static    int one;
96     if (!one ) 
97       {
98         one = 1;
99         for (opcode = h8500_table; opcode->name; opcode++)
100           {
101             if ((opcode->bytes[0].contents & 0x8) == 0)
102               printf("%s\n", opcode->name);
103           }
104       }
105   }
106
107
108   /* Run down the table to find the one which matches */
109   for (opcode = h8500_table; opcode->name; opcode++)
110     {
111       int byte;
112       int rn = 0;
113       int rd = 0;
114       int rs = 0;
115       int disp = 0;
116       int abs = 0;
117       int imm = 0;
118       int pcrel = 0;
119       int qim = 0;
120       int i;
121       int cr = 0;
122       for (byte = 0; byte < opcode->length; byte++)
123         {
124           FETCH_DATA (info, buffer + byte + 1);
125           if ((buffer[byte] & opcode->bytes[byte].mask)
126               != (opcode->bytes[byte].contents))
127             {
128               goto next;
129             }
130           else
131             {
132               /* extract any info parts */
133               switch (opcode->bytes[byte].insert)
134                 {
135                 case 0:
136                 case FP:
137                   break;
138                 default:
139                   /* xgettext:c-format */
140                   func (stream, _("can't cope with insert %d\n"),
141                         opcode->bytes[byte].insert);
142                   break;
143                 case RN:
144                   rn = buffer[byte] & 0x7;
145                   break;
146                 case RS:
147                   rs = buffer[byte] & 0x7;
148                   break;
149                 case CRB:
150                   cr = buffer[byte] & 0x7;
151                   if (cr == 0)
152                     goto next;
153                   break;
154                 case CRW:
155                   cr = buffer[byte] & 0x7;
156                   if (cr != 0)
157                     goto next;
158                   break;
159                 case DISP16:
160                   FETCH_DATA (info, buffer + byte + 2);
161                   disp = (buffer[byte] << 8) | (buffer[byte + 1]);
162                   break;
163                 case FPIND_D8:
164                 case DISP8:
165                   disp = ((char) (buffer[byte]));
166                   break;
167                 case RD:
168                 case RDIND:
169                   rd = buffer[byte] & 0x7;
170                   break;
171                 case ABS24:
172                   FETCH_DATA (info, buffer + byte + 3);
173                   abs =
174                     (buffer[byte] << 16)
175                     | (buffer[byte + 1] << 8)
176                     | (buffer[byte + 2]);
177                   break;
178                 case ABS16:
179                   FETCH_DATA (info, buffer + byte + 2);
180                   abs = (buffer[byte] << 8) | (buffer[byte + 1]);
181                   break;
182                 case ABS8:
183                   abs = (buffer[byte]);
184                   break;
185                 case IMM16:
186                   FETCH_DATA (info, buffer + byte + 2);
187                   imm = (buffer[byte] << 8) | (buffer[byte + 1]);
188                   break;
189                 case IMM4:
190                   imm = (buffer[byte]) & 0xf;
191                   break;
192                 case IMM8:
193                 case RLIST:
194                   imm = (buffer[byte]);
195                   break;
196                 case PCREL16:
197                   FETCH_DATA (info, buffer + byte + 2);
198                   pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
199                   break;
200                 case PCREL8:
201                   pcrel = (buffer[byte]);
202                   break;
203                 case QIM:
204                   switch (buffer[byte] & 0x7)
205                     {
206                     case 0:
207                       qim = 1;
208                       break;
209                     case 1:
210                       qim = 2;
211                       break;
212                     case 4:
213                       qim = -1;
214                       break;
215                     case 5:
216                       qim = -2;
217                       break;
218                     }
219                   break;
220
221                 }
222             }
223         }
224       /* We get here when all the masks have passed so we can output the
225          operands*/
226       FETCH_DATA (info, buffer + opcode->length);
227       for (i = 0; i < opcode->length; i++)
228         {
229           (func) (stream, "%02x ", buffer[i]);
230         }
231       for (; i < 6; i++)
232         {
233           (func) (stream, "   ");
234         }
235       (func) (stream, "%s\t", opcode->name);
236       for (i = 0; i < opcode->nargs; i++)
237         {
238           if (i)
239             (func) (stream, ",");
240           switch (opcode->arg_type[i])
241             {
242             case FP:
243               func (stream, "fp");
244               break;
245             case RNIND_D16:
246               func (stream, "@(0x%x:16,r%d)", disp, rn);
247               break;
248             case RNIND_D8:
249               func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
250               break;
251             case RDIND_D16:
252               func (stream, "@(0x%x:16,r%d)", disp, rd);
253               break;
254             case RDIND_D8:
255               func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
256               break;
257             case FPIND_D8:
258               func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
259               break;
260             case CRB:
261             case CRW:
262               func (stream, "%s", crname[cr]);
263               break;
264             case RN:
265               func (stream, "r%d", rn);
266               break;
267             case RD:
268               func (stream, "r%d", rd);
269               break;
270             case RS:
271               func (stream, "r%d", rs);
272               break;
273             case RNDEC:
274               func (stream, "@-r%d", rn);
275               break;
276             case RNINC:
277               func (stream, "@r%d+", rn);
278               break;
279             case RNIND:
280               func (stream, "@r%d", rn);
281               break;
282             case RDIND:
283               func (stream, "@r%d", rd);
284               break;
285             case SPINC:
286               func (stream, "@sp+");
287               break;
288             case SPDEC:
289               func (stream, "@-sp");
290               break;
291             case ABS24:
292               func (stream, "@0x%0x:24", abs);
293               break;
294             case ABS16:
295               func (stream, "@0x%0x:16", abs & 0xffff);
296               break;
297             case ABS8:
298               func (stream, "@0x%0x:8", abs & 0xff);
299               break;
300             case IMM16:
301               func (stream, "#0x%0x:16", imm & 0xffff);
302               break;
303             case RLIST:
304               {
305                 int i;
306                 int nc = 0;
307                 func (stream, "(");
308                 for (i = 0; i < 8; i++)
309                   {
310                     if (imm & (1 << i))
311                       {
312                         func (stream, "r%d", i);
313                         if (nc)
314                           func (stream, ",");
315                         nc = 1;
316                       }
317                   }
318                 func (stream, ")");
319               }
320               break;
321             case IMM8:
322               func (stream, "#0x%0x:8", imm & 0xff);
323               break;
324             case PCREL16:
325               func (stream, "0x%0x:16", (pcrel + addr + opcode->length) & 0xffff);
326               break;
327             case PCREL8:
328               func (stream, "#0x%0x:8",
329                     ((char) pcrel + addr + opcode->length) & 0xffff);
330               break;
331             case QIM:
332               func (stream, "#%d:q", qim);
333               break;
334             case IMM4:
335               func (stream, "#%d:4", imm);
336               break;
337             }
338         }
339       return opcode->length;
340     next:;
341     }
342
343   /* Couldn't understand anything */
344   /* xgettext:c-format */
345   func (stream, _("%02x\t\t*unknown*"), buffer[0]);
346   return 1;
347
348 }