]> Git Repo - binutils.git/blob - opcodes/m10200-dis.c
NS32K arg_bufs uninitialised
[binutils.git] / opcodes / m10200-dis.c
1 /* Disassemble MN10200 instructions.
2    Copyright (C) 1996-2020 Free Software Foundation, Inc.
3
4    This file is part of the GNU opcodes library.
5
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include "opcode/mn10200.h"
24 #include "disassemble.h"
25 #include "opintl.h"
26
27 static void
28 disassemble (bfd_vma memaddr,
29              struct disassemble_info *info,
30              unsigned long insn,
31              unsigned long extension,
32              unsigned int size)
33 {
34   struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes;
35   const struct mn10200_operand *operand;
36   int match = 0;
37
38   /* Find the opcode.  */
39   while (op->name)
40     {
41       int mysize, extra_shift;
42
43       if (op->format == FMT_1)
44         mysize = 1;
45       else if (op->format == FMT_2
46                || op->format == FMT_4)
47         mysize = 2;
48       else if (op->format == FMT_3
49                || op->format == FMT_5)
50         mysize = 3;
51       else if (op->format == FMT_6)
52         mysize = 4;
53       else if (op->format == FMT_7)
54         mysize = 5;
55       else
56         abort ();
57
58       if (op->format == FMT_2 || op->format == FMT_5)
59         extra_shift = 8;
60       else if (op->format == FMT_3
61                || op->format == FMT_6
62                || op->format == FMT_7)
63         extra_shift = 16;
64       else
65         extra_shift = 0;
66
67       if ((op->mask & insn) == op->opcode
68           && size == (unsigned int) mysize)
69         {
70           const unsigned char *opindex_ptr;
71           unsigned int nocomma;
72           int paren = 0;
73
74           match = 1;
75           (*info->fprintf_func) (info->stream, "%s\t", op->name);
76
77           /* Now print the operands.  */
78           for (opindex_ptr = op->operands, nocomma = 1;
79                *opindex_ptr != 0;
80                opindex_ptr++)
81             {
82               unsigned long value;
83
84               operand = &mn10200_operands[*opindex_ptr];
85
86               if ((operand->flags & MN10200_OPERAND_DREG) != 0
87                   || (operand->flags & MN10200_OPERAND_AREG) != 0)
88                 value = ((insn >> (operand->shift + extra_shift))
89                          & ((1 << operand->bits) - 1));
90               else if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0)
91                 {
92                   value = (insn & 0xffff) << 8;
93                   value |= extension;
94                 }
95               else
96                 value = ((insn >> (operand->shift))
97                          & ((1L << operand->bits) - 1L));
98
99               if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
100                 value = ((long)(value << (32 - operand->bits))
101                           >> (32 - operand->bits));
102
103               if (!nocomma
104                   && (!paren
105                       || ((operand->flags & MN10200_OPERAND_PAREN) == 0)))
106                 (*info->fprintf_func) (info->stream, ",");
107
108               nocomma = 0;
109
110               if ((operand->flags & MN10200_OPERAND_DREG) != 0)
111                 (*info->fprintf_func) (info->stream, "d%ld", value);
112
113               else if ((operand->flags & MN10200_OPERAND_AREG) != 0)
114                 (*info->fprintf_func) (info->stream, "a%ld", value);
115
116               else if ((operand->flags & MN10200_OPERAND_PSW) != 0)
117                 (*info->fprintf_func) (info->stream, "psw");
118
119               else if ((operand->flags & MN10200_OPERAND_MDR) != 0)
120                 (*info->fprintf_func) (info->stream, "mdr");
121
122               else if ((operand->flags & MN10200_OPERAND_PAREN) != 0)
123                 {
124                   if (paren)
125                     (*info->fprintf_func) (info->stream, ")");
126                   else
127                     {
128                       (*info->fprintf_func) (info->stream, "(");
129                       nocomma = 1;
130                     }
131                   paren = !paren;
132                 }
133
134               else if ((operand->flags & MN10200_OPERAND_PCREL) != 0)
135                 (*info->print_address_func)
136                   ((value + memaddr + mysize) & 0xffffff, info);
137
138               else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0)
139                 (*info->print_address_func) (value, info);
140
141               else
142                 (*info->fprintf_func) (info->stream, "%ld", value);
143             }
144           /* All done. */
145           break;
146         }
147       op++;
148     }
149
150   if (!match)
151     (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
152 }
153
154 int
155 print_insn_mn10200 (bfd_vma memaddr, struct disassemble_info *info)
156 {
157   int status;
158   bfd_byte buffer[4];
159   unsigned long insn;
160   unsigned long extension = 0;
161   unsigned int consume;
162
163   /* First figure out how big the opcode is.  */
164   status = (*info->read_memory_func) (memaddr, buffer, 1, info);
165   if (status != 0)
166     {
167       (*info->memory_error_func) (status, memaddr, info);
168       return -1;
169     }
170
171   insn = *(unsigned char *) buffer;
172
173   /* These are one byte insns.  */
174   if ((insn & 0xf0) == 0x00
175       || (insn & 0xf0) == 0x10
176       || (insn & 0xf0) == 0x20
177       || (insn & 0xf0) == 0x30
178       || ((insn & 0xf0) == 0x80
179           && (insn & 0x0c) >> 2 != (insn & 0x03))
180       || (insn & 0xf0) == 0x90
181       || (insn & 0xf0) == 0xa0
182       || (insn & 0xf0) == 0xb0
183       || (insn & 0xff) == 0xeb
184       || (insn & 0xff) == 0xf6
185       || (insn & 0xff) == 0xfe
186       || (insn & 0xff) == 0xff)
187     {
188       extension = 0;
189       consume = 1;
190     }
191
192   /* These are two byte insns.  */
193   else if ((insn & 0xf0) == 0x40
194            || (insn & 0xf0) == 0x50
195            || (insn & 0xf0) == 0x60
196            || (insn & 0xf0) == 0x70
197            || (insn & 0xf0) == 0x80
198            || (insn & 0xfc) == 0xd0
199            || (insn & 0xfc) == 0xd4
200            || (insn & 0xfc) == 0xd8
201            || (insn & 0xfc) == 0xe0
202            || (insn & 0xfc) == 0xe4
203            || (insn & 0xff) == 0xe8
204            || (insn & 0xff) == 0xe9
205            || (insn & 0xff) == 0xea
206            || (insn & 0xff) == 0xf0
207            || (insn & 0xff) == 0xf1
208            || (insn & 0xff) == 0xf2
209            || (insn & 0xff) == 0xf3)
210     {
211       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
212       if (status != 0)
213         {
214           (*info->memory_error_func) (status, memaddr, info);
215            return -1;
216         }
217       insn = bfd_getb16 (buffer);
218       consume = 2;
219     }
220
221   /* These are three byte insns with a 16bit operand in little
222      endian form.  */
223   else if ((insn & 0xf0) == 0xc0
224            || (insn & 0xfc) == 0xdc
225            || (insn & 0xfc) == 0xec
226            || (insn & 0xff) == 0xf8
227            || (insn & 0xff) == 0xf9
228            || (insn & 0xff) == 0xfa
229            || (insn & 0xff) == 0xfb
230            || (insn & 0xff) == 0xfc
231            || (insn & 0xff) == 0xfd)
232     {
233       status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
234       if (status != 0)
235         {
236           (*info->memory_error_func) (status, memaddr, info);
237           return -1;
238         }
239       insn <<= 16;
240       insn |= bfd_getl16 (buffer);
241       extension = 0;
242       consume = 3;
243     }
244   /* These are three byte insns too, but we don't have to mess with
245      endianness stuff.  */
246   else if ((insn & 0xff) == 0xf5)
247     {
248       status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
249       if (status != 0)
250         {
251           (*info->memory_error_func) (status, memaddr, info);
252           return -1;
253         }
254       insn <<= 16;
255       insn |= bfd_getb16 (buffer);
256       extension = 0;
257       consume = 3;
258     }
259
260   /* These are four byte insns.  */
261   else if ((insn & 0xff) == 0xf7)
262     {
263       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
264       if (status != 0)
265         {
266           (*info->memory_error_func) (status, memaddr, info);
267           return -1;
268         }
269       insn = bfd_getb16 (buffer);
270       insn <<= 16;
271       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
272       if (status != 0)
273         {
274           (*info->memory_error_func) (status, memaddr, info);
275           return -1;
276         }
277       insn |= bfd_getl16 (buffer);
278       extension = 0;
279       consume = 4;
280     }
281
282   /* These are five byte insns.  */
283   else if ((insn & 0xff) == 0xf4)
284     {
285       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
286       if (status != 0)
287         {
288           (*info->memory_error_func) (status, memaddr, info);
289           return -1;
290         }
291       insn = bfd_getb16 (buffer);
292       insn <<= 16;
293
294       status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
295       if (status != 0)
296         {
297           (*info->memory_error_func) (status, memaddr, info);
298           return -1;
299         }
300       insn |= (*(unsigned char *)buffer << 8) & 0xff00;
301
302       status = (*info->read_memory_func) (memaddr + 3, buffer, 1, info);
303       if (status != 0)
304         {
305           (*info->memory_error_func) (status, memaddr, info);
306           return -1;
307         }
308       insn |= (*(unsigned char *)buffer) & 0xff;
309
310       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
311       if (status != 0)
312         {
313           (*info->memory_error_func) (status, memaddr, info);
314           return -1;
315         }
316       extension = (*(unsigned char *)buffer) & 0xff;
317       consume = 5;
318     }
319   else
320     {
321       (*info->fprintf_func) (info->stream, _("unknown\t0x%02lx"), insn);
322       return 1;
323     }
324
325   disassemble (memaddr, info, insn, extension, consume);
326
327   return consume;
328 }
This page took 0.057818 seconds and 4 git commands to generate.