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