175fd0b74Schristos /* BFD library support routines for the Renesas H8/300 architecture.
2*e992f068Schristos Copyright (C) 1990-2022 Free Software Foundation, Inc.
375fd0b74Schristos Hacked by Steve Chamberlain of Cygnus Support.
475fd0b74Schristos
575fd0b74Schristos This file is part of BFD, the Binary File Descriptor library.
675fd0b74Schristos
775fd0b74Schristos This program is free software; you can redistribute it and/or modify
875fd0b74Schristos it under the terms of the GNU General Public License as published by
975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos (at your option) any later version.
1175fd0b74Schristos
1275fd0b74Schristos This program is distributed in the hope that it will be useful,
1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1575fd0b74Schristos GNU General Public License for more details.
1675fd0b74Schristos
1775fd0b74Schristos You should have received a copy of the GNU General Public License
1875fd0b74Schristos along with this program; if not, write to the Free Software
1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos MA 02110-1301, USA. */
2175fd0b74Schristos
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "libbfd.h"
25012573ebSchristos #include "cpu-h8300.h"
2675fd0b74Schristos
27*e992f068Schristos static bool
h8300_scan(const struct bfd_arch_info * info,const char * string)2875fd0b74Schristos h8300_scan (const struct bfd_arch_info *info, const char *string)
2975fd0b74Schristos {
3075fd0b74Schristos if (*string != 'h' && *string != 'H')
31*e992f068Schristos return false;
3275fd0b74Schristos
3375fd0b74Schristos string++;
3475fd0b74Schristos if (*string != '8')
35*e992f068Schristos return false;
3675fd0b74Schristos
3775fd0b74Schristos string++;
3875fd0b74Schristos if (*string == '/')
3975fd0b74Schristos string++;
4075fd0b74Schristos
4175fd0b74Schristos if (*string != '3')
42*e992f068Schristos return false;
4375fd0b74Schristos string++;
4475fd0b74Schristos if (*string != '0')
45*e992f068Schristos return false;
4675fd0b74Schristos string++;
4775fd0b74Schristos if (*string != '0')
48*e992f068Schristos return false;
4975fd0b74Schristos string++;
5075fd0b74Schristos if (*string == '-')
5175fd0b74Schristos string++;
5275fd0b74Schristos
5375fd0b74Schristos /* In ELF linker scripts, we typically express the architecture/machine
5475fd0b74Schristos as architecture:machine.
5575fd0b74Schristos
5675fd0b74Schristos So if we've matched so far and encounter a colon, try to match the
5775fd0b74Schristos string following the colon. */
5875fd0b74Schristos if (*string == ':')
5975fd0b74Schristos {
6075fd0b74Schristos string++;
6175fd0b74Schristos return h8300_scan (info, string);
6275fd0b74Schristos }
6375fd0b74Schristos
6475fd0b74Schristos if (*string == 'h' || *string == 'H')
6575fd0b74Schristos {
6675fd0b74Schristos string++;
6775fd0b74Schristos if (*string == 'n' || *string == 'N')
6875fd0b74Schristos return (info->mach == bfd_mach_h8300hn);
6975fd0b74Schristos
7075fd0b74Schristos return (info->mach == bfd_mach_h8300h);
7175fd0b74Schristos }
7275fd0b74Schristos else if (*string == 's' || *string == 'S')
7375fd0b74Schristos {
7475fd0b74Schristos string++;
7575fd0b74Schristos if (*string == 'n' || *string == 'N')
7675fd0b74Schristos return (info->mach == bfd_mach_h8300sn);
7775fd0b74Schristos
7875fd0b74Schristos if (*string == 'x' || *string == 'X')
7975fd0b74Schristos {
8075fd0b74Schristos string++;
8175fd0b74Schristos if (*string == 'n' || *string == 'N')
8275fd0b74Schristos return (info->mach == bfd_mach_h8300sxn);
8375fd0b74Schristos
8475fd0b74Schristos return (info->mach == bfd_mach_h8300sx);
8575fd0b74Schristos }
8675fd0b74Schristos
8775fd0b74Schristos return (info->mach == bfd_mach_h8300s);
8875fd0b74Schristos }
8975fd0b74Schristos else
9075fd0b74Schristos return info->mach == bfd_mach_h8300;
9175fd0b74Schristos }
9275fd0b74Schristos
9375fd0b74Schristos /* This routine is provided two arch_infos and works out the machine
9475fd0b74Schristos which would be compatible with both and returns a pointer to its
9575fd0b74Schristos info structure. */
9675fd0b74Schristos
9775fd0b74Schristos static const bfd_arch_info_type *
compatible(const bfd_arch_info_type * in,const bfd_arch_info_type * out)9875fd0b74Schristos compatible (const bfd_arch_info_type *in, const bfd_arch_info_type *out)
9975fd0b74Schristos {
10075fd0b74Schristos if (in->arch != out->arch)
10175fd0b74Schristos return 0;
10275fd0b74Schristos if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s)
10375fd0b74Schristos return in;
10475fd0b74Schristos if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx)
10575fd0b74Schristos return out;
10675fd0b74Schristos if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn)
10775fd0b74Schristos return in;
10875fd0b74Schristos if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn)
10975fd0b74Schristos return out;
11075fd0b74Schristos /* It's really not a good idea to mix and match modes. */
11175fd0b74Schristos if (in->mach != out->mach)
11275fd0b74Schristos return 0;
11375fd0b74Schristos else
11475fd0b74Schristos return in;
11575fd0b74Schristos }
11675fd0b74Schristos
117012573ebSchristos #define N(word, addr, number, name, print, default, next) \
118012573ebSchristos { word, addr, 8, bfd_arch_h8300, number, name, print, 1, default, \
119012573ebSchristos compatible, h8300_scan, bfd_arch_default_fill, next, 0 }
120012573ebSchristos
12175fd0b74Schristos static const bfd_arch_info_type h8300sxn_info_struct =
122*e992f068Schristos N (32, 16, bfd_mach_h8300sxn, "h8300sxn", "h8300sxn", false, NULL);
12375fd0b74Schristos
12475fd0b74Schristos static const bfd_arch_info_type h8300sx_info_struct =
125*e992f068Schristos N (32, 32, bfd_mach_h8300sx, "h8300sx", "h8300sx", false, &h8300sxn_info_struct);
12675fd0b74Schristos
12775fd0b74Schristos static const bfd_arch_info_type h8300sn_info_struct =
128*e992f068Schristos N (32, 16, bfd_mach_h8300sn, "h8300sn", "h8300sn", false, &h8300sx_info_struct);
12975fd0b74Schristos
13075fd0b74Schristos static const bfd_arch_info_type h8300hn_info_struct =
131*e992f068Schristos N (32, 16, bfd_mach_h8300hn, "h8300hn", "h8300hn", false, &h8300sn_info_struct);
13275fd0b74Schristos
13375fd0b74Schristos static const bfd_arch_info_type h8300s_info_struct =
134*e992f068Schristos N (32, 32, bfd_mach_h8300s, "h8300s", "h8300s", false, & h8300hn_info_struct);
13575fd0b74Schristos
13675fd0b74Schristos static const bfd_arch_info_type h8300h_info_struct =
137*e992f068Schristos N (32, 32, bfd_mach_h8300h, "h8300h", "h8300h", false, &h8300s_info_struct);
13875fd0b74Schristos
13975fd0b74Schristos const bfd_arch_info_type bfd_h8300_arch =
140*e992f068Schristos N (16, 16, bfd_mach_h8300, "h8300", "h8300", true, &h8300h_info_struct);
14175fd0b74Schristos
14275fd0b74Schristos /* Pad the given address to 32 bits, converting 16-bit and 24-bit
14375fd0b74Schristos addresses into the values they would have had on a h8s target. */
14475fd0b74Schristos
14575fd0b74Schristos bfd_vma
bfd_h8300_pad_address(bfd * abfd,bfd_vma address)14675fd0b74Schristos bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
14775fd0b74Schristos {
14875fd0b74Schristos /* Cope with bfd_vma's larger than 32 bits. */
14975fd0b74Schristos address &= 0xffffffffu;
15075fd0b74Schristos
15175fd0b74Schristos switch (bfd_get_mach (abfd))
15275fd0b74Schristos {
15375fd0b74Schristos case bfd_mach_h8300:
15475fd0b74Schristos case bfd_mach_h8300hn:
15575fd0b74Schristos case bfd_mach_h8300sn:
15675fd0b74Schristos case bfd_mach_h8300sxn:
15775fd0b74Schristos /* Sign extend a 16-bit address. */
15875fd0b74Schristos if (address >= 0x8000)
15975fd0b74Schristos return address | 0xffff0000u;
16075fd0b74Schristos return address;
16175fd0b74Schristos
16275fd0b74Schristos case bfd_mach_h8300h:
16375fd0b74Schristos /* Sign extend a 24-bit address. */
16475fd0b74Schristos if (address >= 0x800000)
16575fd0b74Schristos return address | 0xff000000u;
16675fd0b74Schristos return address;
16775fd0b74Schristos
16875fd0b74Schristos case bfd_mach_h8300s:
16975fd0b74Schristos case bfd_mach_h8300sx:
17075fd0b74Schristos return address;
17175fd0b74Schristos
17275fd0b74Schristos default:
17375fd0b74Schristos abort ();
17475fd0b74Schristos }
17575fd0b74Schristos }
176