xref: /netbsd-src/external/gpl3/binutils/dist/bfd/cpu-powerpc.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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