This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Add support for Xilinx FP/APU to PowerPC
- From: Michael Eager <eager at eagercon dot com>
- To: binutils at sourceware dot org
- Date: Mon, 21 Apr 2008 11:33:07 -0700
- Subject: [PATCH] Add support for Xilinx FP/APU to PowerPC
Xilinx's PowerPC 405 and 440 processors have an Auxiliary
Processor Unit (APU) co-processor which is used to implement
floating point or other operations. This patch adds support
for the instructions used to control the APU. This also
separates the definitions of PPC403 and PPC405.
2008-04-21 Michael J. Eager <eager@eagercon.com>
* gas/config/tc-ppc.c: Add -m405, split definition
of PPC403 & PPC405
2008-04-21 Michael J. Eager <eager@eagercon.com>
* include/opcode/ppc.h: PPC_OPCODE_405: New CPU macro
PPC_OPERAND_FSL, PPC_OPERAND_FCR, PPC_OPERAND_UDI:
New field macros
2008-04-21 Michael J. Eager <eager@eagercon.com>
* opcodes/ppc-dis.c: Disassemble FSL/FCR/UDI fields
* opcodes/ppc-opc.c: FCRT, FSL, UDI_R[TABC]: New field macros
APU_MASK, APU_RT_MASK, APU_RA_MASK: New insn macros
PPC405: New processor macro
Add get/put/udi instructions
--
Michael Eager eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306 650-325-8077
Index: config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.136
diff -u -p -r1.136 tc-ppc.c
--- config/tc-ppc.c 14 Apr 2008 11:01:38 -0000 1.136
+++ config/tc-ppc.c 21 Apr 2008 18:10:32 -0000
@@ -849,11 +849,12 @@ parse_cpu (const char *arg)
/* Do all PPC750s have paired single ops? */
else if (strcmp (arg, "750cl") == 0)
ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_PPCPS;
- /* -m403 and -m405 mean to assemble for the PowerPC 403/405. */
- else if (strcmp (arg, "403") == 0
- || strcmp (arg, "405") == 0)
+ else if (strcmp (arg, "403") == 0)
ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
| PPC_OPCODE_403 | PPC_OPCODE_32);
+ else if (strcmp (arg, "405") == 0)
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_403 | PPC_OPCODE_405 | PPC_OPCODE_32);
else if (strcmp (arg, "440") == 0)
ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
@@ -1121,7 +1122,8 @@ PowerPC options:\n\
-m601 generate code for PowerPC 601\n\
-mppc, -mppc32, -m603, -m604\n\
generate code for PowerPC 603/604\n\
--m403, -m405 generate code for PowerPC 403/405\n\
+-m403 generate code for PowerPC 403\n\
+-m405 generate code for PowerPC 405\n\
-m440 generate code for PowerPC 440\n\
-m7400, -m7410, -m7450, -m7455\n\
generate code for PowerPC 7400/7410/7450/7455\n\
Index: opcode/ppc.h
===================================================================
RCS file: /cvs/src/src/include/opcode/ppc.h,v
retrieving revision 1.27
diff -u -p -r1.27 ppc.h
--- opcode/ppc.h 14 Apr 2008 11:01:38 -0000 1.27
+++ opcode/ppc.h 21 Apr 2008 16:59:11 -0000
@@ -152,6 +152,9 @@ extern const int powerpc_num_opcodes;
/* Opcode is supported by Power E500MC */
#define PPC_OPCODE_E500MC 0x20000000
+/* Opcode is supported by PowerPC 405 processor. */
+#define PPC_OPCODE_405 0x10000000
+
/* A macro to extract the major opcode from an instruction. */
#define PPC_OP(i) (((i) >> 26) & 0x3f)
@@ -302,6 +305,11 @@ extern const unsigned int num_powerpc_op
/* Valid range of operand is 0..n rather than 0..n-1. */
#define PPC_OPERAND_PLUS1 (0x10000)
+
+/* Xilinx APU and FSL related operands */
+#define PPC_OPERAND_FSL (0x20000)
+#define PPC_OPERAND_FCR (0x40000)
+#define PPC_OPERAND_UDI (0x80000)
/* The POWER and PowerPC assemblers use a few macros. We keep them
with the operands table for simplicity. The macro table is an
Index: ppc-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-dis.c,v
retrieving revision 1.31
diff -u -p -r1.31 ppc-dis.c
--- ppc-dis.c 14 Apr 2008 11:01:38 -0000 1.31
+++ ppc-dis.c 21 Apr 2008 17:25:20 -0000
@@ -75,9 +75,12 @@ powerpc_dialect (struct disassemble_info
&& strstr (info->disassembler_options, "440") != NULL)
dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_32
| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI;
+ else if (info->disassembler_options
+ && strstr (info->disassembler_options, "altivec") != NULL)
+ dialect |= PPC_OPCODE_ALTIVEC;
else
dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
- | PPC_OPCODE_COMMON | PPC_OPCODE_ALTIVEC);
+ | PPC_OPCODE_COMMON);
if (info->disassembler_options
&& strstr (info->disassembler_options, "power4") != NULL)
@@ -313,6 +316,12 @@ print_insn_powerpc (bfd_vma memaddr,
else if ((operand->flags & PPC_OPERAND_CR) == 0
|| (dialect & PPC_OPCODE_PPC) == 0)
(*info->fprintf_func) (info->stream, "%ld", value);
+ else if ((operand->flags & PPC_OPERAND_FSL) != 0)
+ (*info->fprintf_func) (info->stream, "fsl%ld", value);
+ else if ((operand->flags & PPC_OPERAND_FCR) != 0)
+ (*info->fprintf_func) (info->stream, "fcr%ld", value);
+ else if ((operand->flags & PPC_OPERAND_UDI) != 0)
+ (*info->fprintf_func) (info->stream, "%ld", value);
else
{
if (operand->bitm == 7)
Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.105
diff -u -p -r1.105 ppc-opc.c
--- ppc-opc.c 14 Apr 2008 11:01:38 -0000 1.105
+++ ppc-opc.c 21 Apr 2008 17:25:32 -0000
@@ -576,6 +576,30 @@ const struct powerpc_operand powerpc_ope
/* The L field in an mtfsf or XFL form instruction. */
#define XFL_L EH + 1
{ 0x1, 25, NULL, NULL, PPC_OPERAND_OPTIONAL},
+
+ /* Xilinx APU related masks and macros */
+#define FCRT XFL_L + 1
+#define FCRT_MASK (0x1f << 21)
+ { 0x1f, 21, 0, 0, PPC_OPERAND_FCR },
+
+ /* Xilinx FSL related masks and macros */
+#define FSL FCRT + 1
+#define FSL_MASK (0x1f << 11)
+ { 0x1f, 11, 0, 0, PPC_OPERAND_FSL },
+
+ /* Xilinx UDI related masks and macros */
+#define UDI_RT FSL + 1
+ { 0x1f, 21, 0, 0, PPC_OPERAND_UDI },
+
+#define UDI_RA UDI_RT + 1
+ { 0x1f, 16, 0, 0, PPC_OPERAND_UDI },
+
+#define UDI_RB UDI_RA + 1
+ { 0x1f, 11, 0, 0, PPC_OPERAND_UDI },
+
+#define UDI_RC UDI_RB + 1
+ { 0x1f, 6, 0, 0, PPC_OPERAND_UDI },
+
};
const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
@@ -1205,12 +1229,9 @@ insert_sprg (unsigned long insn,
int dialect,
const char **errmsg)
{
- /* This check uses PPC_OPCODE_403 because PPC405 is later defined
- as a synonym. If ever a 405 specific dialect is added this
- check should use that instead. */
if (value > 7
|| (value > 3
- && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
+ && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_405)) == 0))
*errmsg = _("invalid sprg number");
/* If this is mfsprg4..7 then use spr 260..263 which can be read in
@@ -1597,6 +1618,14 @@ extract_tbr (unsigned long insn,
/* The mask for a G form instruction. rc not supported at present. */
#define XW_MASK XW (0x3f, 0x3f, 0)
+/* An APU form instruction. */
+#define APU(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff) )
+
+/* The mask for an APU form instruction. */
+#define APU_MASK APU (0x3f, 0x7ff)
+#define APU_RT_MASK (APU_MASK | RT_MASK)
+#define APU_RA_MASK (APU_MASK | RA_MASK)
+
/* The BO encodings used in extended conditional branch mnemonics. */
#define BODNZF (0x0)
#define BODNZFP (0x1)
@@ -1664,7 +1693,7 @@ extract_tbr (unsigned long insn,
#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC
#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC
#define PPC403 PPC_OPCODE_403
-#define PPC405 PPC403
+#define PPC405 PPC_OPCODE_405
#define PPC440 PPC_OPCODE_440
#define PPC750 PPC
#define PPC7450 PPC
@@ -2316,8 +2345,68 @@ const struct powerpc_opcode powerpc_opco
{"maclhwso.", XO (4, 492,1,1),XO_MASK, PPC405|PPC440, {RT, RA, RB}},
{"nmaclhwso", XO (4, 494,1,0),XO_MASK, PPC405|PPC440, {RT, RA, RB}},
{"nmaclhwso.", XO (4, 494,1,1),XO_MASK, PPC405|PPC440, {RT, RA, RB}},
+
+{"get", APU(4,536), APU_RA_MASK, PPC405 | PPC32, { RT, FSL } },
+{"cget", APU(4,568), APU_RA_MASK, PPC405 | PPC32, { RT, FSL } },
+{"nget", APU(4,600), APU_RA_MASK, PPC405 | PPC32, { RT, FSL } },
+{"ncget", APU(4,632), APU_RA_MASK, PPC405 | PPC32, { RT, FSL } },
+{"put", APU(4,664), APU_RT_MASK, PPC405 | PPC32, { RA, FSL } },
+{"cput", APU(4,696), APU_RT_MASK, PPC405 | PPC32, { RA, FSL } },
+{"nput", APU(4,728), APU_RT_MASK, PPC405 | PPC32, { RA, FSL } },
+{"ncput", APU(4,760), APU_RT_MASK, PPC405 | PPC32, { RA, FSL } },
+
{"dcbz_l", X (4,1014), XRT_MASK, PPCPS, {RA, RB}},
+{"udi0fcm.", APU(4,1030), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi0fcm", APU(4,1031), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi1fcm.", APU(4,1094), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi1fcm", APU(4,1095), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi2fcm.", APU(4,1158), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi2fcm", APU(4,1159), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi3fcm.", APU(4,1222), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi3fcm", APU(4,1223), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi4fcm.", APU(4,1286), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi4fcm", APU(4,1287), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi5fcm.", APU(4,1350), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi5fcm", APU(4,1351), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi6fcm.", APU(4,1414), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi6fcm", APU(4,1415), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi7fcm.", APU(4,1478), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi7fcm", APU(4,1479), APU_MASK, PPC405 | PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi8fcm.", APU(4,1542), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi8fcm", APU(4,1543), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi9fcm.", APU(4,1606), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi9fcm", APU(4,1607), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi10fcm.", APU(4,1670), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi10fcm", APU(4,1671), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi11fcm.", APU(4,1734), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi11fcm", APU(4,1735), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi12fcm.", APU(4,1798), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi12fcm", APU(4,1799), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi13fcm.", APU(4,1862), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi13fcm", APU(4,1862), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi14fcm.", APU(4,1926), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi14fcm", APU(4,1927), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi15fcm.", APU(4,1990), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+{"udi15fcm", APU(4,1991), APU_MASK, PPC440 | PPC32, { UDI_RT, UDI_RA, UDI_RB } },
+
+{"udi0fcmwc", A(4,8,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi1fcmwc", A(4,9,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi2fcmwc", A(4,10,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi3fcmwc", A(4,11,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi4fcmwc", A(4,12,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi5fcmwc", A(4,13,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi6fcmwc", A(4,14,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi7fcmwc", A(4,15,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi8fcmwc", A(4,16,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi9fcmwc", A(4,17,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi10fcmwc", A(4,18,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi11fcmwc", A(4,19,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi12fcmwc", A(4,20,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi13fcmwc", A(4,21,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi14fcmwc", A(4,22,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+{"udi15fcmwc", A(4,23,0), A_MASK, PPC440, { UDI_RT, UDI_RA, UDI_RB, UDI_RC } },
+
{"mulli", OP(7), OP_MASK, PPCCOM, {RT, RA, SI}},
{"muli", OP(7), OP_MASK, PWRCOM, {RT, RA, SI}},
@@ -3221,6 +3310,28 @@ const struct powerpc_opcode powerpc_opco
{"lwzx", X(31,23), X_MASK, PPCCOM, {RT, RA0, RB}},
{"lx", X(31,23), X_MASK, PWRCOM, {RT, RA, RB}},
+{"lbfcmux", APU(31,1038), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lhfcmux", APU(31,1102), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lwfcmux", APU(31,1166), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"ldfcmux", APU(31,1550), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lqfcmux", APU(31,1230), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lbfcmx", APU(31,14), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lhfcmx", APU(31,78), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lwfcmx", APU(31,142), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"ldfcmx", APU(31,526), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"lqfcmx", APU(31,206), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+
+{"stbfcmux", APU(31,1294), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"sthfcmux", APU(31,1358), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stwfcmux", APU(31,1422), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stdfcmux", APU(31,1806), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stqfcmux", APU(31,1486), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stbfcmx", APU(31,270), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"sthfcmx", APU(31,334), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stwfcmx", APU(31,398), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stdfcmx", APU(31,782), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+{"stqfcmx", APU(31,462), APU_MASK, PPC405 | PPC32, { FCRT, RA, RB } },
+
{"slw", XRC(31,24,0), X_MASK, PPCCOM, {RA, RS, RB}},
{"sl", XRC(31,24,0), X_MASK, PWRCOM, {RA, RS, RB}},
{"slw.", XRC(31,24,1), X_MASK, PPCCOM, {RA, RS, RB}},