diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-07 20:10:24 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-07 20:10:24 +0000 |
commit | 4d0eb637f0798726ef49d93ecb1e6ab371ab9ca3 (patch) | |
tree | 9243727e1951278d7e324d04ab5d1e5dafe65e35 | |
parent | 4f66a050a2f74fc065bbe5c5a564feb40ea03bae (diff) |
Fix 64-bit immediate patterns.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146059 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 23 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 4 | ||||
-rw-r--r-- | test/CodeGen/Mips/mips64imm.ll | 35 |
4 files changed, 60 insertions, 6 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index d5676120ba..8a1245aa59 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -25,7 +25,7 @@ def uimm16_64 : Operand<i64> { // Transformation Function - get Imm - 32. def Subtract32 : SDNodeXForm<imm, [{ - return getI32Imm((unsigned)N->getZExtValue() - 32); + return getImm(N, (unsigned)N->getZExtValue() - 32); }]>; // shamt field must fit in 5 bits. @@ -36,6 +36,19 @@ def imm32_63 : ImmLeaf<i32, [{return (int32_t)Imm >= 32 && (int32_t)Imm < 64;}], Subtract32>; +// Is a 32-bit int. +def immSExt32 : ImmLeaf<i64, [{return isInt<32>(Imm);}]>; + +// Transformation Function - get the higher 16 bits. +def HIGHER : SDNodeXForm<imm, [{ + return getImm(N, (N->getZExtValue() >> 32) & 0xFFFF); +}]>; + +// Transformation Function - get the highest 16 bits. +def HIGHEST : SDNodeXForm<imm, [{ + return getImm(N, (N->getZExtValue() >> 48) & 0xFFFF); +}]>; + //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// @@ -219,9 +232,15 @@ def : Pat<(i64 immSExt16:$in), def : Pat<(i64 immZExt16:$in), (ORi64 ZERO_64, imm:$in)>; +// 32-bit immediates +def : Pat<(i64 immSExt32:$imm), + (ORi64 (LUi64 (HI16 imm:$imm)), (LO16 imm:$imm))>; + // Arbitrary immediates def : Pat<(i64 imm:$imm), - (ORi64 (LUi64 (HI16 imm:$imm)), (LO16 imm:$imm))>; + (ORi64 (DSLL (ORi64 (DSLL (ORi64 (LUi64 (HIGHEST imm:$imm)), + (HIGHER imm:$imm)), 16), (HI16 imm:$imm)), 16), + (LO16 imm:$imm))>; // extended loads let Predicates = [NotN64] in { diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 9c831ede9d..73c4a808ce 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -88,8 +88,8 @@ private: // getI32Imm - Return a target constant with the specified // value, of type i32. - inline SDValue getI32Imm(unsigned Imm) { - return CurDAG->getTargetConstant(Imm, MVT::i32); + inline SDValue getImm(const SDNode *Node, unsigned Imm) { + return CurDAG->getTargetConstant(Imm, Node->getValueType(0)); } virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index fcf57af89c..4cddd6b7fb 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -194,12 +194,12 @@ def size_ins : Operand<i32> { // Transformation Function - get the lower 16 bits. def LO16 : SDNodeXForm<imm, [{ - return getI32Imm((unsigned)N->getZExtValue() & 0xFFFF); + return getImm(N, N->getZExtValue() & 0xFFFF); }]>; // Transformation Function - get the higher 16 bits. def HI16 : SDNodeXForm<imm, [{ - return getI32Imm((unsigned)N->getZExtValue() >> 16); + return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF); }]>; // Node immediate fits as 16-bit sign extended on target immediate. diff --git a/test/CodeGen/Mips/mips64imm.ll b/test/CodeGen/Mips/mips64imm.ll new file mode 100644 index 0000000000..dca656c431 --- /dev/null +++ b/test/CodeGen/Mips/mips64imm.ll @@ -0,0 +1,35 @@ +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s + +define i64 @foo3() nounwind readnone { +entry: +; CHECK: foo3 +; CHECK: lui $[[R0:[0-9]+]], 4660 +; CHECK: ori ${{[0-9]+}}, $[[R0]], 22136 + ret i64 305419896 +} + +define i64 @foo6() nounwind readnone { +entry: +; CHECK: foo6 +; CHECK: ori ${{[0-9]+}}, $zero, 33332 + ret i64 33332 +} + +define i64 @foo7() nounwind readnone { +entry: +; CHECK: foo7 +; CHECK: daddiu ${{[0-9]+}}, $zero, -32204 + ret i64 -32204 +} + +define i64 @foo9() nounwind readnone { +entry: +; CHECK: foo9 +; CHECK: lui $[[R0:[0-9]+]], 4660 +; CHECK: ori $[[R1:[0-9]+]], $[[R0]], 22136 +; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 16 +; CHECK: ori $[[R3:[0-9]+]], $[[R2]], 36882 +; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 16 +; CHECK: ori ${{[0-9]+}}, $[[R4]], 13398 + ret i64 1311768467284833366 +} |