146285ec71b3c400ee4728852f0b9a90dde8ef8d
[deliverable/binutils-gdb.git] / bfd / cpu-h8300.c
1 /* BFD library support routines for the Hitachi H8/300 architecture.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Hacked by Steve Chamberlain of Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include <sysdep.h>
22 #include "bfd.h"
23 #include "libbfd.h"
24
25 #define DEFINE_TABLE
26 #include "h8300-opcode.h"
27
28 #define MAXSAME 14
29
30 static struct h8_opcode * h8_opcodes_sorted[256][MAXSAME];
31
32 /* Run through the opcodes and sort them into order to make them easy
33 to disassemble
34 */
35 static void
36 DEFUN_VOID(bfd_h8_disassemble_init)
37 {
38 unsigned int i;
39 struct h8_opcode *p;
40
41 for (p = h8_opcodes; p->name; p++) {
42 int where = 0;
43 int n1 = 0;
44 int n2 = 0;
45 int n3 = 0;
46 int n4= 0;
47 if ((int)p->data.nib[0] < 16) {
48 n1 =(int) p->data.nib[0] ;
49 } else n1 = 0;
50 if ((int)p->data.nib[1] < 16) {
51 n2 = (int) p->data.nib[1];
52 }else n2 = 0;
53
54 for (i = 0; i < MAXSAME; i++) {
55 int j = n1 * 16 + n2;
56 if (h8_opcodes_sorted[j][i] == (struct h8_opcode *)NULL) {
57 h8_opcodes_sorted[j][i] = p;
58 break;
59 }
60 }
61
62 if (i==MAXSAME)abort();
63
64 /* Just make sure there are an even number of nibbles in it, and
65 that the count is the same s the length */
66 for (i = 0; p->data.nib[i] != E; i++) ;
67 if (i & 1) abort();
68 if (i/2 != p->length) abort();
69 }
70 for (i = 0; i < 256; i++)
71 {
72 if (h8_opcodes_sorted[i][0])
73 p = h8_opcodes_sorted[i][0];
74 else h8_opcodes_sorted[i][0] = p;
75 }
76 }
77
78 unsigned int
79 DEFUN(bfd_h8_disassemble,(addr, data, stream),
80 bfd_vma addr AND
81 CONST bfd_byte *data AND
82 FILE *stream)
83 {
84 /* Find the first entry in the table for this opcode */
85 int rs = 0;
86 int rd = 0;
87 int rdisp = 0;
88 int abs = 0;
89 struct h8_opcode **p = h8_opcodes_sorted[(unsigned)(data[0])];
90 struct h8_opcode *q;
91
92 /* Find the exact opcode/arg combo */
93 while (*p) {
94 op_enum_type *nib;
95 unsigned int len = 0;
96 q = *p++;
97 nib =q->data.nib;
98 while (*nib != E) {
99 op_enum_type looking_for = *nib;
100 int thisnib = data[len>>1] ;
101 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
102 if ((int)looking_for & (int)B31) {
103 if (((int)thisnib & 0x8) ==0) goto fail;
104 looking_for = (op_enum_type)((int)looking_for & ~(int)B31);
105 }
106 if ((int)looking_for & (int)B30) {
107 if (((int)thisnib & 0x8) !=0) goto fail;
108 looking_for = (op_enum_type)((int)looking_for & ~(int)B30);
109 }
110 switch (looking_for) {
111 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
112 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
113 if ((int)looking_for != thisnib) goto fail;
114 break;
115 case ABS16SRC:
116 case ABS16DST:
117 case DISPSRC:
118 case DISPDST:
119 case IMM16:
120 abs = (data[len>>1]) * 256 + data[(len+2)>>1];
121 len+=3;
122 nib+=3;
123 break;
124 case DISPREG:
125 rdisp = thisnib;
126 break;
127 case KBIT:
128 abs = thisnib == 0x80 ? 2:1;
129 break;
130 case IMM8:
131 case ABS8SRC:
132 case ABS8DST:
133 case DISP8:
134 abs= data[len>>1];
135 len++;
136 nib++;
137 break;
138 case IMM3:
139 abs = thisnib ;
140 break;
141 case RS8:
142 case RS16:
143 case RSINC:
144 case RSIND:
145 rs = thisnib;
146 break;
147 case RD16:
148 case RDDEC:
149 case RD8:
150 case RDIND:
151 rd = thisnib;
152 break;
153 default:
154 fprintf(stream, "Dont understand \n");
155 goto found;
156 }
157 len++;
158 nib++;
159 }
160 goto found;
161 fail:
162 ;
163
164 }
165 fprintf(stream, "%02x %02x .word\tH'%x,H'%x\n",
166 data[0], data[1],
167 data[0], data[1]);
168 return 2;
169 found:;
170 { int i;
171
172 for (i = 0; i < q->length; i++) {
173 fprintf(stream, "%02x ", data[i]);
174 }
175 for (; i < 6; i++) {
176 fprintf(stream, " ");
177 }
178 }
179 fprintf(stream, "%s\t",q->name);
180 /* Now print out the args */
181 {
182 op_enum_type *args = q->args.nib;
183 int hadone = 0;
184 while (*args != E) {
185 if (hadone)
186 fprintf(stream, ",");
187 switch ((int)(*args) & ~((int)B30|(int)B31)) {
188 case IMM16:
189 case IMM8:
190 case IMM3:
191 fprintf(stream, "#H'%x", (unsigned)abs); break;
192 case RD8:
193 fprintf(stream, "r%d%c", rd/2, rd & 1 ? 'l' : 'h'); break;
194 case RS8:
195 fprintf(stream, "r%d%c", rs/2, rs & 1 ? 'l' : 'h'); break;
196 case RD16:
197 fprintf(stream, "r%d", rd& 0x7); break;
198 case RS16:
199 fprintf(stream, "r%d", rs & 0x7); break;
200 case RSINC:
201 fprintf(stream, "@r%d+", rs & 0x7); break;
202 case RDDEC:
203 fprintf(stream, "@-r%d", rd & 0x7); break;
204 case RDIND:
205 fprintf(stream, "@r%d", rd & 0x7); break;
206 case RSIND:
207 fprintf(stream, "@r%d",rs & 0x7); break;
208 case ABS8SRC:
209 case ABS16SRC:
210 case ABS16DST:
211 case ABS8DST:
212 fprintf(stream, "@H'%x", (unsigned)abs); break;
213 case DISP8:
214 fprintf(stream, "%d", (char)abs);break;
215 case DISPSRC:
216 case DISPDST:
217 fprintf(stream, "@(%d,r%d)", abs, rdisp & 0x7); break;
218 case CCR:
219 fprintf(stream, "ccr"); break;
220 case KBIT:
221 fprintf(stream, "#%d",abs); break;
222 default:
223 abort();
224 }
225 hadone = 1;
226 args++;
227 }
228 }
229 return q->length;
230 }
231
232
233
234 unsigned int DEFUN( print_insn_h8300,(addr, data, file),
235 bfd_vma addr AND
236 CONST bfd_byte *data AND
237 PTR file)
238 {
239 static boolean init;
240 if (!init) {
241 bfd_h8_disassemble_init();
242 init= 1;
243
244 }
245 return bfd_h8_disassemble(addr, data, file);
246 }
247
248 /*
249 Relocations for the H8
250
251 */
252 static bfd_reloc_status_enum_type
253 DEFUN(howto16_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
254 bfd *abfd AND
255 arelent *reloc_entry AND
256 asymbol *symbol_in AND
257 unsigned char *data AND
258 asection *ignore_input_section)
259 {
260 long relocation = 0;
261 bfd_vma addr = reloc_entry->address;
262 long x = bfd_get_16(abfd, (bfd_byte *)data + addr);
263
264 HOWTO_PREPARE(relocation, symbol_in);
265
266 x = (x + relocation + reloc_entry->addend);
267
268 bfd_put_16(abfd, x, (bfd_byte *)data + addr);
269 return bfd_reloc_ok;
270 }
271
272
273 static bfd_reloc_status_enum_type
274 DEFUN(howto8_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
275 bfd *abfd AND
276 arelent *reloc_entry AND
277 asymbol *symbol_in AND
278 unsigned char *data AND
279 asection *ignore_input_section)
280 {
281 long relocation = 0;
282 bfd_vma addr = reloc_entry->address;
283 long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
284
285 HOWTO_PREPARE(relocation, symbol_in);
286
287 x = (x + relocation + reloc_entry->addend);
288
289 bfd_put_8(abfd, x, (bfd_byte *)data + addr);
290 return bfd_reloc_ok;
291 }
292
293
294 static bfd_reloc_status_enum_type
295 DEFUN(howto8_FFnn_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
296 bfd *abfd AND
297 arelent *reloc_entry AND
298 asymbol *symbol_in AND
299 unsigned char *data AND
300 asection *ignore_input_section)
301 {
302 long relocation = 0;
303 bfd_vma addr = reloc_entry->address;
304
305 long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
306 abort();
307 HOWTO_PREPARE(relocation, symbol_in);
308
309 x = (x + relocation + reloc_entry->addend);
310
311 bfd_put_8(abfd, x, (bfd_byte *)data + addr);
312 return bfd_reloc_ok;
313 }
314
315 static bfd_reloc_status_enum_type
316 DEFUN(howto8_pcrel_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
317 bfd *abfd AND
318 arelent *reloc_entry AND
319 asymbol *symbol_in AND
320 unsigned char *data AND
321 asection *ignore_input_section)
322 {
323 long relocation = 0;
324 bfd_vma addr = reloc_entry->address;
325 long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
326 abort();
327 HOWTO_PREPARE(relocation, symbol_in);
328
329 x = (x + relocation + reloc_entry->addend);
330
331 bfd_put_8(abfd, x, (bfd_byte *)data + addr);
332 return bfd_reloc_ok;
333 }
334
335
336 static reloc_howto_type howto_16
337 = NEWHOWTO(howto16_callback,"abs16",1,0);
338 static reloc_howto_type howto_8
339 = NEWHOWTO(howto8_callback,"abs8",0,0);
340
341 static reloc_howto_type howto_8_FFnn
342 = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,0);
343
344 static reloc_howto_type howto_8_pcrel
345 = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,1);
346
347
348
349 static CONST struct reloc_howto_struct *DEFUN(local_bfd_reloc_type_lookup,( code),
350 bfd_reloc_code_enum_type code)
351 {
352 switch (code) {
353 case BFD_RELOC_16:
354 return &howto_16;
355 case BFD_RELOC_8_FFnn:
356 return &howto_8_FFnn;
357 case BFD_RELOC_8:
358 return &howto_8;
359 case BFD_RELOC_8_PCREL:
360 return &howto_8_pcrel;
361 }
362 return (reloc_howto_type *)NULL;
363 }
364
365 int bfd_default_scan_num_mach();
366
367 static bfd_arch_info_struct_type arch_info_struct =
368 {
369 16, /* 16 bits in a word */
370 16, /* 16 bits in an address */
371 8, /* 8 bits in a byte */
372 bfd_arch_h8300,
373 0, /* only 1 machine */
374 "H8/300", /* arch_name */
375 "H8/300", /* printable name */
376 true, /* the default machine */
377 bfd_default_compatible,
378 bfd_default_scan,
379 print_insn_h8300,
380 local_bfd_reloc_type_lookup,
381 0,
382 };
383
384
385
386
387 void DEFUN_VOID(bfd_h8300_arch)
388 {
389 bfd_arch_linkin(&arch_info_struct);
390 }
391
392
393
This page took 0.054634 seconds and 3 git commands to generate.