OSDN Git Service

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