175fd0b74Schristos /* BFD PowerPC CPU definition
2*e992f068Schristos Copyright (C) 1994-2022 Free Software Foundation, Inc.
375fd0b74Schristos Contributed by Ian Lance Taylor, 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"
2575fd0b74Schristos
2675fd0b74Schristos /* The common PowerPC architecture is compatible with the RS/6000. */
2775fd0b74Schristos
2875fd0b74Schristos static const bfd_arch_info_type *
powerpc_compatible(const bfd_arch_info_type * a,const bfd_arch_info_type * b)2975fd0b74Schristos powerpc_compatible (const bfd_arch_info_type *a,
3075fd0b74Schristos const bfd_arch_info_type *b)
3175fd0b74Schristos {
3275fd0b74Schristos BFD_ASSERT (a->arch == bfd_arch_powerpc);
3375fd0b74Schristos switch (b->arch)
3475fd0b74Schristos {
3575fd0b74Schristos default:
3675fd0b74Schristos return NULL;
3775fd0b74Schristos case bfd_arch_powerpc:
3875fd0b74Schristos if (a->mach == bfd_mach_ppc_vle && b->bits_per_word == 32)
3975fd0b74Schristos return a;
4075fd0b74Schristos if (b->mach == bfd_mach_ppc_vle && a->bits_per_word == 32)
4175fd0b74Schristos return b;
4275fd0b74Schristos return bfd_default_compatible (a, b);
4375fd0b74Schristos case bfd_arch_rs6000:
4475fd0b74Schristos if (b->mach == bfd_mach_rs6k)
4575fd0b74Schristos return a;
4675fd0b74Schristos return NULL;
4775fd0b74Schristos }
4875fd0b74Schristos /*NOTREACHED*/
4975fd0b74Schristos }
5075fd0b74Schristos
51012573ebSchristos /* Return a COUNT sized buffer filled with nops (if CODE is TRUE) or
52012573ebSchristos zeros (if CODE is FALSE). This is the fill used between input
53012573ebSchristos sections for alignment. It won't normally be executed. */
54012573ebSchristos
55012573ebSchristos static void *
bfd_arch_ppc_nop_fill(bfd_size_type count,bool is_bigendian,bool code)56012573ebSchristos bfd_arch_ppc_nop_fill (bfd_size_type count,
57*e992f068Schristos bool is_bigendian,
58*e992f068Schristos bool code)
59012573ebSchristos {
60012573ebSchristos bfd_byte *fill;
61012573ebSchristos
62012573ebSchristos if (count == 0)
63012573ebSchristos return NULL;
64012573ebSchristos fill = bfd_malloc (count);
65012573ebSchristos if (fill == NULL)
66012573ebSchristos return fill;
67012573ebSchristos
68012573ebSchristos if (code && (count & 3) == 0)
69012573ebSchristos {
70012573ebSchristos static const char nop_be[4] = {0x60, 0, 0, 0};
71012573ebSchristos static const char nop_le[4] = {0, 0, 0, 0x60};
72012573ebSchristos const char *nop = is_bigendian ? nop_be : nop_le;
73012573ebSchristos bfd_byte *p = fill;
74012573ebSchristos
75012573ebSchristos while (count != 0)
76012573ebSchristos {
77012573ebSchristos memcpy (p, nop, 4);
78012573ebSchristos p += 4;
79012573ebSchristos count -= 4;
80012573ebSchristos }
81012573ebSchristos }
82012573ebSchristos else
83012573ebSchristos memset (fill, 0, count);
84012573ebSchristos
85012573ebSchristos return fill;
86012573ebSchristos }
87012573ebSchristos
88012573ebSchristos #define N(BITS, NUMBER, PRINT, DEFAULT, NEXT) \
89012573ebSchristos { \
90012573ebSchristos BITS, /* Bits in a word. */ \
91012573ebSchristos BITS, /* Bits in an address. */ \
92012573ebSchristos 8, /* Bits in a byte. */ \
93012573ebSchristos bfd_arch_powerpc, \
94012573ebSchristos NUMBER, \
95012573ebSchristos "powerpc", \
96012573ebSchristos PRINT, \
97012573ebSchristos 3, /* Section alignment power. */ \
98012573ebSchristos DEFAULT, \
99012573ebSchristos powerpc_compatible, \
100012573ebSchristos bfd_default_scan, \
101012573ebSchristos bfd_arch_ppc_nop_fill, \
102012573ebSchristos NEXT, \
103012573ebSchristos 0 /* Maximum offset of a reloc from the start of an insn. */ \
104012573ebSchristos }
105012573ebSchristos
10675fd0b74Schristos const bfd_arch_info_type bfd_powerpc_archs[] =
10775fd0b74Schristos {
10875fd0b74Schristos #if BFD_DEFAULT_TARGET_SIZE == 64
109012573ebSchristos /* Default for 64 bit target. */
110*e992f068Schristos N (64, bfd_mach_ppc64, "powerpc:common64", true, bfd_powerpc_archs + 1),
11175fd0b74Schristos /* elf32-ppc:ppc_elf_object_p relies on the default 32 bit arch
11275fd0b74Schristos being immediately after the 64 bit default. */
113*e992f068Schristos N (32, bfd_mach_ppc, "powerpc:common", false, bfd_powerpc_archs + 2),
11475fd0b74Schristos #else
11575fd0b74Schristos /* Default arch must come first. */
116*e992f068Schristos N (32, bfd_mach_ppc, "powerpc:common", true, bfd_powerpc_archs + 1),
11775fd0b74Schristos /* elf64-ppc:ppc64_elf_object_p relies on the default 64 bit arch
11875fd0b74Schristos being immediately after the 32 bit default. */
119*e992f068Schristos N (64, bfd_mach_ppc64, "powerpc:common64", false, bfd_powerpc_archs + 2),
12075fd0b74Schristos #endif
121*e992f068Schristos N (32, bfd_mach_ppc_603, "powerpc:603", false, bfd_powerpc_archs + 3),
122*e992f068Schristos N (32, bfd_mach_ppc_ec603e, "powerpc:EC603e", false, bfd_powerpc_archs + 4),
123*e992f068Schristos N (32, bfd_mach_ppc_604, "powerpc:604", false, bfd_powerpc_archs + 5),
124*e992f068Schristos N (32, bfd_mach_ppc_403, "powerpc:403", false, bfd_powerpc_archs + 6),
125*e992f068Schristos N (32, bfd_mach_ppc_601, "powerpc:601", false, bfd_powerpc_archs + 7),
126*e992f068Schristos N (64, bfd_mach_ppc_620, "powerpc:620", false, bfd_powerpc_archs + 8),
127*e992f068Schristos N (64, bfd_mach_ppc_630, "powerpc:630", false, bfd_powerpc_archs + 9),
128*e992f068Schristos N (64, bfd_mach_ppc_a35, "powerpc:a35", false, bfd_powerpc_archs + 10),
129*e992f068Schristos N (64, bfd_mach_ppc_rs64ii, "powerpc:rs64ii", false, bfd_powerpc_archs + 11),
130*e992f068Schristos N (64, bfd_mach_ppc_rs64iii, "powerpc:rs64iii", false, bfd_powerpc_archs + 12),
131*e992f068Schristos N (32, bfd_mach_ppc_7400, "powerpc:7400", false, bfd_powerpc_archs + 13),
132*e992f068Schristos N (32, bfd_mach_ppc_e500, "powerpc:e500", false, bfd_powerpc_archs + 14),
133*e992f068Schristos N (32, bfd_mach_ppc_e500mc, "powerpc:e500mc", false, bfd_powerpc_archs + 15),
134*e992f068Schristos N (64, bfd_mach_ppc_e500mc64, "powerpc:e500mc64",false, bfd_powerpc_archs + 16),
135*e992f068Schristos N (32, bfd_mach_ppc_860, "powerpc:MPC8XX", false, bfd_powerpc_archs + 17),
136*e992f068Schristos N (32, bfd_mach_ppc_750, "powerpc:750", false, bfd_powerpc_archs + 18),
137*e992f068Schristos N (32, bfd_mach_ppc_titan, "powerpc:titan", false, bfd_powerpc_archs + 19),
138012573ebSchristos
13975fd0b74Schristos {
140012573ebSchristos 16, /* Bits in a word. */
141012573ebSchristos 32, /* Bits in an address. */
142012573ebSchristos 8, /* Bits in a byte. */
14375fd0b74Schristos bfd_arch_powerpc,
14475fd0b74Schristos bfd_mach_ppc_vle,
14575fd0b74Schristos "powerpc",
14675fd0b74Schristos "powerpc:vle",
14775fd0b74Schristos 3,
148*e992f068Schristos false, /* Not the default. */
14975fd0b74Schristos powerpc_compatible,
15075fd0b74Schristos bfd_default_scan,
15175fd0b74Schristos bfd_arch_default_fill,
152012573ebSchristos bfd_powerpc_archs + 20,
153012573ebSchristos 0 /* Maximum offset of a reloc from the start of an insn. */
15475fd0b74Schristos },
155012573ebSchristos
156*e992f068Schristos N (64, bfd_mach_ppc_e5500, "powerpc:e5500", false, bfd_powerpc_archs + 21),
157*e992f068Schristos N (64, bfd_mach_ppc_e6500, "powerpc:e6500", false, NULL)
15875fd0b74Schristos };
159