[llvm] r184946 - [PowerPC] Accept 17-bit signed immediates for addis

Ulrich Weigand ulrich.weigand at de.ibm.com
Wed Jun 26 06:49:53 PDT 2013


Author: uweigand
Date: Wed Jun 26 08:49:53 2013
New Revision: 184946

URL: http://llvm.org/viewvc/llvm-project?rev=184946&view=rev
Log:

[PowerPC] Accept 17-bit signed immediates for addis

The assembler currently strictly verifies that immediates for
s16imm operands are in range (-32768 ... 32767).  This matches
the behaviour of the GNU assembler, with one exception: gas
allows, as a special case, operands in an extended range
(-65536 .. 65535) for the addis instruction only (and its
extended mnemonic lis).

The main reason for this seems to be to allow using unsigned
16-bit operands for lis, e.g. like lis %r1, 0xfedc.

Since this has been supported by gas for a long time, and
assembler source code seen "in the wild" actually exploits
this feature, this patch adds equivalent support to LLVM
for compatibility reasons.


Modified:
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/trunk/test/MC/PowerPC/ppc64-errors.s
    llvm/trunk/test/MC/PowerPC/ppc64-operands.s

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=184946&r1=184945&r2=184946&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Wed Jun 26 08:49:53 2013
@@ -267,6 +267,8 @@ public:
   bool isS16ImmX4() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<16>(getImm()) &&
                                     (getImm() & 3) == 0); }
+  bool isS17Imm() const { return Kind == Expression ||
+                                 (Kind == Immediate && isInt<17>(getImm())); }
   bool isDirectBr() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<26>(getImm()) &&
                                     (getImm() & 3) == 0); }

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=184946&r1=184945&r2=184946&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Wed Jun 26 08:49:53 2013
@@ -25,6 +25,14 @@ def u16imm64 : Operand<i64> {
   let EncoderMethod = "getImm16Encoding";
   let ParserMatchClass = PPCU16ImmAsmOperand;
 }
+def s17imm64 : Operand<i64> {
+  // This operand type is used for addis/lis to allow the assembler parser
+  // to accept immediates in the range -65536..65535 for compatibility with
+  // the GNU assembler.  The operand is treated as 16-bit otherwise.
+  let PrintMethod = "printS16ImmOperand";
+  let EncoderMethod = "getImm16Encoding";
+  let ParserMatchClass = PPCS17ImmAsmOperand;
+}
 def tocentry : Operand<iPTR> {
   let MIOperandInfo = (ops i64imm:$imm);
 }
@@ -330,7 +338,7 @@ let isReMaterializable = 1, isAsCheapAsA
 def LI8  : DForm_2_r0<14, (outs g8rc:$rD), (ins s16imm64:$imm),
                       "li $rD, $imm", IntSimple,
                       [(set i64:$rD, imm64SExt16:$imm)]>;
-def LIS8 : DForm_2_r0<15, (outs g8rc:$rD), (ins s16imm64:$imm),
+def LIS8 : DForm_2_r0<15, (outs g8rc:$rD), (ins s17imm64:$imm),
                       "lis $rD, $imm", IntSimple,
                       [(set i64:$rD, imm16ShiftedSExt:$imm)]>;
 }
@@ -406,7 +414,7 @@ def ADDIC8 : DForm_2<12, (outs g8rc:$rD)
 def ADDI8  : DForm_2<14, (outs g8rc:$rD), (ins g8rc_nox0:$rA, s16imm64:$imm),
                      "addi $rD, $rA, $imm", IntSimple,
                      [(set i64:$rD, (add i64:$rA, imm64SExt16:$imm))]>;
-def ADDIS8 : DForm_2<15, (outs g8rc:$rD), (ins g8rc_nox0:$rA, s16imm64:$imm),
+def ADDIS8 : DForm_2<15, (outs g8rc:$rD), (ins g8rc_nox0:$rA, s17imm64:$imm),
                      "addis $rD, $rA, $imm", IntSimple,
                      [(set i64:$rD, (add i64:$rA, imm16ShiftedSExt:$imm))]>;
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=184946&r1=184945&r2=184946&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Jun 26 08:49:53 2013
@@ -446,6 +446,18 @@ def u16imm  : Operand<i32> {
   let EncoderMethod = "getImm16Encoding";
   let ParserMatchClass = PPCU16ImmAsmOperand;
 }
