From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18932 invoked by alias); 27 Aug 2009 22:29:54 -0000 Received: (qmail 18923 invoked by uid 22791); 27 Aug 2009 22:29:53 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_22,SPF_PASS X-Spam-Check-By: sourceware.org Received: from e33.co.us.ibm.com (HELO e33.co.us.ibm.com) (32.97.110.151) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 27 Aug 2009 22:29:43 +0000 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e33.co.us.ibm.com (8.14.3/8.13.1) with ESMTP id n7RMRdiC014299 for ; Thu, 27 Aug 2009 16:27:39 -0600 Received: from d03av01.boulder.ibm.com (d03av01.boulder.ibm.com [9.17.195.167]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id n7RMTd4H220344 for ; Thu, 27 Aug 2009 16:29:39 -0600 Received: from d03av01.boulder.ibm.com (loopback [127.0.0.1]) by d03av01.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n7RMTcnT025343 for ; Thu, 27 Aug 2009 16:29:39 -0600 Received: from [9.76.91.194] (sig-9-76-91-194.mts.ibm.com [9.76.91.194]) by d03av01.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id n7RMTa3q025242; Thu, 27 Aug 2009 16:29:37 -0600 Subject: Handle extrdi and large register rotate values From: Peter Bergner To: Alan Modra Cc: "binutils@sourceware.org" Content-Type: text/plain Date: Fri, 28 Aug 2009 00:02:00 -0000 Message-Id: <1251412176.5257.51.camel@otta> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2009-08/txt/msg00512.txt.bz2 Alan, Someone complained that the assembler rejects the following extended mnemonic (whereas the AIX and iSeries assemblers accept): extrdi rA,rS,6,58 (ie, rA = rS & 0x3f) This is mapped to "rldicl rA,rS,58+6,64-6", which complains that the SH value (58+6=64) is too large. Logically, the extrdi use above makes sense, since it's saying we just want to grab 6 bits starting at bit position 58. It's just that the rldicl handling doesn't accept SH values greater than the register size. At first, I thought about doing something like: -{"extrdi", 4, PPC64, "rldicl %0,%1,(%2)+(%3),64-(%2)"}, -{"extrdi.", 4, PPC64, "rldicl. %0,%1,(%2)+(%3),64-(%2)"}, +{"extrdi", 4, PPC64, "rldicl %0,%1,((%2)+(%3))&0x3f,64-(%2)"}, +{"extrdi.", 4, PPC64, "rldicl. %0,%1,((%2)+(%3))&0x3f,64-(%2)"}, but that would mean updating quite a few other ops similarly. Is the following patch acceptable to catch them all in one shot or do you prefer a change like the above? Peter Index: include/opcode/ppc.h =================================================================== --- include/opcode/ppc.h (revision 521) +++ include/opcode/ppc.h (working copy) @@ -329,6 +329,13 @@ extern const unsigned int num_powerpc_op /* This operand names a vector-scalar unit register. The disassembler prints these with a leading 'vs'. */ #define PPC_OPERAND_VSR (0x100000) + +/* This operand's value should be truncated to fit within the + range specified by its bitmask. Namely: + op &= o->bitm; + This can be used to handle register rotate bit shift values that + exceed the register size and convert them to their logical equivalents. */ +#define PPC_OPERAND_TRUNCATE (0x200000) /* The POWER and PowerPC assemblers use a few macros. We keep them with the operands table for simplicity. The macro table is an Index: gas/config/tc-ppc.c =================================================================== --- gas/config/tc-ppc.c (revision 521) +++ gas/config/tc-ppc.c (working copy) @@ -1629,6 +1629,9 @@ ppc_insert_operand (unsigned long insn, { long min, max, right; + if ((operand->flags & PPC_OPERAND_TRUNCATE) != 0) + val &= operand->bitm; + max = operand->bitm; right = max & -max; min = 0; Index: opcodes/ppc-opc.c =================================================================== --- opcodes/ppc-opc.c (revision 521) +++ opcodes/ppc-opc.c (working copy) @@ -418,14 +418,16 @@ const struct powerpc_operand powerpc_ope /* The SH field in an X or M form instruction. */ #define SH RSO + 1 #define SH_MASK (0x1f << 11) + { 0x1f, 11, NULL, NULL, PPC_OPERAND_TRUNCATE }, + /* The other UIMM field in a EVX form instruction. */ -#define EVUIMM SH +#define EVUIMM SH + 1 { 0x1f, 11, NULL, NULL, 0 }, /* The SH field in an MD form instruction. This is split. */ -#define SH6 SH + 1 +#define SH6 EVUIMM + 1 #define SH6_MASK ((0x1f << 11) | (1 << 1)) - { 0x3f, -1, insert_sh6, extract_sh6, 0 }, + { 0x3f, -1, insert_sh6, extract_sh6, PPC_OPERAND_TRUNCATE }, /* The SH field of the tlbwe instruction, which is optional. */ #define SHO SH6 + 1