1c074d1c9Sdrahn /* BFD library support routines for the Renesas H8/300 architecture.
2c074d1c9Sdrahn Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 2003
3b55d4692Sfgsch Free Software Foundation, Inc.
42159047fSniklas Hacked by Steve Chamberlain of Cygnus Support.
52159047fSniklas
62159047fSniklas This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
212159047fSniklas
222159047fSniklas #include "bfd.h"
232159047fSniklas #include "sysdep.h"
242159047fSniklas #include "libbfd.h"
252159047fSniklas
26c074d1c9Sdrahn static bfd_boolean
h8300_scan(const struct bfd_arch_info * info,const char * string)27*007c2a45Smiod h8300_scan (const struct bfd_arch_info *info, const char *string)
282159047fSniklas {
292159047fSniklas if (*string != 'h' && *string != 'H')
30c074d1c9Sdrahn return FALSE;
312159047fSniklas
322159047fSniklas string++;
332159047fSniklas if (*string != '8')
34c074d1c9Sdrahn return FALSE;
352159047fSniklas
362159047fSniklas string++;
372159047fSniklas if (*string == '/')
382159047fSniklas string++;
392159047fSniklas
402159047fSniklas if (*string != '3')
41c074d1c9Sdrahn return FALSE;
422159047fSniklas string++;
432159047fSniklas if (*string != '0')
44c074d1c9Sdrahn return FALSE;
452159047fSniklas string++;
462159047fSniklas if (*string != '0')
47c074d1c9Sdrahn return FALSE;
482159047fSniklas string++;
492159047fSniklas if (*string == '-')
502159047fSniklas string++;
51c074d1c9Sdrahn
52c074d1c9Sdrahn /* In ELF linker scripts, we typically express the architecture/machine
53c074d1c9Sdrahn as architecture:machine.
54c074d1c9Sdrahn
55c074d1c9Sdrahn So if we've matched so far and encounter a colon, try to match the
56c074d1c9Sdrahn string following the colon. */
57c074d1c9Sdrahn if (*string == ':')
58c074d1c9Sdrahn {
59c074d1c9Sdrahn string++;
60c074d1c9Sdrahn return h8300_scan (info, string);
61c074d1c9Sdrahn }
62c074d1c9Sdrahn
632159047fSniklas if (*string == 'h' || *string == 'H')
642159047fSniklas {
65c074d1c9Sdrahn string++;
66c074d1c9Sdrahn if (*string == 'n' || *string == 'N')
67c074d1c9Sdrahn return (info->mach == bfd_mach_h8300hn);
68c074d1c9Sdrahn
692159047fSniklas return (info->mach == bfd_mach_h8300h);
702159047fSniklas }
714361b62eSniklas else if (*string == 's' || *string == 'S')
724361b62eSniklas {
73c074d1c9Sdrahn string++;
74c074d1c9Sdrahn if (*string == 'n' || *string == 'N')
75c074d1c9Sdrahn return (info->mach == bfd_mach_h8300sn);
76c074d1c9Sdrahn
77*007c2a45Smiod if (*string == 'x' || *string == 'X')
78*007c2a45Smiod {
79*007c2a45Smiod string++;
80*007c2a45Smiod if (*string == 'n' || *string == 'N')
81*007c2a45Smiod return (info->mach == bfd_mach_h8300sxn);
82*007c2a45Smiod
83*007c2a45Smiod return (info->mach == bfd_mach_h8300sx);
84*007c2a45Smiod }
85*007c2a45Smiod
864361b62eSniklas return (info->mach == bfd_mach_h8300s);
874361b62eSniklas }
882159047fSniklas else
892159047fSniklas return info->mach == bfd_mach_h8300;
902159047fSniklas }
912159047fSniklas
92b55d4692Sfgsch /* This routine is provided two arch_infos and works out the machine
93b55d4692Sfgsch which would be compatible with both and returns a pointer to its
94b55d4692Sfgsch info structure. */
952159047fSniklas
962159047fSniklas static const bfd_arch_info_type *
compatible(const bfd_arch_info_type * in,const bfd_arch_info_type * out)97*007c2a45Smiod compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out)
982159047fSniklas {
994361b62eSniklas /* It's really not a good idea to mix and match modes. */
100c074d1c9Sdrahn if (in->arch != out->arch || in->mach != out->mach)
1012159047fSniklas return 0;
1024361b62eSniklas else
1032159047fSniklas return in;
1042159047fSniklas }
1052159047fSniklas
106*007c2a45Smiod static const bfd_arch_info_type h8300sxn_info_struct =
107*007c2a45Smiod {
108*007c2a45Smiod 32, /* 32 bits in a word */
109*007c2a45Smiod 16, /* 16 bits in an address */
110*007c2a45Smiod 8, /* 8 bits in a byte */
111*007c2a45Smiod bfd_arch_h8300,
112*007c2a45Smiod bfd_mach_h8300sxn,
113*007c2a45Smiod "h8300sxn", /* arch_name */
114*007c2a45Smiod "h8300sxn", /* printable name */
115*007c2a45Smiod 1,
116*007c2a45Smiod FALSE, /* the default machine */
117*007c2a45Smiod compatible,
118*007c2a45Smiod h8300_scan,
119*007c2a45Smiod 0
120*007c2a45Smiod };
121*007c2a45Smiod
122*007c2a45Smiod static const bfd_arch_info_type h8300sx_info_struct =
123*007c2a45Smiod {
124*007c2a45Smiod 32, /* 32 bits in a word */
125*007c2a45Smiod 32, /* 32 bits in an address */
126*007c2a45Smiod 8, /* 8 bits in a byte */
127*007c2a45Smiod bfd_arch_h8300,
128*007c2a45Smiod bfd_mach_h8300sx,
129*007c2a45Smiod "h8300sx", /* arch_name */
130*007c2a45Smiod "h8300sx", /* printable name */
131*007c2a45Smiod 1,
132*007c2a45Smiod FALSE, /* the default machine */
133*007c2a45Smiod compatible,
134*007c2a45Smiod h8300_scan,
135*007c2a45Smiod &h8300sxn_info_struct
136*007c2a45Smiod };
137*007c2a45Smiod
138c074d1c9Sdrahn static const bfd_arch_info_type h8300sn_info_struct =
1392159047fSniklas {
140c074d1c9Sdrahn 32, /* 32 bits in a word. */
141*007c2a45Smiod 16, /* 16 bits in an address. */
142c074d1c9Sdrahn 8, /* 8 bits in a byte. */
1432159047fSniklas bfd_arch_h8300,
144c074d1c9Sdrahn bfd_mach_h8300sn,
145c074d1c9Sdrahn "h8300sn", /* Architecture name. */
146c074d1c9Sdrahn "h8300sn", /* Printable name. */
1472159047fSniklas 1,
148c074d1c9Sdrahn FALSE, /* The default machine. */
1492159047fSniklas compatible,
1502159047fSniklas h8300_scan,
151*007c2a45Smiod &h8300sx_info_struct
152c074d1c9Sdrahn };
153c074d1c9Sdrahn
154c074d1c9Sdrahn static const bfd_arch_info_type h8300hn_info_struct =
155c074d1c9Sdrahn {
156c074d1c9Sdrahn 32, /* 32 bits in a word. */
157*007c2a45Smiod 16, /* 16 bits in an address. */
158c074d1c9Sdrahn 8, /* 8 bits in a byte. */
159c074d1c9Sdrahn bfd_arch_h8300,
160c074d1c9Sdrahn bfd_mach_h8300hn,
161c074d1c9Sdrahn "h8300hn", /* Architecture name. */
162c074d1c9Sdrahn "h8300hn", /* Printable name. */
163c074d1c9Sdrahn 1,
164c074d1c9Sdrahn FALSE, /* The default machine. */
165c074d1c9Sdrahn compatible,
166c074d1c9Sdrahn h8300_scan,
167c074d1c9Sdrahn &h8300sn_info_struct
168c074d1c9Sdrahn };
169c074d1c9Sdrahn
170c074d1c9Sdrahn static const bfd_arch_info_type h8300s_info_struct =
171c074d1c9Sdrahn {
172c074d1c9Sdrahn 32, /* 32 bits in a word. */
173c074d1c9Sdrahn 32, /* 32 bits in an address. */
174c074d1c9Sdrahn 8, /* 8 bits in a byte. */
175c074d1c9Sdrahn bfd_arch_h8300,
176c074d1c9Sdrahn bfd_mach_h8300s,
177c074d1c9Sdrahn "h8300s", /* Architecture name. */
178c074d1c9Sdrahn "h8300s", /* Printable name. */
179c074d1c9Sdrahn 1,
180c074d1c9Sdrahn FALSE, /* The default machine. */
181c074d1c9Sdrahn compatible,
182c074d1c9Sdrahn h8300_scan,
183c074d1c9Sdrahn & h8300hn_info_struct
1842159047fSniklas };
1852159047fSniklas
1864361b62eSniklas static const bfd_arch_info_type h8300h_info_struct =
1872159047fSniklas {
188c074d1c9Sdrahn 32, /* 32 bits in a word. */
189c074d1c9Sdrahn 32, /* 32 bits in an address. */
190c074d1c9Sdrahn 8, /* 8 bits in a byte. */
1912159047fSniklas bfd_arch_h8300,
1922159047fSniklas bfd_mach_h8300h,
193c074d1c9Sdrahn "h8300h", /* Architecture name. */
194c074d1c9Sdrahn "h8300h", /* Printable name. */
1952159047fSniklas 1,
196c074d1c9Sdrahn FALSE, /* The default machine. */
1972159047fSniklas compatible,
1982159047fSniklas h8300_scan,
199c074d1c9Sdrahn &h8300s_info_struct
2002159047fSniklas };
2014361b62eSniklas
2024361b62eSniklas const bfd_arch_info_type bfd_h8300_arch =
2034361b62eSniklas {
204c074d1c9Sdrahn 16, /* 16 bits in a word. */
205c074d1c9Sdrahn 16, /* 16 bits in an address. */
206c074d1c9Sdrahn 8, /* 8 bits in a byte. */
2074361b62eSniklas bfd_arch_h8300,
208c074d1c9Sdrahn bfd_mach_h8300,
209c074d1c9Sdrahn "h8300", /* Architecture name. */
210c074d1c9Sdrahn "h8300", /* Printable name. */
2114361b62eSniklas 1,
212c074d1c9Sdrahn TRUE, /* The default machine. */
2134361b62eSniklas compatible,
2144361b62eSniklas h8300_scan,
215c074d1c9Sdrahn &h8300h_info_struct
2164361b62eSniklas };
217*007c2a45Smiod
218*007c2a45Smiod /* Pad the given address to 32 bits, converting 16-bit and 24-bit
219*007c2a45Smiod addresses into the values they would have had on a h8s target. */
220*007c2a45Smiod
221*007c2a45Smiod bfd_vma
bfd_h8300_pad_address(bfd * abfd,bfd_vma address)222*007c2a45Smiod bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
223*007c2a45Smiod {
224*007c2a45Smiod /* Cope with bfd_vma's larger than 32 bits. */
225*007c2a45Smiod address &= 0xffffffffu;
226*007c2a45Smiod
227*007c2a45Smiod switch (bfd_get_mach (abfd))
228*007c2a45Smiod {
229*007c2a45Smiod case bfd_mach_h8300:
230*007c2a45Smiod case bfd_mach_h8300hn:
231*007c2a45Smiod case bfd_mach_h8300sn:
232*007c2a45Smiod case bfd_mach_h8300sxn:
233*007c2a45Smiod /* Sign extend a 16-bit address. */
234*007c2a45Smiod if (address >= 0x8000)
235*007c2a45Smiod return address | 0xffff0000u;
236*007c2a45Smiod return address;
237*007c2a45Smiod
238*007c2a45Smiod case bfd_mach_h8300h:
239*007c2a45Smiod /* Sign extend a 24-bit address. */
240*007c2a45Smiod if (address >= 0x800000)
241*007c2a45Smiod return address | 0xff000000u;
242*007c2a45Smiod return address;
243*007c2a45Smiod
244*007c2a45Smiod case bfd_mach_h8300s:
245*007c2a45Smiod case bfd_mach_h8300sx:
246*007c2a45Smiod return address;
247*007c2a45Smiod
248*007c2a45Smiod default:
249*007c2a45Smiod abort ();
250*007c2a45Smiod }
251*007c2a45Smiod }
252