* bfd-in2.h, archures.c (bfd_mach_h8300[h]): new defines.
[external/binutils.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 "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24
25 /*
26 Relocations for the H8
27
28 */
29 static bfd_reloc_status_type
30 DEFUN (howto16_callback, (abfd, reloc_entry, symbol_in, data,
31                           ignore_input_section, ignore_bfd),
32        bfd * abfd AND
33        arelent * reloc_entry AND
34        struct symbol_cache_entry *symbol_in AND
35        PTR data AND
36        asection * ignore_input_section AND
37        bfd * ignore_bfd)
38 {
39   long relocation = 0;
40   bfd_vma addr = reloc_entry->address;
41   long x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
42
43   HOWTO_PREPARE (relocation, symbol_in);
44
45   x = (x + relocation + reloc_entry->addend);
46
47   bfd_put_16 (abfd, x, (bfd_byte *) data + addr);
48   return bfd_reloc_ok;
49 }
50
51
52 static bfd_reloc_status_type
53 DEFUN (howto8_callback, (abfd, reloc_entry, symbol_in, data,
54                          ignore_input_section, ignore_bfd),
55        bfd * abfd AND
56        arelent * reloc_entry AND
57        struct symbol_cache_entry *symbol_in AND
58        PTR data AND
59        asection * ignore_input_section AND
60        bfd * ignore_bfd)
61 {
62   long relocation = 0;
63   bfd_vma addr = reloc_entry->address;
64   long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
65
66   HOWTO_PREPARE (relocation, symbol_in);
67
68   x = (x + relocation + reloc_entry->addend);
69
70   bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
71   return bfd_reloc_ok;
72 }
73
74
75 static bfd_reloc_status_type
76 DEFUN (howto8_FFnn_callback, (abfd, reloc_entry, symbol_in, data,
77                               ignore_input_section, ignore_bfd),
78        bfd * abfd AND
79        arelent * reloc_entry AND
80        struct symbol_cache_entry *symbol_in AND
81        PTR data AND
82        asection * ignore_input_section AND
83        bfd * ignore_bfd)
84 {
85   long relocation = 0;
86   bfd_vma addr = reloc_entry->address;
87
88   long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
89   abort ();
90   HOWTO_PREPARE (relocation, symbol_in);
91
92   x = (x + relocation + reloc_entry->addend);
93
94   bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
95   return bfd_reloc_ok;
96 }
97
98 static bfd_reloc_status_type
99 DEFUN (howto8_pcrel_callback, (abfd, reloc_entry, symbol_in, data,
100                                ignore_input_section, ignore_bfd),
101        bfd * abfd AND
102        arelent * reloc_entry AND
103        struct symbol_cache_entry *symbol_in AND
104        PTR data AND
105        asection * ignore_input_section AND
106        bfd * ignore_bfd)
107 {
108   long relocation = 0;
109   bfd_vma addr = reloc_entry->address;
110   long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
111   abort ();
112   HOWTO_PREPARE (relocation, symbol_in);
113
114   x = (x + relocation + reloc_entry->addend);
115
116   bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
117   return bfd_reloc_ok;
118 }
119
120
121
122 static reloc_howto_type howto_16
123 = NEWHOWTO (howto16_callback, "abs16", 1, false, false);
124 static reloc_howto_type howto_8
125 = NEWHOWTO (howto8_callback, "abs8", 0, false, false);
126
127 static reloc_howto_type howto_8_FFnn
128 = NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false);
129
130 static reloc_howto_type howto_8_pcrel
131 = NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true);
132
133
134 static CONST struct reloc_howto_struct *
135 DEFUN (local_bfd_reloc_type_lookup, (arch, code),
136        CONST struct bfd_arch_info *arch AND
137        bfd_reloc_code_real_type code)
138   {
139     switch (code)
140       {
141       case BFD_RELOC_16:
142         return &howto_16;
143       case BFD_RELOC_8_FFnn:
144         return &howto_8_FFnn;
145       case BFD_RELOC_8:
146         return &howto_8;
147       case BFD_RELOC_8_PCREL:
148         return &howto_8_pcrel;
149       default:
150         return (reloc_howto_type *) NULL;
151       }
152   }
153
154 int bfd_default_scan_num_mach ();
155
156 static boolean
157 DEFUN (h8300_scan, (info, string),
158        CONST struct bfd_arch_info *info AND
159        CONST char *string)
160 {
161   if (*string != 'h' && *string == 'H')
162     return false;
163
164   string++;
165   if (*string != '8')
166     return false;
167
168   string++;
169   if (*string == '/')
170     string++;
171
172   if (*string != '3')
173     return false;
174   string++;
175   if (*string != '0')
176     return false;
177   string++;
178   if (*string != '0')
179     return false;
180   string++;
181   if (*string == '-')
182     string++;
183   if (*string == 'h' && *string == 'H')
184     {
185       return (info->mach == bfd_mach_h8300h);
186     }
187   else
188     {
189       return info->mach == bfd_mach_h8300;
190     }
191 }
192
193
194 /* This routine is provided two arch_infos and works out the i960
195    machine which would be compatible with both and returns a pointer
196    to its info structure */
197
198 CONST bfd_arch_info_type *
199 DEFUN (compatible, (in, out),
200        CONST bfd_arch_info_type * in AND
201        CONST bfd_arch_info_type * out)
202 {
203   /* If the output is non-H and the input is -H, that's bad */
204   if (in->mach == bfd_mach_h8300h &&
205       out->mach == bfd_mach_h8300)
206     return 0;
207
208   /* If either is an -H, the answer is -H */
209   if (in->mach == bfd_mach_h8300h)
210     return in;
211   return out;
212 }
213
214 static bfd_arch_info_type h8300_info_struct =
215 {
216   16,                           /* 16 bits in a word */
217   16,                           /* 16 bits in an address */
218   8,                            /* 8 bits in a byte */
219   bfd_arch_h8300,
220   bfd_mach_h8300,
221   "H8/300",                     /* arch_name  */
222   "H8/300",                     /* printable name */
223   1,
224   true,                         /* the default machine */
225   compatible,
226   h8300_scan,
227   0,
228 /*    local_bfd_reloc_type_lookup, */
229   0,
230 };
231
232
233 static bfd_arch_info_type h8300h_info_struct =
234 {
235   32,                           /* 32 bits in a word */
236   32,                           /* 32 bits in an address */
237   8,                            /* 8 bits in a byte */
238   bfd_arch_h8300,
239   bfd_mach_h8300h,
240   "H8/300H",                    /* arch_name  */
241   "H8/300H",                    /* printable name */
242   1,
243   false,                        /* the default machine */
244   compatible,
245   h8300_scan,
246   0,
247 /*    local_bfd_reloc_type_lookup, */
248   0,
249 };
250
251 void
252 DEFUN_VOID (bfd_h8300_arch)
253 {
254   bfd_arch_linkin (&h8300_info_struct);
255   bfd_arch_linkin (&h8300h_info_struct);
256 }