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] Fix POWER6 dquai assembly and disassembly


Steve Munroe noticed that the TE field in the DFP dquai instruction was only
accepting unsigned constants, but according to the documentation for that
instruction, the TE field should be a signed constant.  After fixing that,
I noticed that objdump couldn't disassemble the instruction.  I tracked
that down to Ben's checkin of the 750cl code that added some instructions
to the powerpc_opcodes table in unsorted order and the disassembler assumes
all instructions are sorted by major opcode order.  To catch this kind of
thing in the future, I added some extra checking code that verifies the
table is sorted according to major opcode number.

This passed bootstrap and regtesting on powerpc-linux using
--enable-targets=powerpc64-linux.  Ok for mainline?

Peter


gas/

	* config/tc-ppc.c (ppc_setup_opcodes): Verify instructions are sorted
	according to major opcode number.

opcodes/

	* ppc-opc.c (TE): Correct signedness.
	(powerpc_opcodes): Sort psq_st and psq_stu according to major
	opcode number.

Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.126
diff -u -p -r1.126 tc-ppc.c
--- gas/config/tc-ppc.c	24 Aug 2007 00:56:29 -0000	1.126
+++ gas/config/tc-ppc.c	16 Oct 2007 01:21:18 -0000
@@ -1249,6 +1249,7 @@ ppc_setup_opcodes (void)
   const struct powerpc_macro *macro;
   const struct powerpc_macro *macro_end;
   bfd_boolean bad_insn = FALSE;
+  unsigned long prev_opcode = 0;
 
   if (ppc_hash != NULL)
     hash_die (ppc_hash);
@@ -1296,6 +1297,17 @@ ppc_setup_opcodes (void)
 	{
 	  const unsigned char *o;
 	  unsigned long omask = op->mask;
+	  unsigned long major_opcode = PPC_OP (op->opcode);
+
+	  /* The major opcodes had better be sorted.  Code in the disassembler
+	     assumes the insns are sorted according to major opcode.  */
+	  if (major_opcode < prev_opcode)
+	    {
+	      as_bad (_("major opcode is not sorted for %s"),
+		      op->name);
+	      bad_insn = TRUE;
+	    }
+	  prev_opcode = major_opcode;
 
 	  /* The mask had better not trim off opcode bits.  */
 	  if ((op->opcode & omask) != op->opcode)

Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.99
diff -u -p -r1.99 ppc-opc.c
--- opcodes/ppc-opc.c	24 Aug 2007 00:56:30 -0000	1.99
+++ opcodes/ppc-opc.c	16 Oct 2007 01:21:19 -0000
@@ -492,13 +492,13 @@ const struct powerpc_operand powerpc_ope
 #define VS VD
   { 0x1f, 21, NULL, NULL, PPC_OPERAND_VR },
 
-  /* The SIMM field in a VX form instruction.  */
+  /* The SIMM field in a VX form instruction, and TE in Z form.  */
 #define SIMM VD + 1
+#define TE SIMM
   { 0x1f, 16, NULL, NULL, PPC_OPERAND_SIGNED},
 
-  /* The UIMM field in a VX form instruction, and TE in Z form.  */
+  /* The UIMM field in a VX form instruction.  */
 #define UIMM SIMM + 1
-#define TE UIMM
   { 0x1f, 16, NULL, NULL, 0 },
 
   /* The SHB field in a VA form instruction.  */
@@ -4495,9 +4495,6 @@ const struct powerpc_opcode powerpc_opco
 { "fnmadds", A(59,31,0), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
 { "fnmadds.",A(59,31,1), A_MASK,	PPC,		{ FRT,FRA,FRC,FRB } },
 
-{ "psq_st",  OP(60),    OP_MASK,        PPCPS,          { FRS, PSD, RA, PSW, PSQ } },
-{ "psq_stu", OP(61),    OP_MASK,        PPCPS,          { FRS, PSD, RA, PSW, PSQ } },
-
 { "dmul",    XRC(59,34,0), X_MASK,	POWER6,		{ FRT, FRA, FRB } },
 { "dmul.",   XRC(59,34,1), X_MASK,	POWER6,		{ FRT, FRA, FRB } },
 
@@ -4561,6 +4558,9 @@ const struct powerpc_opcode powerpc_opco
 
 { "stfq",    OP(60),	OP_MASK,	POWER2,		{ FRS, D, RA } },
 
+{ "psq_st",  OP(60),    OP_MASK,        PPCPS,          { FRS, PSD, RA, PSW, PSQ } },
+{ "psq_stu", OP(61),    OP_MASK,        PPCPS,          { FRS, PSD, RA, PSW, PSQ } },
+
 { "stfqu",   OP(61),	OP_MASK,	POWER2,		{ FRS, D, RA } },
 
 { "stfdp",   OP(61),	OP_MASK,	POWER6,		{ FRT, D, RA0 } },


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