Commit 5b161fc3 authored by Doug Gilbert's avatar Doug Gilbert Committed by Patrick Williams

PowerPC PPE42 modifications

parent 237df3fa
...@@ -3183,6 +3183,7 @@ instruction. */ ...@@ -3183,6 +3183,7 @@ instruction. */
BFD_RELOC_PPC_EMB_RELST_HA, BFD_RELOC_PPC_EMB_RELST_HA,
BFD_RELOC_PPC_EMB_BIT_FLD, BFD_RELOC_PPC_EMB_BIT_FLD,
BFD_RELOC_PPC_EMB_RELSDA, BFD_RELOC_PPC_EMB_RELSDA,
BFD_RELOC_PPC_PPE_REL10,
BFD_RELOC_PPC_VLE_REL8, BFD_RELOC_PPC_VLE_REL8,
BFD_RELOC_PPC_VLE_REL15, BFD_RELOC_PPC_VLE_REL15,
BFD_RELOC_PPC_VLE_REL24, BFD_RELOC_PPC_VLE_REL24,
......
...@@ -1402,6 +1402,22 @@ static reloc_howto_type ppc_elf_howto_raw[] = { ...@@ -1402,6 +1402,22 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
0xffff, /* dst_mask */ 0xffff, /* dst_mask */
FALSE), /* pcrel_offset */ FALSE), /* pcrel_offset */
/* A relative 12 bit branch. */
HOWTO (R_PPC_PPE_REL10, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
10, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_PPC_PPE_REL10", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
0x7fe, /* dst_mask */
TRUE), /* pcrel_offset */
/* A relative 8 bit branch. */ /* A relative 8 bit branch. */
HOWTO (R_PPC_VLE_REL8, /* type */ HOWTO (R_PPC_VLE_REL8, /* type */
1, /* rightshift */ 1, /* rightshift */
...@@ -1958,6 +1974,7 @@ ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, ...@@ -1958,6 +1974,7 @@ ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
case BFD_RELOC_PPC_EMB_RELST_HA: r = R_PPC_EMB_RELST_HA; break; case BFD_RELOC_PPC_EMB_RELST_HA: r = R_PPC_EMB_RELST_HA; break;
case BFD_RELOC_PPC_EMB_BIT_FLD: r = R_PPC_EMB_BIT_FLD; break; case BFD_RELOC_PPC_EMB_BIT_FLD: r = R_PPC_EMB_BIT_FLD; break;
case BFD_RELOC_PPC_EMB_RELSDA: r = R_PPC_EMB_RELSDA; break; case BFD_RELOC_PPC_EMB_RELSDA: r = R_PPC_EMB_RELSDA; break;
case BFD_RELOC_PPC_PPE_REL10: r = R_PPC_PPE_REL10; break;
case BFD_RELOC_PPC_VLE_REL8: r = R_PPC_VLE_REL8; break; case BFD_RELOC_PPC_VLE_REL8: r = R_PPC_VLE_REL8; break;
case BFD_RELOC_PPC_VLE_REL15: r = R_PPC_VLE_REL15; break; case BFD_RELOC_PPC_VLE_REL15: r = R_PPC_VLE_REL15; break;
case BFD_RELOC_PPC_VLE_REL24: r = R_PPC_VLE_REL24; break; case BFD_RELOC_PPC_VLE_REL24: r = R_PPC_VLE_REL24; break;
...@@ -4121,6 +4138,7 @@ ppc_elf_check_relocs (bfd *abfd, ...@@ -4121,6 +4138,7 @@ ppc_elf_check_relocs (bfd *abfd,
} }
break; break;
case R_PPC_PPE_REL10:
case R_PPC_VLE_REL8: case R_PPC_VLE_REL8:
case R_PPC_VLE_REL15: case R_PPC_VLE_REL15:
case R_PPC_VLE_REL24: case R_PPC_VLE_REL24:
...@@ -8236,6 +8254,7 @@ ppc_elf_relocate_section (bfd *output_bfd, ...@@ -8236,6 +8254,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
case R_PPC_UADDR16: case R_PPC_UADDR16:
goto dodyn; goto dodyn;
case R_PPC_PPE_REL10:
case R_PPC_VLE_REL8: case R_PPC_VLE_REL8:
case R_PPC_VLE_REL15: case R_PPC_VLE_REL15:
case R_PPC_VLE_REL24: case R_PPC_VLE_REL24:
......
...@@ -1359,6 +1359,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", ...@@ -1359,6 +1359,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_EMB_RELST_HA", "BFD_RELOC_PPC_EMB_RELST_HA",
"BFD_RELOC_PPC_EMB_BIT_FLD", "BFD_RELOC_PPC_EMB_BIT_FLD",
"BFD_RELOC_PPC_EMB_RELSDA", "BFD_RELOC_PPC_EMB_RELSDA",
"BFD_RELOC_PPC_PPE_REL10",
"BFD_RELOC_PPC_VLE_REL8", "BFD_RELOC_PPC_VLE_REL8",
"BFD_RELOC_PPC_VLE_REL15", "BFD_RELOC_PPC_VLE_REL15",
"BFD_RELOC_PPC_VLE_REL24", "BFD_RELOC_PPC_VLE_REL24",
......
...@@ -2815,6 +2815,8 @@ ENUMX ...@@ -2815,6 +2815,8 @@ ENUMX
BFD_RELOC_PPC_EMB_BIT_FLD BFD_RELOC_PPC_EMB_BIT_FLD
ENUMX ENUMX
BFD_RELOC_PPC_EMB_RELSDA BFD_RELOC_PPC_EMB_RELSDA
ENUMX
BFD_RELOC_PPC_PPE_REL10
ENUMX ENUMX
BFD_RELOC_PPC_VLE_REL8 BFD_RELOC_PPC_VLE_REL8
ENUMX ENUMX
......
...@@ -141,7 +141,7 @@ host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktr ...@@ -141,7 +141,7 @@ host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktr
# binutils, gas and ld appear in that order because it makes sense to run # binutils, gas and ld appear in that order because it makes sense to run
# "make check" in that particular order. # "make check" in that particular order.
# If --enable-gold is used, "gold" may replace "ld". # If --enable-gold is used, "gold" may replace "ld".
host_tools="texinfo flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools" host_tools="flex bison binutils gas ld fixincludes gcc cgen sid sim gdb gprof etc expect dejagnu m4 utils guile fastjar gnattools"
# libgcj represents the runtime libraries only used by gcj. # libgcj represents the runtime libraries only used by gcj.
libgcj="target-libffi \ libgcj="target-libffi \
......
...@@ -177,6 +177,8 @@ enum ...@@ -177,6 +177,8 @@ enum
R_PPC64_DTPREL16_HIGHA = 115, R_PPC64_DTPREL16_HIGHA = 115,
R_PPC_EMB_RELSDA = 116, R_PPC_EMB_RELSDA = 116,
R_PPC_PPE_REL10 = 200,
R_PPC_VLE_REL8 = 216, R_PPC_VLE_REL8 = 216,
R_PPC_VLE_REL15 = 217, R_PPC_VLE_REL15 = 217,
R_PPC_VLE_REL24 = 218, R_PPC_VLE_REL24 = 218,
...@@ -204,6 +206,7 @@ enum ...@@ -204,6 +206,7 @@ enum
R_POWERPC_GNU_VTINHERIT = 253, R_POWERPC_GNU_VTINHERIT = 253,
R_POWERPC_GNU_VTENTRY = 254, R_POWERPC_GNU_VTENTRY = 254,
R_PPC_TOC16 = 255, R_PPC_TOC16 = 255,
}; };
// e_flags values defined for powerpc // e_flags values defined for powerpc
......
...@@ -364,6 +364,36 @@ static const struct pd_reg pre_defined_registers[] = ...@@ -364,6 +364,36 @@ static const struct pd_reg pre_defined_registers[] =
{ "ctr", 9 }, { "ctr", 9 },
{ "d.0", 0 }, /* Double Word Regs for PPE */
{ "d.1", 1 },
{ "d.2", 2 },
{ "d.28", 28 },
{ "d.29", 29 },
{ "d.3", 3 },
{ "d.30", 30 },
{ "d.31", 31 },
{ "d.4", 4 },
{ "d.5", 5 },
{ "d.6", 6 },
{ "d.7", 7 },
{ "d.8", 8 },
{ "d.9", 9 },
{ "d0", 0 }, /* More Double Word Regs for PPE */
{ "d1", 1 },
{ "d2", 2 },
{ "d28", 28 },
{ "d29", 29 },
{ "d3", 3 },
{ "d30", 30 },
{ "d31", 31 },
{ "d4", 4 },
{ "d5", 5 },
{ "d6", 6 },
{ "d7", 7 },
{ "d8", 8 },
{ "d9", 9 },
{ "dar", 19 }, /* Data Access Register */ { "dar", 19 }, /* Data Access Register */
{ "dec", 22 }, /* Decrementer */ { "dec", 22 }, /* Decrementer */
{ "dsisr", 18 }, /* Data Storage Interrupt Status Register */ { "dsisr", 18 }, /* Data Storage Interrupt Status Register */
...@@ -1272,6 +1302,7 @@ PowerPC options:\n\ ...@@ -1272,6 +1302,7 @@ PowerPC options:\n\
generate code for PowerPC 603/604\n\ generate code for PowerPC 603/604\n\
-m403 generate code for PowerPC 403\n\ -m403 generate code for PowerPC 403\n\
-m405 generate code for PowerPC 405\n\ -m405 generate code for PowerPC 405\n\
-mppe42 generate code for PowerPC ppe\n\
-m440 generate code for PowerPC 440\n\ -m440 generate code for PowerPC 440\n\
-m464 generate code for PowerPC 464\n\ -m464 generate code for PowerPC 464\n\
-m476 generate code for PowerPC 476\n\ -m476 generate code for PowerPC 476\n\
...@@ -1362,7 +1393,7 @@ ppc_arch (void) ...@@ -1362,7 +1393,7 @@ ppc_arch (void)
const char *default_cpu = TARGET_CPU; const char *default_cpu = TARGET_CPU;
ppc_set_cpu (); ppc_set_cpu ();
if ((ppc_cpu & PPC_OPCODE_PPC) != 0) if ((ppc_cpu & (PPC_OPCODE_PPC | PPC_OPCODE_PPE)) != 0)
return bfd_arch_powerpc; return bfd_arch_powerpc;
if ((ppc_cpu & PPC_OPCODE_VLE) != 0) if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
return bfd_arch_powerpc; return bfd_arch_powerpc;
...@@ -1820,6 +1851,47 @@ ppc_insert_operand (unsigned long insn, ...@@ -1820,6 +1851,47 @@ ppc_insert_operand (unsigned long insn,
as_bad_value_out_of_range (_("operand"), val, min, max, file, line); as_bad_value_out_of_range (_("operand"), val, min, max, file, line);
} }
if (cpu & PPC_OPCODE_PPE)
{
if (operand->flags & (PPC_OPERAND_GPR | PPC_OPERAND_GPR_0))
switch(val)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
case 7: case 8: case 9: case 10: case 13:
case 28: case 29: case 30: case 31:
break;
/* do nothing */
default:
if (val > 1 && val < 31)
as_bad_where (file, line, "%s %d", "Invalid PPE register: ", (int)val);
break;
}
else if (operand->flags & PPC_OPERAND_GPVDR)
switch(val)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
case 7: case 8: case 9:
case 28: case 29: case 30: case 31:
break;
/* do nothing */
default:
if (val > 0 && val < 31)
as_bad_where (file, line, "%s %d %x", "Invalid PPE virtual double register:", (int)val, (unsigned)operand->flags);
break;
}
else if (operand->flags & PPC_OPERAND_CR_REG)
switch(val)
{
case 0:
break;
/* do nothing */
default:
if (val != 0)
as_bad_where (file, line, "%s %d %x", "Invalid PPE Condition register:", (int)val, (unsigned)operand->flags);
break;
}
}
if (operand->insert) if (operand->insert)
{ {
const char *errmsg; const char *errmsg;
...@@ -3255,6 +3327,10 @@ md_assemble (char *str) ...@@ -3255,6 +3327,10 @@ md_assemble (char *str)
&& operand->bitm == 0xfffc && operand->bitm == 0xfffc
&& operand->shift == 0) && operand->shift == 0)
reloc = BFD_RELOC_PPC_B16; reloc = BFD_RELOC_PPC_B16;
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
&& operand->bitm == 0xffc
&& operand->shift == -1)
reloc = BFD_RELOC_PPC_PPE_REL10;
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
&& operand->bitm == 0x1fe && operand->bitm == 0x1fe
&& operand->shift == -1) && operand->shift == -1)
...@@ -7030,6 +7106,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) ...@@ -7030,6 +7106,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_24_PLT_PCREL: case BFD_RELOC_24_PLT_PCREL:
case BFD_RELOC_32_PLT_PCREL: case BFD_RELOC_32_PLT_PCREL:
case BFD_RELOC_64_PLT_PCREL: case BFD_RELOC_64_PLT_PCREL:
case BFD_RELOC_PPC_PPE_REL10:
case BFD_RELOC_PPC_VLE_REL8: case BFD_RELOC_PPC_VLE_REL8:
case BFD_RELOC_PPC_VLE_REL15: case BFD_RELOC_PPC_VLE_REL15:
case BFD_RELOC_PPC_VLE_REL24: case BFD_RELOC_PPC_VLE_REL24:
......
...@@ -131,6 +131,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type) ...@@ -131,6 +131,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
RELOC_NUMBER (R_PPC_EMB_BIT_FLD, 115) RELOC_NUMBER (R_PPC_EMB_BIT_FLD, 115)
RELOC_NUMBER (R_PPC_EMB_RELSDA, 116) RELOC_NUMBER (R_PPC_EMB_RELSDA, 116)
/* PowerPC PPE relocations. */
RELOC_NUMBER (R_PPC_PPE_REL10, 200)
/* PowerPC VLE relocations. */ /* PowerPC VLE relocations. */
RELOC_NUMBER (R_PPC_VLE_REL8, 216) RELOC_NUMBER (R_PPC_VLE_REL8, 216)
RELOC_NUMBER (R_PPC_VLE_REL15, 217) RELOC_NUMBER (R_PPC_VLE_REL15, 217)
......
...@@ -191,6 +191,9 @@ extern const int vle_num_opcodes; ...@@ -191,6 +191,9 @@ extern const int vle_num_opcodes;
/* Opcode is only supported by Power8 architecture. */ /* Opcode is only supported by Power8 architecture. */
#define PPC_OPCODE_POWER8 0x2000000000ull #define PPC_OPCODE_POWER8 0x2000000000ull
/* Opcode is only supported by PPE architecture. */
#define PPC_OPCODE_PPE 0x8000000000ull
/* Opcode which is supported by the Hardware Transactional Memory extension. */ /* Opcode which is supported by the Hardware Transactional Memory extension. */
/* Currently, this is the same as the POWER8 mask. If another cpu comes out /* Currently, this is the same as the POWER8 mask. If another cpu comes out
that isn't a superset of POWER8, we can define this to its own mask. */ that isn't a superset of POWER8, we can define this to its own mask. */
...@@ -386,6 +389,12 @@ extern const unsigned int num_powerpc_operands; ...@@ -386,6 +389,12 @@ extern const unsigned int num_powerpc_operands;
with the operands table for simplicity. The macro table is an with the operands table for simplicity. The macro table is an
array of struct powerpc_macro. */ array of struct powerpc_macro. */
/* This operand names a general purpose double register. PPE42 specific.
* The disassembler uses this to print
register names with a leading 'd'. */
#define PPC_OPERAND_GPVDR (0x400000)
struct powerpc_macro struct powerpc_macro
{ {
/* The macro name. */ /* The macro name. */
...@@ -409,5 +418,8 @@ extern const struct powerpc_macro powerpc_macros[]; ...@@ -409,5 +418,8 @@ extern const struct powerpc_macro powerpc_macros[];
extern const int powerpc_num_macros; extern const int powerpc_num_macros;
extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *); extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *);
extern int string_print_insn_powerpc (unsigned long insn,
uint64_t dialect, char * assemblyString);
extern void disassemble_init_powerpc_standalone (void);
#endif /* PPC_H */ #endif /* PPC_H */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
in both big and little endian mode and also for the POWER (RS/6000) in both big and little endian mode and also for the POWER (RS/6000)
chip. */ chip. */
static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
ppc_cpu_t); ppc_cpu_t);
struct dis_private struct dis_private
{ {
...@@ -56,14 +56,16 @@ struct ppc_mopt ppc_opts[] = { ...@@ -56,14 +56,16 @@ struct ppc_mopt ppc_opts[] = {
0 }, 0 },
{ "405", (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405), { "405", (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405),
0 }, 0 },
{ "ppe42", (PPC_OPCODE_PPE),
0 },
{ "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 { "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
| PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
0 }, 0 },
{ "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 { "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
| PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
0 }, 0 },
{ "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_440 { "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_440
| PPC_OPCODE_476 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5), | PPC_OPCODE_476 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
0 }, 0 },
{ "601", (PPC_OPCODE_PPC | PPC_OPCODE_601), { "601", (PPC_OPCODE_PPC | PPC_OPCODE_601),
0 }, 0 },
...@@ -84,8 +86,8 @@ struct ppc_mopt ppc_opts[] = { ...@@ -84,8 +86,8 @@ struct ppc_mopt ppc_opts[] = {
{ "750cl", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS) { "750cl", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS)
, 0 }, , 0 },
{ "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4 { "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
| PPC_OPCODE_A2), | PPC_OPCODE_A2),
0 }, 0 },
{ "altivec", (PPC_OPCODE_PPC), { "altivec", (PPC_OPCODE_PPC),
PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 }, PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 },
...@@ -96,61 +98,61 @@ struct ppc_mopt ppc_opts[] = { ...@@ -96,61 +98,61 @@ struct ppc_mopt ppc_opts[] = {
{ "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE), { "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE),
0 }, 0 },
{ "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC), | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
0 }, 0 },
{ "com", (PPC_OPCODE_COMMON), { "com", (PPC_OPCODE_COMMON),
0 }, 0 },
{ "e300", (PPC_OPCODE_PPC | PPC_OPCODE_E300), { "e300", (PPC_OPCODE_PPC | PPC_OPCODE_E300),
0 }, 0 },
{ "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE { "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500), | PPC_OPCODE_E500),
0 }, 0 },
{ "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL { "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500MC), | PPC_OPCODE_E500MC),
0 }, 0 },
{ "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL { "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
| PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
0 }, 0 },
{ "e5500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL { "e5500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_POWER7), | PPC_OPCODE_POWER7),
0 }, 0 },
{ "e6500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL { "e6500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
0 }, 0 },
{ "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE { "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500), | PPC_OPCODE_E500),
0 }, 0 },
{ "efs", (PPC_OPCODE_PPC | PPC_OPCODE_EFS), { "efs", (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
0 }, 0 },
{ "power4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4), { "power4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4),
0 }, 0 },
{ "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5), | PPC_OPCODE_POWER5),
0 }, 0 },
{ "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
0 }, 0 },
{ "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 { "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
0 }, 0 },
{ "power8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 { "power8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX), | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX),
0 }, 0 },
{ "ppc", (PPC_OPCODE_PPC), { "ppc", (PPC_OPCODE_PPC),
0 }, 0 },
...@@ -169,29 +171,29 @@ struct ppc_mopt ppc_opts[] = { ...@@ -169,29 +171,29 @@ struct ppc_mopt ppc_opts[] = {
{ "pwr4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4), { "pwr4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4),
0 }, 0 },
{ "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5), | PPC_OPCODE_POWER5),
0 }, 0 },
{ "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5), | PPC_OPCODE_POWER5),
0 }, 0 },
{ "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 { "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
0 }, 0 },
{ "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 { "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
0 }, 0 },
{ "pwr8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 { "pwr8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX), | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX),
0 }, 0 },
{ "pwrx", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2), { "pwrx", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2),
0 }, 0 },
{ "spe", (PPC_OPCODE_PPC | PPC_OPCODE_EFS), { "spe", (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
PPC_OPCODE_SPE }, PPC_OPCODE_SPE },
{ "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR { "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
| PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN), | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
0 }, 0 },
{ "vle", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE), { "vle", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE),
PPC_OPCODE_VLE }, PPC_OPCODE_VLE },
...@@ -230,14 +232,14 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) ...@@ -230,14 +232,14 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
if (strcmp (ppc_opts[i].opt, arg) == 0) if (strcmp (ppc_opts[i].opt, arg) == 0)
{ {
if (ppc_opts[i].sticky) if (ppc_opts[i].sticky)
{ {
*sticky |= ppc_opts[i].sticky; *sticky |= ppc_opts[i].sticky;
if ((ppc_cpu & ~*sticky) != 0) if ((ppc_cpu & ~*sticky) != 0)
break; break;
} }
ppc_cpu = ppc_opts[i].cpu; ppc_cpu = ppc_opts[i].cpu;
break; break;
} }
if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0])) if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0]))
return 0; return 0;
...@@ -308,19 +310,19 @@ powerpc_init_dialect (struct disassemble_info *info) ...@@ -308,19 +310,19 @@ powerpc_init_dialect (struct disassemble_info *info)
char *end = strchr (arg, ','); char *end = strchr (arg, ',');
if (end != NULL) if (end != NULL)
*end = 0; *end = 0;
if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0) if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0)
dialect = new_cpu; dialect = new_cpu;
else if (strcmp (arg, "32") == 0) else if (strcmp (arg, "32") == 0)
dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
else if (strcmp (arg, "64") == 0) else if (strcmp (arg, "64") == 0)
dialect |= PPC_OPCODE_64; dialect |= PPC_OPCODE_64;
else else
fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg); fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg);
if (end != NULL) if (end != NULL)
*end++ = ','; *end++ = ',';
arg = end; arg = end;
} }
...@@ -354,7 +356,7 @@ disassemble_init_powerpc (struct disassemble_info *info) ...@@ -354,7 +356,7 @@ disassemble_init_powerpc (struct disassemble_info *info)
for (i = PPC_OPCD_SEGS; i > 0; --i) for (i = PPC_OPCD_SEGS; i > 0; --i)
{ {
if (powerpc_opcd_indices[i] == 0) if (powerpc_opcd_indices[i] == 0)
powerpc_opcd_indices[i] = last; powerpc_opcd_indices[i] = last;
last = powerpc_opcd_indices[i]; last = powerpc_opcd_indices[i];
} }
...@@ -371,7 +373,7 @@ disassemble_init_powerpc (struct disassemble_info *info) ...@@ -371,7 +373,7 @@ disassemble_init_powerpc (struct disassemble_info *info)
for (i = VLE_OPCD_SEGS; i > 0; --i) for (i = VLE_OPCD_SEGS; i > 0; --i)
{ {
if (vle_opcd_indices[i] == 0) if (vle_opcd_indices[i] == 0)
vle_opcd_indices[i] = last; vle_opcd_indices[i] = last;
last = vle_opcd_indices[i]; last = vle_opcd_indices[i];
} }
...@@ -379,6 +381,33 @@ disassemble_init_powerpc (struct disassemble_info *info) ...@@ -379,6 +381,33 @@ disassemble_init_powerpc (struct disassemble_info *info)
powerpc_init_dialect (info); powerpc_init_dialect (info);
} }
/* Calculate opcode table indices to speed up disassembly,
and init dialect. */
void
disassemble_init_powerpc_standalone ()
{
int i;
unsigned short last;
i = powerpc_num_opcodes;
while (--i >= 0)
{
unsigned op = PPC_OP (powerpc_opcodes[i].opcode);
powerpc_opcd_indices[op] = i;
}
last = powerpc_num_opcodes;
for (i = PPC_OPCD_SEGS; i > 0; --i)
{
if (powerpc_opcd_indices[i] == 0)
powerpc_opcd_indices[i] = last;
last = powerpc_opcd_indices[i];
}
}
/* Print a big endian PowerPC instruction. */ /* Print a big endian PowerPC instruction. */
int int
...@@ -407,7 +436,7 @@ print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info) ...@@ -407,7 +436,7 @@ print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
static long static long
operand_value_powerpc (const struct powerpc_operand *operand, operand_value_powerpc (const struct powerpc_operand *operand,
unsigned long insn, ppc_cpu_t dialect) unsigned long insn, ppc_cpu_t dialect)
{ {
long value; long value;
int invalid; int invalid;
...@@ -417,20 +446,20 @@ operand_value_powerpc (const struct powerpc_operand *operand, ...@@ -417,20 +446,20 @@ operand_value_powerpc (const struct powerpc_operand *operand,
else else
{ {
if (operand->shift >= 0) if (operand->shift >= 0)
value = (insn >> operand->shift) & operand->bitm; value = (insn >> operand->shift) & operand->bitm;
else else
value = (insn << -operand->shift) & operand->bitm;