Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
ppe42-binutils
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
OpenPOWER Firmware
ppe42-binutils
Commits
5b161fc3
Commit
5b161fc3
authored
Jul 26, 2016
by
Doug Gilbert
Committed by
Patrick Williams
Aug 15, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PowerPC PPE42 modifications
parent
237df3fa
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1464 additions
and
885 deletions
+1464
-885
bfd/bfd-in2.h
bfd/bfd-in2.h
+1
-0
bfd/elf32-ppc.c
bfd/elf32-ppc.c
+19
-0
bfd/libbfd.h
bfd/libbfd.h
+1
-0
bfd/reloc.c
bfd/reloc.c
+2
-0
configure.ac
configure.ac
+1
-1
elfcpp/powerpc.h
elfcpp/powerpc.h
+3
-0
gas/config/tc-ppc.c
gas/config/tc-ppc.c
+78
-1
include/elf/ppc.h
include/elf/ppc.h
+3
-0
include/opcode/ppc.h
include/opcode/ppc.h
+12
-0
opcodes/ppc-dis.c
opcodes/ppc-dis.c
+363
-188
opcodes/ppc-opc.c
opcodes/ppc-opc.c
+981
-695
No files found.
bfd/bfd-in2.h
View file @
5b161fc3
...
...
@@ -3183,6 +3183,7 @@ instruction. */
BFD_RELOC_PPC_EMB_RELST_HA
,
BFD_RELOC_PPC_EMB_BIT_FLD
,
BFD_RELOC_PPC_EMB_RELSDA
,
BFD_RELOC_PPC_PPE_REL10
,
BFD_RELOC_PPC_VLE_REL8
,
BFD_RELOC_PPC_VLE_REL15
,
BFD_RELOC_PPC_VLE_REL24
,
...
...
bfd/elf32-ppc.c
View file @
5b161fc3
...
...
@@ -1402,6 +1402,22 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
0xffff
,
/* dst_mask */
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. */
HOWTO
(
R_PPC_VLE_REL8
,
/* type */
1
,
/* rightshift */
...
...
@@ -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_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_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_REL15
:
r
=
R_PPC_VLE_REL15
;
break
;
case
BFD_RELOC_PPC_VLE_REL24
:
r
=
R_PPC_VLE_REL24
;
break
;
...
...
@@ -4121,6 +4138,7 @@ ppc_elf_check_relocs (bfd *abfd,
}
break
;
case
R_PPC_PPE_REL10
:
case
R_PPC_VLE_REL8
:
case
R_PPC_VLE_REL15
:
case
R_PPC_VLE_REL24
:
...
...
@@ -8236,6 +8254,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
case
R_PPC_UADDR16
:
goto
dodyn
;
case
R_PPC_PPE_REL10
:
case
R_PPC_VLE_REL8
:
case
R_PPC_VLE_REL15
:
case
R_PPC_VLE_REL24
:
...
...
bfd/libbfd.h
View file @
5b161fc3
...
...
@@ -1359,6 +1359,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_EMB_RELST_HA"
,
"BFD_RELOC_PPC_EMB_BIT_FLD"
,
"BFD_RELOC_PPC_EMB_RELSDA"
,
"BFD_RELOC_PPC_PPE_REL10"
,
"BFD_RELOC_PPC_VLE_REL8"
,
"BFD_RELOC_PPC_VLE_REL15"
,
"BFD_RELOC_PPC_VLE_REL24"
,
...
...
bfd/reloc.c
View file @
5b161fc3
...
...
@@ -2815,6 +2815,8 @@ ENUMX
BFD_RELOC_PPC_EMB_BIT_FLD
ENUMX
BFD_RELOC_PPC_EMB_RELSDA
ENUMX
BFD_RELOC_PPC_PPE_REL10
ENUMX
BFD_RELOC_PPC_VLE_REL8
ENUMX
...
...
configure.ac
View file @
5b161fc3
...
...
@@ -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
# "make check" in that particular order.
# 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="target-libffi \
...
...
elfcpp/powerpc.h
View file @
5b161fc3
...
...
@@ -177,6 +177,8 @@ enum
R_PPC64_DTPREL16_HIGHA
=
115
,
R_PPC_EMB_RELSDA
=
116
,
R_PPC_PPE_REL10
=
200
,
R_PPC_VLE_REL8
=
216
,
R_PPC_VLE_REL15
=
217
,
R_PPC_VLE_REL24
=
218
,
...
...
@@ -204,6 +206,7 @@ enum
R_POWERPC_GNU_VTINHERIT
=
253
,
R_POWERPC_GNU_VTENTRY
=
254
,
R_PPC_TOC16
=
255
,
};
// e_flags values defined for powerpc
...
...
gas/config/tc-ppc.c
View file @
5b161fc3
...
...
@@ -364,6 +364,36 @@ static const struct pd_reg pre_defined_registers[] =
{
"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 */
{
"dec"
,
22
},
/* Decrementer */
{
"dsisr"
,
18
},
/* Data Storage Interrupt Status Register */
...
...
@@ -1272,6 +1302,7 @@ PowerPC options:\n\
generate code for PowerPC 603/604
\n
\
-m403 generate code for PowerPC 403
\n
\
-m405 generate code for PowerPC 405
\n
\
-mppe42 generate code for PowerPC ppe
\n
\
-m440 generate code for PowerPC 440
\n
\
-m464 generate code for PowerPC 464
\n
\
-m476 generate code for PowerPC 476
\n
\
...
...
@@ -1362,7 +1393,7 @@ ppc_arch (void)
const
char
*
default_cpu
=
TARGET_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
;
if
((
ppc_cpu
&
PPC_OPCODE_VLE
)
!=
0
)
return
bfd_arch_powerpc
;
...
...
@@ -1820,6 +1851,47 @@ ppc_insert_operand (unsigned long insn,
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
)
{
const
char
*
errmsg
;
...
...
@@ -3255,6 +3327,10 @@ md_assemble (char *str)
&&
operand
->
bitm
==
0xfffc
&&
operand
->
shift
==
0
)
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
&&
operand
->
bitm
==
0x1fe
&&
operand
->
shift
==
-
1
)
...
...
@@ -7030,6 +7106,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case
BFD_RELOC_24_PLT_PCREL
:
case
BFD_RELOC_32_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_REL15
:
case
BFD_RELOC_PPC_VLE_REL24
:
...
...
include/elf/ppc.h
View file @
5b161fc3
...
...
@@ -131,6 +131,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
RELOC_NUMBER
(
R_PPC_EMB_BIT_FLD
,
115
)
RELOC_NUMBER
(
R_PPC_EMB_RELSDA
,
116
)
/* PowerPC PPE relocations. */
RELOC_NUMBER
(
R_PPC_PPE_REL10
,
200
)
/* PowerPC VLE relocations. */
RELOC_NUMBER
(
R_PPC_VLE_REL8
,
216
)
RELOC_NUMBER
(
R_PPC_VLE_REL15
,
217
)
...
...
include/opcode/ppc.h
View file @
5b161fc3
...
...
@@ -191,6 +191,9 @@ extern const int vle_num_opcodes;
/* Opcode is only supported by Power8 architecture. */
#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. */
/* 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. */
...
...
@@ -386,6 +389,12 @@ extern const unsigned int num_powerpc_operands;
with the operands table for simplicity. The macro table is an
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
{
/* The macro name. */
...
...
@@ -409,5 +418,8 @@ extern const struct powerpc_macro powerpc_macros[];
extern
const
int
powerpc_num_macros
;
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 */
opcodes/ppc-dis.c
View file @
5b161fc3
...
...
@@ -34,7 +34,7 @@
in both big and little endian mode and also for the POWER (RS/6000)
chip. */
static
int
print_insn_powerpc
(
bfd_vma
,
struct
disassemble_info
*
,
int
,
ppc_cpu_t
);
ppc_cpu_t
);
struct
dis_private
{
...
...
@@ -56,14 +56,16 @@ struct ppc_mopt ppc_opts[] = {
0
},
{
"405"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_403
|
PPC_OPCODE_405
),
0
},
{
"ppe42"
,
(
PPC_OPCODE_PPE
),
0
},
{
"440"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_440
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_RFMCI
),
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_RFMCI
),
0
},
{
"464"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_440
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_RFMCI
),
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_RFMCI
),
0
},
{
"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
},
{
"601"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_601
),
0
},
...
...
@@ -84,8 +86,8 @@ struct ppc_mopt ppc_opts[] = {
{
"750cl"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_PPCPS
)
,
0
},
{
"a2"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_64
|
PPC_OPCODE_A2
),
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_64
|
PPC_OPCODE_A2
),
0
},
{
"altivec"
,
(
PPC_OPCODE_PPC
),
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
},
...
...
@@ -96,61 +98,61 @@ struct ppc_mopt ppc_opts[] = {
{
"booke32"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
),
0
},
{
"cell"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_CELL
|
PPC_OPCODE_ALTIVEC
),
|
PPC_OPCODE_CELL
|
PPC_OPCODE_ALTIVEC
),
0
},
{
"com"
,
(
PPC_OPCODE_COMMON
),
0
},
{
"e300"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_E300
),
0
},
{
"e500"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_SPE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_EFS
|
PPC_OPCODE_BRLOCK
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500
),
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_EFS
|
PPC_OPCODE_BRLOCK
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500
),
0
},
{
"e500mc"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
),
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
),
0
},
{
"e500mc64"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
0
},
{
"e5500"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
0
},
{
"e6500"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_E6500
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500MC
|
PPC_OPCODE_64
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_E6500
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
),
0
},
{
"e500x2"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_SPE
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_EFS
|
PPC_OPCODE_BRLOCK
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500
),
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_EFS
|
PPC_OPCODE_BRLOCK
|
PPC_OPCODE_PMR
|
PPC_OPCODE_CACHELCK
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_E500
),
0
},
{
"efs"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_EFS
),
0
},
{
"power4"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
),
0
},
{
"power5"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
),
|
PPC_OPCODE_POWER5
),
0
},
{
"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
},
{
"power7"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_VSX
),
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_VSX
),
0
},
{
"power8"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_POWER8
|
PPC_OPCODE_HTM
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_VSX
),
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_POWER8
|
PPC_OPCODE_HTM
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_VSX
),
0
},
{
"ppc"
,
(
PPC_OPCODE_PPC
),
0
},
...
...
@@ -169,29 +171,29 @@ struct ppc_mopt ppc_opts[] = {
{
"pwr4"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
),
0
},
{
"pwr5"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
),
|
PPC_OPCODE_POWER5
),
0
},
{
"pwr5x"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
),
|
PPC_OPCODE_POWER5
),
0
},
{
"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
},
{
"pwr7"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_VSX
),
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_VSX
),
0
},
{
"pwr8"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
PPC_OPCODE_64
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_POWER8
|
PPC_OPCODE_HTM
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_VSX
),
|
PPC_OPCODE_POWER4
|
PPC_OPCODE_POWER5
|
PPC_OPCODE_POWER6
|
PPC_OPCODE_POWER7
|
PPC_OPCODE_POWER8
|
PPC_OPCODE_HTM
|
PPC_OPCODE_ALTIVEC
|
PPC_OPCODE_ALTIVEC2
|
PPC_OPCODE_VSX
),
0
},
{
"pwrx"
,
(
PPC_OPCODE_POWER
|
PPC_OPCODE_POWER2
),
0
},
{
"spe"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_EFS
),
PPC_OPCODE_SPE
},
{
"titan"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_BOOKE
|
PPC_OPCODE_PMR
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_TITAN
),
|
PPC_OPCODE_RFMCI
|
PPC_OPCODE_TITAN
),
0
},
{
"vle"
,
(
PPC_OPCODE_PPC
|
PPC_OPCODE_ISEL
|
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)
for
(
i
=
0
;
i
<
sizeof
(
ppc_opts
)
/
sizeof
(
ppc_opts
[
0
]);
i
++
)
if
(
strcmp
(
ppc_opts
[
i
].
opt
,
arg
)
==
0
)
{
if
(
ppc_opts
[
i
].
sticky
)
{
*
sticky
|=
ppc_opts
[
i
].
sticky
;
if
((
ppc_cpu
&
~*
sticky
)
!=
0
)
break
;
}
ppc_cpu
=
ppc_opts
[
i
].
cpu
;
break
;
if
(
ppc_opts
[
i
].
sticky
)
{
*
sticky
|=
ppc_opts
[
i
].
sticky
;
if
((
ppc_cpu
&
~*
sticky
)
!=
0
)
break
;
}
ppc_cpu
=
ppc_opts
[
i
].
cpu
;
break
;
}
if
(
i
>=
sizeof
(
ppc_opts
)
/
sizeof
(
ppc_opts
[
0
]))
return
0
;
...
...
@@ -308,19 +310,19 @@ powerpc_init_dialect (struct disassemble_info *info)
char
*
end
=
strchr
(
arg
,
','
);
if
(
end
!=
NULL
)
*
end
=
0
;
*
end
=
0
;
if
((
new_cpu
=
ppc_parse_cpu
(
dialect
,
&
sticky
,
arg
))
!=
0
)
dialect
=
new_cpu
;
dialect
=
new_cpu
;
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
)
dialect
|=
PPC_OPCODE_64
;
dialect
|=
PPC_OPCODE_64
;
else
fprintf
(
stderr
,
_
(
"warning: ignoring unknown -M%s option
\n
"
),
arg
);
fprintf
(
stderr
,
_
(
"warning: ignoring unknown -M%s option
\n
"
),
arg
);
if
(
end
!=
NULL
)
*
end
++
=
','
;
*
end
++
=
','
;
arg
=
end
;
}
...
...
@@ -354,7 +356,7 @@ disassemble_init_powerpc (struct disassemble_info *info)
for
(
i
=
PPC_OPCD_SEGS
;
i
>
0
;
--
i
)
{
if
(
powerpc_opcd_indices
[
i
]
==
0
)
powerpc_opcd_indices
[
i
]
=
last
;
powerpc_opcd_indices
[
i
]
=
last
;
last
=
powerpc_opcd_indices
[
i
];
}
...
...
@@ -371,7 +373,7 @@ disassemble_init_powerpc (struct disassemble_info *info)
for
(
i
=
VLE_OPCD_SEGS
;
i
>
0
;
--
i
)
{
if
(
vle_opcd_indices
[
i
]
==
0
)
vle_opcd_indices
[
i
]
=
last
;
vle_opcd_indices
[
i
]
=
last
;
last
=
vle_opcd_indices
[
i
];
}
...
...
@@ -379,6 +381,33 @@ disassemble_init_powerpc (struct disassemble_info *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. */
int
...
...
@@ -407,7 +436,7 @@ print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
static
long
operand_value_powerpc
(
const
struct
powerpc_operand
*
operand
,
unsigned
long
insn
,
ppc_cpu_t
dialect
)
unsigned
long
insn
,
ppc_cpu_t
dialect
)
{
long
value
;
int
invalid
;
...
...
@@ -417,20 +446,20 @@ operand_value_powerpc (const struct powerpc_operand *operand,
else
{
if
(
operand
->
shift
>=
0
)
value
=
(
insn
>>
operand
->
shift
)
&
operand
->
bitm
;
value
=
(
insn
>>
operand
->
shift
)
&
operand
->
bitm
;
else
value
=
(
insn
<<
-
operand
->
shift
)
&
operand
->
bitm
;
value
=
(
insn
<<
-
operand
->
shift
)
&
operand
->
bitm
;
if
((
operand
->
flags
&
PPC_OPERAND_SIGNED
)
!=
0
)
{
/* BITM is always some number of zeros followed by some
number of ones, followed by some number of zeros. */
unsigned
long
top
=
operand
->
bitm
;
/* top & -top gives the rightmost 1 bit, so this
fills in any trailing zeros. */
top
|=
(
top
&
-
top
)
-
1
;
top
&=
~
(
top
>>
1
);
value
=
(
value
^
top
)
-
top
;
}
{
/* BITM is always some number of zeros followed by some
number of ones, followed by some number of zeros. */
unsigned
long
top
=
operand
->
bitm
;
/* top & -top gives the rightmost 1 bit, so this
fills in any trailing zeros. */
top
|=
(
top
&
-
top
)
-
1
;
top
&=
~
(
top
>>
1
);
value
=
(
value
^
top
)
-
top
;
}
}
return
value
;
...
...
@@ -440,7 +469,7 @@ operand_value_powerpc (const struct powerpc_operand *operand,
static
int
skip_optional_operands
(
const
unsigned
char
*
opindex
,
unsigned
long
insn
,
ppc_cpu_t
dialect
)
unsigned
long
insn
,
ppc_cpu_t
dialect
)
{
const
struct
powerpc_operand
*
operand
;
...
...
@@ -448,9 +477,9 @@ skip_optional_operands (const unsigned char *opindex,
{
operand
=
&
powerpc_operands
[
*
opindex
];
if
((
operand
->
flags
&
PPC_OPERAND_NEXT
)
!=
0
||
((
operand
->
flags
&
PPC_OPERAND_OPTIONAL
)
!=
0
&&
operand_value_powerpc
(
operand
,
insn
,
dialect
)
!=
0
))
return
0
;
||
((
operand
->
flags
&
PPC_OPERAND_OPTIONAL
)
!=
0
&&
operand_value_powerpc
(
operand
,
insn
,
dialect
)
!=
0
))
return
0
;
}
return
1
;
...
...
@@ -480,21 +509,21 @@ lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
int
invalid
;
if
((
insn
&
opcode
->
mask
)
!=
opcode
->
opcode
||
(
dialect
!=
(
ppc_cpu_t
)
-
1
&&
((
opcode
->
flags
&
dialect
)
==
0
||
(
opcode
->
deprecated
&
dialect
)
!=
0
)))
continue
;
||
(
dialect
!=
(
ppc_cpu_t
)
-
1
&&
((
opcode
->
flags
&
dialect
)
==
0
||
(
opcode
->
deprecated
&
dialect
)
!=
0
)))
continue
;
/* Check validity of operands. */
invalid
=
0
;
for
(
opindex
=
opcode
->
operands
;
*
opindex
!=
0
;
opindex
++
)
{
operand
=
powerpc_operands
+
*
opindex
;
if
(
operand
->
extract
)
(
*
operand
->
extract
)
(
insn
,
dialect
,
&
invalid
);
}
{
operand
=
powerpc_operands
+
*
opindex
;
if
(
operand
->
extract
)
(
*
operand
->
extract
)
(
insn
,
dialect
,
&
invalid
);
}
if
(
invalid
)
continue
;
continue
;
return
opcode
;
}
...
...
@@ -535,20 +564,20 @@ lookup_vle (unsigned long insn)
insn2
=
insn
;
if
(
table_op_is_short
)
insn2
>>=
16
;
insn2
>>=
16
;
if
((
insn2
&
table_mask
)
!=
table_opcd
)
continue
;
continue
;
/* Check validity of operands. */
invalid
=
0
;
for
(
opindex
=
opcode
->
operands
;
*
opindex
!=
0
;
++
opindex
)
{
operand
=
powerpc_operands
+
*
opindex
;
if
(
operand
->
extract
)
(
*
operand
->
extract
)
(
insn
,
(
ppc_cpu_t
)
0
,
&
invalid
);
}
{
operand
=
powerpc_operands
+
*
opindex
;
if
(
operand
->
extract
)
(
*
operand
->
extract
)
(
insn
,
(
ppc_cpu_t
)
0
,
&
invalid
);
}
if
(
invalid
)
continue
;
continue
;
return
opcode
;
}
...
...
@@ -560,9 +589,9 @@ lookup_vle (unsigned long insn)
static
int
print_insn_powerpc
(
bfd_vma
memaddr
,
struct
disassemble_info
*
info
,
int
bigendian
,
ppc_cpu_t
dialect
)
struct
disassemble_info
*
info
,
int
bigendian
,
ppc_cpu_t
dialect
)
{
bfd_byte
buffer
[
4
];
int
status
;
...
...
@@ -604,7 +633,7 @@ print_insn_powerpc (bfd_vma memaddr,
{
opcode
=
lookup_vle
(
insn
);
if
(
opcode
!=
NULL
)
insn_is_short
=
PPC_OP_SE_VLE
(
opcode
->
mask
);
insn_is_short
=
PPC_OP_SE_VLE
(
opcode
->
mask
);
}
if
(
opcode
==
NULL
)
opcode
=
lookup_powerpc
(
insn
,
dialect
);
...
...
@@ -620,9 +649,9 @@ print_insn_powerpc (bfd_vma memaddr,
int
skip_optional
;
if
(
opcode
->
operands
[
0
]
!=
0
)
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"%-7s "
,
opcode
->
name
);
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"%-7s "
,
opcode
->
name
);
else
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"%s"
,
opcode
->
name
);
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"%s"
,
opcode
->
name
);
if
(
insn_is_short
)
/* The operands will be fetched out of the 16-bit instruction. */
...
...
@@ -633,91 +662,93 @@ print_insn_powerpc (bfd_vma memaddr,
need_paren
=
0
;
skip_optional
=
-
1
;
for
(
opindex
=
opcode
->
operands
;
*
opindex
!=
0
;
opindex
++
)
{
long
value
;
operand
=
powerpc_operands
+
*
opindex
;
/* Operands that are marked FAKE are simply ignored. We
already made sure that the extract function considered
the instruction to be valid. */
if
((
operand
->
flags
&
PPC_OPERAND_FAKE
)
!=
0
)
continue
;
/* If all of the optional operands have the value zero,
then don't print any of them. */
if
((
operand
->
flags
&
PPC_OPERAND_OPTIONAL
)
!=
0
)
{
if
(
skip_optional
<
0
)
skip_optional
=
skip_optional_operands
(
opindex
,
insn
,
dialect
);
if
(
skip_optional
)
continue
;
}
value
=
operand_value_powerpc
(
operand
,
insn
,
dialect
);
if
(
need_comma
)
{
(
*
info
->
fprintf_func
)
(
info
->
stream
,
","
);
need_comma
=
0
;
}
/* Print the operand as directed by the flags. */
if
((
operand
->
flags
&
PPC_OPERAND_GPR
)
!=
0
||
((
operand
->
flags
&
PPC_OPERAND_GPR_0
)
!=
0
&&
value
!=
0
))
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"r%ld"
,
value
);
else
if
((
operand
->
flags
&
PPC_OPERAND_FPR
)
!=
0
)
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"f%ld"
,
value
);
else
if
((
operand
->
flags
&
PPC_OPERAND_VR
)
!=
0
)
(
*
info
->
fprintf_func
)
(
info
->
stream
,
"v%ld"
,
value
);
else
if
((
operand
->
flags
&
PPC_OPERAND_VSR
)
!=
0
)