1 |
/* BFD library support routines for the Hitachi H8/300 architecture. |
/* BFD library support routines for the Renesas H8/300 architecture. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, |
3 |
Free Software Foundation, Inc. |
2003, 2004 Free Software Foundation, Inc. |
4 |
Hacked by Steve Chamberlain of Cygnus Support. |
Hacked by Steve Chamberlain of Cygnus Support. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
#include "bfd.h" |
#include "bfd.h" |
23 |
#include "sysdep.h" |
#include "sysdep.h" |
24 |
#include "libbfd.h" |
#include "libbfd.h" |
25 |
|
|
26 |
static boolean h8300_scan |
static bfd_boolean |
27 |
PARAMS ((const struct bfd_arch_info *, const char *)); |
h8300_scan (const struct bfd_arch_info *info, const char *string) |
|
static const bfd_arch_info_type * compatible |
|
|
PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); |
|
|
|
|
|
static boolean |
|
|
h8300_scan (info, string) |
|
|
const struct bfd_arch_info *info; |
|
|
const char *string; |
|
28 |
{ |
{ |
29 |
if (*string != 'h' && *string != 'H') |
if (*string != 'h' && *string != 'H') |
30 |
return false; |
return FALSE; |
31 |
|
|
32 |
string++; |
string++; |
33 |
if (*string != '8') |
if (*string != '8') |
34 |
return false; |
return FALSE; |
35 |
|
|
36 |
string++; |
string++; |
37 |
if (*string == '/') |
if (*string == '/') |
38 |
string++; |
string++; |
39 |
|
|
40 |
if (*string != '3') |
if (*string != '3') |
41 |
return false; |
return FALSE; |
42 |
string++; |
string++; |
43 |
if (*string != '0') |
if (*string != '0') |
44 |
return false; |
return FALSE; |
45 |
string++; |
string++; |
46 |
if (*string != '0') |
if (*string != '0') |
47 |
return false; |
return FALSE; |
48 |
string++; |
string++; |
49 |
if (*string == '-') |
if (*string == '-') |
50 |
string++; |
string++; |
62 |
|
|
63 |
if (*string == 'h' || *string == 'H') |
if (*string == 'h' || *string == 'H') |
64 |
{ |
{ |
65 |
|
string++; |
66 |
|
if (*string == 'n' || *string == 'N') |
67 |
|
return (info->mach == bfd_mach_h8300hn); |
68 |
|
|
69 |
return (info->mach == bfd_mach_h8300h); |
return (info->mach == bfd_mach_h8300h); |
70 |
} |
} |
71 |
else if (*string == 's' || *string == 'S') |
else if (*string == 's' || *string == 'S') |
72 |
{ |
{ |
73 |
|
string++; |
74 |
|
if (*string == 'n' || *string == 'N') |
75 |
|
return (info->mach == bfd_mach_h8300sn); |
76 |
|
|
77 |
|
if (*string == 'x' || *string == 'X') |
78 |
|
{ |
79 |
|
string++; |
80 |
|
if (*string == 'n' || *string == 'N') |
81 |
|
return (info->mach == bfd_mach_h8300sxn); |
82 |
|
|
83 |
|
return (info->mach == bfd_mach_h8300sx); |
84 |
|
} |
85 |
|
|
86 |
return (info->mach == bfd_mach_h8300s); |
return (info->mach == bfd_mach_h8300s); |
87 |
} |
} |
88 |
else |
else |
89 |
{ |
return info->mach == bfd_mach_h8300; |
|
return info->mach == bfd_mach_h8300; |
|
|
} |
|
90 |
} |
} |
91 |
|
|
92 |
/* This routine is provided two arch_infos and works out the machine |
/* This routine is provided two arch_infos and works out the machine |
94 |
info structure. */ |
info structure. */ |
95 |
|
|
96 |
static const bfd_arch_info_type * |
static const bfd_arch_info_type * |
97 |
compatible (in, out) |
compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out) |
|
const bfd_arch_info_type *in; |
|
|
const bfd_arch_info_type *out; |
|
98 |
{ |
{ |
99 |
|
if (in->arch != out->arch) |
100 |
|
return 0; |
101 |
|
if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s) |
102 |
|
return in; |
103 |
|
if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx) |
104 |
|
return out; |
105 |
|
if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn) |
106 |
|
return in; |
107 |
|
if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn) |
108 |
|
return out; |
109 |
/* It's really not a good idea to mix and match modes. */ |
/* It's really not a good idea to mix and match modes. */ |
110 |
if (in->arch != out->arch || in->mach != out->mach) |
if (in->mach != out->mach) |
111 |
return 0; |
return 0; |
112 |
else |
else |
113 |
return in; |
return in; |
114 |
} |
} |
115 |
|
|
116 |
static const bfd_arch_info_type h8300s_info_struct = |
static const bfd_arch_info_type h8300sxn_info_struct = |
117 |
{ |
{ |
118 |
32, /* 32 bits in a word */ |
32, /* 32 bits in a word */ |
119 |
32, /* 32 bits in an address */ |
16, /* 16 bits in an address */ |
120 |
8, /* 8 bits in a byte */ |
8, /* 8 bits in a byte */ |
121 |
bfd_arch_h8300, |
bfd_arch_h8300, |
122 |
bfd_mach_h8300s, |
bfd_mach_h8300sxn, |
123 |
"h8300s", /* arch_name */ |
"h8300sxn", /* arch_name */ |
124 |
"h8300s", /* printable name */ |
"h8300sxn", /* printable name */ |
125 |
1, |
1, |
126 |
false, /* the default machine */ |
FALSE, /* the default machine */ |
127 |
compatible, |
compatible, |
128 |
h8300_scan, |
h8300_scan, |
129 |
0 |
0 |
130 |
}; |
}; |
131 |
|
|
132 |
static const bfd_arch_info_type h8300h_info_struct = |
static const bfd_arch_info_type h8300sx_info_struct = |
133 |
{ |
{ |
134 |
32, /* 32 bits in a word */ |
32, /* 32 bits in a word */ |
135 |
32, /* 32 bits in an address */ |
32, /* 32 bits in an address */ |
136 |
8, /* 8 bits in a byte */ |
8, /* 8 bits in a byte */ |
137 |
bfd_arch_h8300, |
bfd_arch_h8300, |
138 |
|
bfd_mach_h8300sx, |
139 |
|
"h8300sx", /* arch_name */ |
140 |
|
"h8300sx", /* printable name */ |
141 |
|
1, |
142 |
|
FALSE, /* the default machine */ |
143 |
|
compatible, |
144 |
|
h8300_scan, |
145 |
|
&h8300sxn_info_struct |
146 |
|
}; |
147 |
|
|
148 |
|
static const bfd_arch_info_type h8300sn_info_struct = |
149 |
|
{ |
150 |
|
32, /* 32 bits in a word. */ |
151 |
|
16, /* 16 bits in an address. */ |
152 |
|
8, /* 8 bits in a byte. */ |
153 |
|
bfd_arch_h8300, |
154 |
|
bfd_mach_h8300sn, |
155 |
|
"h8300sn", /* Architecture name. */ |
156 |
|
"h8300sn", /* Printable name. */ |
157 |
|
1, |
158 |
|
FALSE, /* The default machine. */ |
159 |
|
compatible, |
160 |
|
h8300_scan, |
161 |
|
&h8300sx_info_struct |
162 |
|
}; |
163 |
|
|
164 |
|
static const bfd_arch_info_type h8300hn_info_struct = |
165 |
|
{ |
166 |
|
32, /* 32 bits in a word. */ |
167 |
|
16, /* 16 bits in an address. */ |
168 |
|
8, /* 8 bits in a byte. */ |
169 |
|
bfd_arch_h8300, |
170 |
|
bfd_mach_h8300hn, |
171 |
|
"h8300hn", /* Architecture name. */ |
172 |
|
"h8300hn", /* Printable name. */ |
173 |
|
1, |
174 |
|
FALSE, /* The default machine. */ |
175 |
|
compatible, |
176 |
|
h8300_scan, |
177 |
|
&h8300sn_info_struct |
178 |
|
}; |
179 |
|
|
180 |
|
static const bfd_arch_info_type h8300s_info_struct = |
181 |
|
{ |
182 |
|
32, /* 32 bits in a word. */ |
183 |
|
32, /* 32 bits in an address. */ |
184 |
|
8, /* 8 bits in a byte. */ |
185 |
|
bfd_arch_h8300, |
186 |
|
bfd_mach_h8300s, |
187 |
|
"h8300s", /* Architecture name. */ |
188 |
|
"h8300s", /* Printable name. */ |
189 |
|
1, |
190 |
|
FALSE, /* The default machine. */ |
191 |
|
compatible, |
192 |
|
h8300_scan, |
193 |
|
& h8300hn_info_struct |
194 |
|
}; |
195 |
|
|
196 |
|
static const bfd_arch_info_type h8300h_info_struct = |
197 |
|
{ |
198 |
|
32, /* 32 bits in a word. */ |
199 |
|
32, /* 32 bits in an address. */ |
200 |
|
8, /* 8 bits in a byte. */ |
201 |
|
bfd_arch_h8300, |
202 |
bfd_mach_h8300h, |
bfd_mach_h8300h, |
203 |
"h8300h", /* arch_name */ |
"h8300h", /* Architecture name. */ |
204 |
"h8300h", /* printable name */ |
"h8300h", /* Printable name. */ |
205 |
1, |
1, |
206 |
false, /* the default machine */ |
FALSE, /* The default machine. */ |
207 |
compatible, |
compatible, |
208 |
h8300_scan, |
h8300_scan, |
209 |
&h8300s_info_struct |
&h8300s_info_struct |
211 |
|
|
212 |
const bfd_arch_info_type bfd_h8300_arch = |
const bfd_arch_info_type bfd_h8300_arch = |
213 |
{ |
{ |
214 |
16, /* 16 bits in a word */ |
16, /* 16 bits in a word. */ |
215 |
16, /* 16 bits in an address */ |
16, /* 16 bits in an address. */ |
216 |
8, /* 8 bits in a byte */ |
8, /* 8 bits in a byte. */ |
217 |
bfd_arch_h8300, |
bfd_arch_h8300, |
218 |
bfd_mach_h8300, |
bfd_mach_h8300, |
219 |
"h8300", /* arch_name */ |
"h8300", /* Architecture name. */ |
220 |
"h8300", /* printable name */ |
"h8300", /* Printable name. */ |
221 |
1, |
1, |
222 |
true, /* the default machine */ |
TRUE, /* The default machine. */ |
223 |
compatible, |
compatible, |
224 |
h8300_scan, |
h8300_scan, |
225 |
&h8300h_info_struct |
&h8300h_info_struct |
226 |
}; |
}; |
227 |
|
|
228 |
|
/* Pad the given address to 32 bits, converting 16-bit and 24-bit |
229 |
|
addresses into the values they would have had on a h8s target. */ |
230 |
|
|
231 |
|
bfd_vma |
232 |
|
bfd_h8300_pad_address (bfd *abfd, bfd_vma address) |
233 |
|
{ |
234 |
|
/* Cope with bfd_vma's larger than 32 bits. */ |
235 |
|
address &= 0xffffffffu; |
236 |
|
|
237 |
|
switch (bfd_get_mach (abfd)) |
238 |
|
{ |
239 |
|
case bfd_mach_h8300: |
240 |
|
case bfd_mach_h8300hn: |
241 |
|
case bfd_mach_h8300sn: |
242 |
|
case bfd_mach_h8300sxn: |
243 |
|
/* Sign extend a 16-bit address. */ |
244 |
|
if (address >= 0x8000) |
245 |
|
return address | 0xffff0000u; |
246 |
|
return address; |
247 |
|
|
248 |
|
case bfd_mach_h8300h: |
249 |
|
/* Sign extend a 24-bit address. */ |
250 |
|
if (address >= 0x800000) |
251 |
|
return address | 0xff000000u; |
252 |
|
return address; |
253 |
|
|
254 |
|
case bfd_mach_h8300s: |
255 |
|
case bfd_mach_h8300sx: |
256 |
|
return address; |
257 |
|
|
258 |
|
default: |
259 |
|
abort (); |
260 |
|
} |
261 |
|
} |