1 /* Disassemble Zylin ZPU instructions.
2 Copyright 1995, 1998, 2000, 2001, 2002 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 #include "sysdep.h"
20 #define STATIC_TABLE
21 #define DEFINE_TABLE
22
23 #include "opcode/zpu.h"
24 #include "zpu-opc.h"
25 #include "dis-asm.h"
26
27 static fprintf_ftype fpr;
28 static void *stream;
29 static struct disassemble_info *local_info;
30
31
32
33
34
35 #define GETINFO(size,type,pcrel)\
36 case ADDR_PCREL: size = 0;type=-1;pcrel=1;break;\
37 case ADDR_IMMEDIATE: size = 0;type=-1;pcrel=0;break;\
38 case ADDR_IMPLIED: size = 0;type=-1;pcrel=0;break;\
39
40
41
42 static void print_operand PARAMS ((int, char *, unsigned int *));
43
44 static void
print_operand(lookup,format,args)45 print_operand (lookup, format, args)
46 int lookup;
47 char *format;
48 unsigned int *args;
49 {
50 int val;
51 int c;
52
53 while (*format)
54 {
55 switch (c = *format++)
56 {
57 case '$':
58 val = args[(*format++) - '0'];
59 if (lookup)
60 {
61 #if 0
62 name = findname (val);
63 if (name)
64 fpr (stream, "%s", name);
65 else
66 #endif
67 local_info->print_address_func (val, local_info);
68 }
69 else
70 fpr (stream, "0x%x", val);
71
72 break;
73 default:
74 fpr (stream, "%c", c);
75 break;
76 }
77 }
78 }
79
80 int
print_insn_zpu(memaddr,info)81 print_insn_zpu (memaddr, info)
82 bfd_vma memaddr;
83 struct disassemble_info *info;
84 {
85 int status = 0;
86 unsigned char insn[4];
87 const struct zpu_opcode *op=NULL;
88 int i;
89 int args[2];
90 stream = info->stream;
91 fpr = info->fprintf_func;
92 local_info = info;
93 for (i = 0; i < 4 && status == 0; i++)
94 {
95 status = info->read_memory_func (memaddr + i, insn + i, 1, info);
96 }
97
98 for (i=0; i<zpu_num_opcodes; i++)
99 {
100 if ((zpu_opcodes[i].code==insn[0])||((zpu_opcodes[i].code&insn[0]&0x80)!=0))
101 {
102 op=zpu_opcodes+i;
103 break;
104 }
105 }
106
107 if ((insn[0]>=ZPU_storesp)&&(insn[0]<ZPU_storesp+32))
108 {
109 fpr (stream, "storesp %d", ((insn[0]-ZPU_storesp)^0x10)*4);
110 } else if ((insn[0]>=ZPU_loadsp)&&(insn[0]<ZPU_loadsp+32))
111 {
112 fpr (stream, "loadsp %d", ((insn[0]-ZPU_loadsp)^0x10)*4);
113 } else
114 {
115 switch (insn[0])
116 {
117 case ZPU_addsp:
118 case ZPU_addsp+1:
119 case ZPU_addsp+2:
120 case ZPU_addsp+3:
121 case ZPU_addsp+4:
122 case ZPU_addsp+5:
123 case ZPU_addsp+6:
124 case ZPU_addsp+7:
125 case ZPU_addsp+8:
126 case ZPU_addsp+9:
127 case ZPU_addsp+10:
128 case ZPU_addsp+11:
129 case ZPU_addsp+12:
130 case ZPU_addsp+13:
131 case ZPU_addsp+14:
132 case ZPU_addsp+15:
133 fpr (stream, "addsp %d", (insn[0]-ZPU_addsp)*4);
134 break;
135
136
137
138 default:
139 if (op==NULL)
140 {
141 fpr (stream, ".byte %d", insn[0]);
142 } else if ((insn[0]&0x80)!=0)
143 {
144 int t;\
145 t=(int)((signed char)((insn[0]<<1)&0xff));\
146 t>>=1;\
147
148 fpr (stream, "im %d", t);
149 } else
150 {
151 fpr (stream, "%s", op->name);
152
153 /* Prepare all the posible operand values. */
154 {
155 int size=1;
156 switch (op->amode)
157 {
158 case ADDR_IMMEDIATE:
159 {
160 int t;
161 t=(int)((signed char)((insn[0]<<1)&0xff));
162 t>>=1;
163 args[0] = t;
164 print_operand (0, " $0", args);
165 size += 0;
166 }
167 break;
168 case ADDR_IMPLIED:
169 size += 0;
170 break;
171 }
172 }
173 }
174 break;
175 }
176 }
177 return 1; // size is always 1
178 }
179