+def PPCS17ImmAsmOperand : AsmOperandClass {
+  let Name = "S17Imm"; let PredicateMethod = "isS17Imm";
+  let RenderMethod = "addImmOperands";
+}
+def s17imm  : Operand<i32> {
+  // This operand type is used for addis/lis to allow the assembler parser
+  // to accept immediates in the range -65536..65535 for compatibility with
+  // the GNU assembler.  The operand is treated as 16-bit otherwise.
+  let PrintMethod = "printS16ImmOperand";
+  let EncoderMethod = "getImm16Encoding";
+  let ParserMatchClass = PPCS17ImmAsmOperand;
+}
 def PPCDirectBrAsmOperand : AsmOperandClass {
   let Name = "DirectBr"; let PredicateMethod = "isDirectBr";
   let RenderMethod = "addBranchTargetOperands";
@@ -1519,7 +1531,7 @@ def ADDICo : DForm_2<13, (outs gprc:$rD)
                      "addic. $rD, $rA, $imm", IntGeneral,
                      []>, isDOT, RecFormRel;
 }
-def ADDIS  : DForm_2<15, (outs gprc:$rD), (ins gprc_nor0:$rA, s16imm:$imm),
+def ADDIS  : DForm_2<15, (outs gprc:$rD), (ins gprc_nor0:$rA, s17imm:$imm),
                      "addis $rD, $rA, $imm", IntSimple,
                      [(set i32:$rD, (add i32:$rA, imm16ShiftedSExt:$imm))]>;
 let isCodeGenOnly = 1 in
@@ -1539,7 +1551,7 @@ let isReMaterializable = 1, isAsCheapAsA
   def LI  : DForm_2_r0<14, (outs gprc:$rD), (ins s16imm:$imm),
                        "li $rD, $imm", IntSimple,
                        [(set i32:$rD, imm32SExt16:$imm)]>;
-  def LIS : DForm_2_r0<15, (outs gprc:$rD), (ins s16imm:$imm),
+  def LIS : DForm_2_r0<15, (outs gprc:$rD), (ins s17imm:$imm),
                        "lis $rD, $imm", IntSimple,
                        [(set i32:$rD, imm16ShiftedSExt:$imm)]>;
 }

Modified: llvm/trunk/test/MC/PowerPC/ppc64-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-errors.s?rev=184946&r1=184945&r2=184946&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-errors.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-errors.s Wed Jun 26 08:49:53 2013
@@ -32,6 +32,14 @@
 # CHECK-NEXT: ori 1, 2, 65536
               ori 1, 2, 65536
 
+# Signed 16-bit immediate operands (extended range for addis)
+
+# CHECK: error: invalid operand for instruction
+         addis 1, 0, -65537
+
+# CHECK: error: invalid operand for instruction
+         addis 1, 0, 65536
+
 # D-Form memory operands
 
 # CHECK: error: invalid register number

Modified: llvm/trunk/test/MC/PowerPC/ppc64-operands.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-operands.s?rev=184946&r1=184945&r2=184946&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-operands.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-operands.s Wed Jun 26 08:49:53 2013
@@ -40,6 +40,14 @@
 # CHECK: ori 1, 2, 65535                 # encoding: [0x60,0x41,0xff,0xff]
          ori 1, 2, 65535
 
+# Signed 16-bit immediate operands (extended range for addis)
+
+# CHECK: addis 1, 0, 0                   # encoding: [0x3c,0x20,0x00,0x00]
+         addis 1, 0, -65536
+
+# CHECK: addis 1, 0, -1                  # encoding: [0x3c,0x20,0xff,0xff]
+         addis 1, 0, 65535
+
 # D-Form memory operands
 
 # CHECK: lwz 1, 0(0)                     # encoding: [0x80,0x20,0x00,0x00]





More information about the llvm-commits mailing list