12a6b7db3Sskrll /* BFD PowerPC CPU definition
2*cb63e24eSchristos Copyright (C) 1994-2024 Free Software Foundation, Inc.
32a6b7db3Sskrll Contributed by Ian Lance Taylor, Cygnus Support.
42a6b7db3Sskrll
52a6b7db3Sskrll This file is part of BFD, the Binary File Descriptor library.
62a6b7db3Sskrll
72a6b7db3Sskrll This program is free software; you can redistribute it and/or modify
82a6b7db3Sskrll it under the terms of the GNU General Public License as published by
92a6b7db3Sskrll the Free Software Foundation; either version 3 of the License, or
102a6b7db3Sskrll (at your option) any later version.
112a6b7db3Sskrll
122a6b7db3Sskrll This program is distributed in the hope that it will be useful,
132a6b7db3Sskrll but WITHOUT ANY WARRANTY; without even the implied warranty of
142a6b7db3Sskrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
152a6b7db3Sskrll GNU General Public License for more details.
162a6b7db3Sskrll
172a6b7db3Sskrll You should have received a copy of the GNU General Public License
182a6b7db3Sskrll along with this program; if not, write to the Free Software
192a6b7db3Sskrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
202a6b7db3Sskrll MA 02110-1301, USA. */
212a6b7db3Sskrll
222a6b7db3Sskrll #include "sysdep.h"
232a6b7db3Sskrll #include "bfd.h"
242a6b7db3Sskrll #include "libbfd.h"
252a6b7db3Sskrll
262a6b7db3Sskrll /* The common PowerPC architecture is compatible with the RS/6000. */
272a6b7db3Sskrll
282a6b7db3Sskrll static const bfd_arch_info_type *
powerpc_compatible(const bfd_arch_info_type * a,const bfd_arch_info_type * b)29883529b6Schristos powerpc_compatible (const bfd_arch_info_type *a,
30883529b6Schristos const bfd_arch_info_type *b)
312a6b7db3Sskrll {
322a6b7db3Sskrll BFD_ASSERT (a->arch == bfd_arch_powerpc);
332a6b7db3Sskrll switch (b->arch)
342a6b7db3Sskrll {
352a6b7db3Sskrll default:
362a6b7db3Sskrll return NULL;
372a6b7db3Sskrll case bfd_arch_powerpc:
388cbf5cb7Schristos if (a->mach == bfd_mach_ppc_vle && b->bits_per_word == 32)
398cbf5cb7Schristos return a;
408cbf5cb7Schristos if (b->mach == bfd_mach_ppc_vle && a->bits_per_word == 32)
418cbf5cb7Schristos return b;
422a6b7db3Sskrll return bfd_default_compatible (a, b);
432a6b7db3Sskrll case bfd_arch_rs6000:
442a6b7db3Sskrll if (b->mach == bfd_mach_rs6k)
452a6b7db3Sskrll return a;
462a6b7db3Sskrll return NULL;
472a6b7db3Sskrll }
482a6b7db3Sskrll /*NOTREACHED*/
492a6b7db3Sskrll }
502a6b7db3Sskrll
516f4ced0bSchristos /* Return a COUNT sized buffer filled with nops (if CODE is TRUE) or
526f4ced0bSchristos zeros (if CODE is FALSE). This is the fill used between input
536f4ced0bSchristos sections for alignment. It won't normally be executed. */
546f4ced0bSchristos
556f4ced0bSchristos static void *
bfd_arch_ppc_nop_fill(bfd_size_type count,bool is_bigendian,bool code)566f4ced0bSchristos bfd_arch_ppc_nop_fill (bfd_size_type count,
574f645668Schristos bool is_bigendian,
584f645668Schristos bool code)
596f4ced0bSchristos {
606f4ced0bSchristos bfd_byte *fill;
616f4ced0bSchristos
626f4ced0bSchristos if (count == 0)
636f4ced0bSchristos return NULL;
646f4ced0bSchristos fill = bfd_malloc (count);
656f4ced0bSchristos if (fill == NULL)
666f4ced0bSchristos return fill;
676f4ced0bSchristos
686f4ced0bSchristos if (code && (count & 3) == 0)
696f4ced0bSchristos {
706f4ced0bSchristos static const char nop_be[4] = {0x60, 0, 0, 0};
716f4ced0bSchristos static const char nop_le[4] = {0, 0, 0, 0x60};
726f4ced0bSchristos const char *nop = is_bigendian ? nop_be : nop_le;
736f4ced0bSchristos bfd_byte *p = fill;
746f4ced0bSchristos
756f4ced0bSchristos while (count != 0)
766f4ced0bSchristos {
776f4ced0bSchristos memcpy (p, nop, 4);
786f4ced0bSchristos p += 4;
796f4ced0bSchristos count -= 4;
806f4ced0bSchristos }
816f4ced0bSchristos }
826f4ced0bSchristos else
836f4ced0bSchristos memset (fill, 0, count);
846f4ced0bSchristos
856f4ced0bSchristos return fill;
866f4ced0bSchristos }
876f4ced0bSchristos
886f4ced0bSchristos #define N(BITS, NUMBER, PRINT, DEFAULT, NEXT) \
896f4ced0bSchristos { \
906f4ced0bSchristos BITS, /* Bits in a word. */ \
916f4ced0bSchristos BITS, /* Bits in an address. */ \
926f4ced0bSchristos 8, /* Bits in a byte. */ \
936f4ced0bSchristos bfd_arch_powerpc, \
946f4ced0bSchristos NUMBER, \
956f4ced0bSchristos "powerpc", \
966f4ced0bSchristos PRINT, \
976f4ced0bSchristos 3, /* Section alignment power. */ \
986f4ced0bSchristos DEFAULT, \
996f4ced0bSchristos powerpc_compatible, \
1006f4ced0bSchristos bfd_default_scan, \
1016f4ced0bSchristos bfd_arch_ppc_nop_fill, \
1026f4ced0bSchristos NEXT, \
1036f4ced0bSchristos 0 /* Maximum offset of a reloc from the start of an insn. */ \
1046f4ced0bSchristos }
1056f4ced0bSchristos
1062a6b7db3Sskrll const bfd_arch_info_type bfd_powerpc_archs[] =
1072a6b7db3Sskrll {
1082a6b7db3Sskrll #if BFD_DEFAULT_TARGET_SIZE == 64
1096f4ced0bSchristos /* Default for 64 bit target. */
1104f645668Schristos N (64, bfd_mach_ppc64, "powerpc:common64", true, bfd_powerpc_archs + 1),
1112a6b7db3Sskrll /* elf32-ppc:ppc_elf_object_p relies on the default 32 bit arch
1122a6b7db3Sskrll being immediately after the 64 bit default. */
1134f645668Schristos N (32, bfd_mach_ppc, "powerpc:common", false, bfd_powerpc_archs + 2),
1142a6b7db3Sskrll #else
1152a6b7db3Sskrll /* Default arch must come first. */
1164f645668Schristos N (32, bfd_mach_ppc, "powerpc:common", true, bfd_powerpc_archs + 1),
1172a6b7db3Sskrll /* elf64-ppc:ppc64_elf_object_p relies on the default 64 bit arch
1182a6b7db3Sskrll being immediately after the 32 bit default. */
1194f645668Schristos N (64, bfd_mach_ppc64, "powerpc:common64", false, bfd_powerpc_archs + 2),
1202a6b7db3Sskrll #endif
1214f645668Schristos N (32, bfd_mach_ppc_603, "powerpc:603", false, bfd_powerpc_archs + 3),
1224f645668Schristos N (32, bfd_mach_ppc_ec603e, "powerpc:EC603e", false, bfd_powerpc_archs + 4),
1234f645668Schristos N (32, bfd_mach_ppc_604, "powerpc:604", false, bfd_powerpc_archs + 5),
1244f645668Schristos N (32, bfd_mach_ppc_403, "powerpc:403", false, bfd_powerpc_archs + 6),
1254f645668Schristos N (32, bfd_mach_ppc_601, "powerpc:601", false, bfd_powerpc_archs + 7),
1264f645668Schristos N (64, bfd_mach_ppc_620, "powerpc:620", false, bfd_powerpc_archs + 8),
1274f645668Schristos N (64, bfd_mach_ppc_630, "powerpc:630", false, bfd_powerpc_archs + 9),
1284f645668Schristos N (64, bfd_mach_ppc_a35, "powerpc:a35", false, bfd_powerpc_archs + 10),
1294f645668Schristos N (64, bfd_mach_ppc_rs64ii, "powerpc:rs64ii", false, bfd_powerpc_archs + 11),
1304f645668Schristos N (64, bfd_mach_ppc_rs64iii, "powerpc:rs64iii", false, bfd_powerpc_archs + 12),
1314f645668Schristos N (32, bfd_mach_ppc_7400, "powerpc:7400", false, bfd_powerpc_archs + 13),
1324f645668Schristos N (32, bfd_mach_ppc_e500, "powerpc:e500", false, bfd_powerpc_archs + 14),
1334f645668Schristos N (32, bfd_mach_ppc_e500mc, "powerpc:e500mc", false, bfd_powerpc_archs + 15),
1344f645668Schristos N (64, bfd_mach_ppc_e500mc64, "powerpc:e500mc64",false, bfd_powerpc_archs + 16),
1354f645668Schristos N (32, bfd_mach_ppc_860, "powerpc:MPC8XX", false, bfd_powerpc_archs + 17),
1364f645668Schristos N (32, bfd_mach_ppc_750, "powerpc:750", false, bfd_powerpc_archs + 18),
1374f645668Schristos N (32, bfd_mach_ppc_titan, "powerpc:titan", false, bfd_powerpc_archs + 19),
1386f4ced0bSchristos
1392a6b7db3Sskrll {
1406f4ced0bSchristos 16, /* Bits in a word. */
1416f4ced0bSchristos 32, /* Bits in an address. */
1426f4ced0bSchristos 8, /* Bits in a byte. */
143883529b6Schristos bfd_arch_powerpc,
144883529b6Schristos bfd_mach_ppc_vle,
145883529b6Schristos "powerpc",
146883529b6Schristos "powerpc:vle",
147883529b6Schristos 3,
1484f645668Schristos false, /* Not the default. */
149883529b6Schristos powerpc_compatible,
150883529b6Schristos bfd_default_scan,
151883529b6Schristos bfd_arch_default_fill,
1526f4ced0bSchristos bfd_powerpc_archs + 20,
1536f4ced0bSchristos 0 /* Maximum offset of a reloc from the start of an insn. */
154883529b6Schristos },
1556f4ced0bSchristos
1564f645668Schristos N (64, bfd_mach_ppc_e5500, "powerpc:e5500", false, bfd_powerpc_archs + 21),
1574f645668Schristos N (64, bfd_mach_ppc_e6500, "powerpc:e6500", false, NULL)
1582a6b7db3Sskrll };
159