From 4d0eb637f0798726ef49d93ecb1e6ab371ab9ca3 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 7 Dec 2011 20:10:24 +0000 Subject: [PATCH] Fix 64-bit immediate patterns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146059 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips64InstrInfo.td | 23 ++++++++++++++++-- lib/Target/Mips/MipsISelDAGToDAG.cpp | 4 ++-- lib/Target/Mips/MipsInstrInfo.td | 4 ++-- test/CodeGen/Mips/mips64imm.ll | 35 ++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/Mips/mips64imm.ll diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index d5676120ba3..8a1245aa59d 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -25,7 +25,7 @@ def uimm16_64 : Operand { // Transformation Function - get Imm - 32. def Subtract32 : SDNodeXFormgetZExtValue() - 32); + return getImm(N, (unsigned)N->getZExtValue() - 32); }]>; // shamt field must fit in 5 bits. @@ -36,6 +36,19 @@ def imm32_63 : ImmLeaf= 32 && (int32_t)Imm < 64;}], Subtract32>; +// Is a 32-bit int. +def immSExt32 : ImmLeaf(Imm);}]>; + +// Transformation Function - get the higher 16 bits. +def HIGHER : SDNodeXFormgetZExtValue() >> 32) & 0xFFFF); +}]>; + +// Transformation Function - get the highest 16 bits. +def HIGHEST : SDNodeXFormgetZExtValue() >> 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 9c831ede9db..73c4a808ce3 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 fcf57af89c2..4cddd6b7fb9 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -194,12 +194,12 @@ def size_ins : Operand { // Transformation Function - get the lower 16 bits. def LO16 : SDNodeXFormgetZExtValue() & 0xFFFF); + return getImm(N, N->getZExtValue() & 0xFFFF); }]>; // Transformation Function - get the higher 16 bits. def HI16 : SDNodeXFormgetZExtValue() >> 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 00000000000..dca656c431c --- /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 +}