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.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
26 #include "opcode/h8300.h"
30 static struct h8_opcode
* h8_opcodes_sorted
[256][MAXSAME
];
32 /* Run through the opcodes and sort them into order to make them easy
36 DEFUN_VOID(bfd_h8_disassemble_init
)
41 for (p
= h8_opcodes
; p
->name
; p
++) {
47 if ((int)p
->data
.nib
[0] < 16) {
48 n1
=(int) p
->data
.nib
[0] ;
50 if ((int)p
->data
.nib
[1] < 16) {
51 n2
= (int) p
->data
.nib
[1];
54 for (i
= 0; i
< MAXSAME
; i
++) {
56 if (h8_opcodes_sorted
[j
][i
] == (struct h8_opcode
*)NULL
) {
57 h8_opcodes_sorted
[j
][i
] = p
;
62 if (i
==MAXSAME
)abort();
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
++) ;
68 if (i
/2 != p
->length
) abort();
70 for (i
= 0; i
< 256; i
++)
72 if (h8_opcodes_sorted
[i
][0])
73 p
= h8_opcodes_sorted
[i
][0];
74 else h8_opcodes_sorted
[i
][0] = p
;
80 DEFUN(bfd_h8_disassemble
,(addr
, data
, stream
),
82 CONST bfd_byte
*data AND
85 /* Find the first entry in the table for this opcode */
86 CONST
static char *regnames
[] = {
87 "r0h","r1h","r2h","r3h","r4h","r5h","r6h","r7h",
88 "r0l","r1l","r2l","r3l","r4l","r5l","r6l","r7l" };
94 struct h8_opcode
**p
= h8_opcodes_sorted
[(unsigned)(data
[0])];
97 /* Find the exact opcode/arg combo */
100 unsigned int len
= 0;
104 op_type looking_for
= *nib
;
105 int thisnib
= data
[len
>>1] ;
106 thisnib
= (len
& 1) ? (thisnib
& 0xf) : ((thisnib
>> 4) & 0xf);
107 if ((int)looking_for
& (int)B31
) {
108 if (((int)thisnib
& 0x8) ==0) goto fail
;
109 looking_for
= (op_type
)((int)looking_for
& ~(int)B31
);
111 if ((int)looking_for
& (int)B30
) {
112 if (((int)thisnib
& 0x8) !=0) goto fail
;
113 looking_for
= (op_type
)((int)looking_for
& ~(int)B30
);
115 switch (looking_for
) {
116 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
117 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
118 if ((int)looking_for
!= thisnib
) goto fail
;
125 abs
= (data
[len
>>1]) * 256 + data
[(len
+2)>>1];
133 abs
= thisnib
== 0x8 ? 2:1;
160 fprintf(stream
, "Dont understand \n");
171 fprintf(stream
, "%02x %02x .word\tH'%x,H'%x",
178 for (i
= 0; i
< q
->length
; i
++) {
179 fprintf(stream
, "%02x ", data
[i
]);
182 fprintf(stream
, " ");
185 fprintf(stream
, "%s\t",q
->name
);
186 /* Now print out the args */
188 op_type
*args
= q
->args
.nib
;
192 fprintf(stream
, ",");
193 switch ((int)(*args
) & ~((int)B30
|(int)B31
)) {
197 fprintf(stream
, "#0x%x", (unsigned)abs
);
200 fprintf(stream
, "%s", regnames
[rd
]);
203 fprintf(stream
, "%s",regnames
[rs
]);
206 fprintf(stream
, "r%d", rd
& 0x7);
209 fprintf(stream
, "r%d", rs
& 0x7);
212 fprintf(stream
, "@r%d+", rs
& 0x7);
215 fprintf(stream
, "@-r%d", rd
& 0x7);
218 fprintf(stream
, "@r%d", rd
& 0x7);
221 fprintf(stream
, "@r%d",rs
& 0x7);
227 fprintf(stream
, "@0x%x", (unsigned)abs
);
230 fprintf(stream
, "@@%d (%x)",abs
, abs
);
233 fprintf(stream
, ".%s%d (%x)",(char)abs
>0 ? "+" :"", (char)abs
,
238 fprintf(stream
, "@(0x%x,r%d)", abs
, rdisp
& 0x7);
241 fprintf(stream
, "ccr");
244 fprintf(stream
, "#%d",abs
);
258 unsigned int DEFUN(print_insn_h8300
,(addr
, data
, file
),
265 bfd_h8_disassemble_init();
269 return bfd_h8_disassemble(addr
, (bfd_byte
*)data
, file
);
273 Relocations for the H8
276 static bfd_reloc_status_type
277 DEFUN(howto16_callback
,(abfd
, reloc_entry
, symbol_in
, data
, ignore_input_section
),
279 arelent
*reloc_entry AND
280 asymbol
*symbol_in AND
281 unsigned char *data AND
282 asection
*ignore_input_section
)
285 bfd_vma addr
= reloc_entry
->address
;
286 long x
= bfd_get_16(abfd
, (bfd_byte
*)data
+ addr
);
288 HOWTO_PREPARE(relocation
, symbol_in
);
290 x
= (x
+ relocation
+ reloc_entry
->addend
);
292 bfd_put_16(abfd
, x
, (bfd_byte
*)data
+ addr
);
297 static bfd_reloc_status_type
298 DEFUN(howto8_callback
,(abfd
, reloc_entry
, symbol_in
, data
, ignore_input_section
),
300 arelent
*reloc_entry AND
301 asymbol
*symbol_in AND
302 unsigned char *data AND
303 asection
*ignore_input_section
)
306 bfd_vma addr
= reloc_entry
->address
;
307 long x
= bfd_get_8(abfd
, (bfd_byte
*)data
+ addr
);
309 HOWTO_PREPARE(relocation
, symbol_in
);
311 x
= (x
+ relocation
+ reloc_entry
->addend
);
313 bfd_put_8(abfd
, x
, (bfd_byte
*)data
+ addr
);
318 static bfd_reloc_status_type
319 DEFUN(howto8_FFnn_callback
,(abfd
, reloc_entry
, symbol_in
, data
, ignore_input_section
),
321 arelent
*reloc_entry AND
322 asymbol
*symbol_in AND
323 unsigned char *data AND
324 asection
*ignore_input_section
)
327 bfd_vma addr
= reloc_entry
->address
;
329 long x
= bfd_get_8(abfd
, (bfd_byte
*)data
+ addr
);
331 HOWTO_PREPARE(relocation
, symbol_in
);
333 x
= (x
+ relocation
+ reloc_entry
->addend
);
335 bfd_put_8(abfd
, x
, (bfd_byte
*)data
+ addr
);
339 static bfd_reloc_status_type
340 DEFUN(howto8_pcrel_callback
,(abfd
, reloc_entry
, symbol_in
, data
, ignore_input_section
),
342 arelent
*reloc_entry AND
343 asymbol
*symbol_in AND
344 unsigned char *data AND
345 asection
*ignore_input_section
)
348 bfd_vma addr
= reloc_entry
->address
;
349 long x
= bfd_get_8(abfd
, (bfd_byte
*)data
+ addr
);
351 HOWTO_PREPARE(relocation
, symbol_in
);
353 x
= (x
+ relocation
+ reloc_entry
->addend
);
355 bfd_put_8(abfd
, x
, (bfd_byte
*)data
+ addr
);
360 static reloc_howto_type howto_16
361 = NEWHOWTO(howto16_callback
,"abs16",1,0,0);
362 static reloc_howto_type howto_8
363 = NEWHOWTO(howto8_callback
,"abs8",0,0,0);
365 static reloc_howto_type howto_8_FFnn
366 = NEWHOWTO(howto8_FFnn_callback
,"ff00+abs8",0,0,0);
368 static reloc_howto_type howto_8_pcrel
369 = NEWHOWTO(howto8_pcrel_callback
,"pcrel8",0,1,1);
373 static CONST
struct reloc_howto_struct
*
374 DEFUN(local_bfd_reloc_type_lookup
,(arch
, code
),
375 CONST
struct bfd_arch_info
*arch AND
376 bfd_reloc_code_type code
)
381 case BFD_RELOC_8_FFnn
:
382 return &howto_8_FFnn
;
385 case BFD_RELOC_8_PCREL
:
386 return &howto_8_pcrel
;
388 return (reloc_howto_type
*)NULL
;
391 int bfd_default_scan_num_mach();
394 DEFUN(h8300_scan
,(info
, string
),
395 CONST
struct bfd_arch_info
*info AND
398 if (strcmp(string
,"h8300") == 0) return true;
399 if (strcmp(string
,"H8300") == 0) return true;
400 if (strcmp(string
,"h8/300") == 0) return true;
401 if (strcmp(string
,"H8/300") == 0) return true;
405 static bfd_arch_info_type arch_info_struct
=
407 16, /* 16 bits in a word */
408 16, /* 16 bits in an address */
409 8, /* 8 bits in a byte */
411 0, /* only 1 machine */
412 "H8/300", /* arch_name */
413 "H8/300", /* printable name */
414 true, /* the default machine */
415 bfd_default_compatible
,
418 local_bfd_reloc_type_lookup
,
423 DEFUN_VOID(bfd_h8300_arch
)
425 bfd_arch_linkin(&arch_info_struct
);