[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