This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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}},

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]