summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r--llvm/lib/Target/Mips/Mips64InstrInfo.td39
-rw-r--r--llvm/lib/Target/Mips/Mips64r6InstrInfo.td15
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp7
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.h3
4 files changed, 64 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index bc80098ade8..878ec29b188 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -825,6 +825,45 @@ def : MipsPat<(atomic_store_32 addr:$a, GPR64:$v), (SW64 GPR64:$v, addr:$a)>,
def : MipsPat<(atomic_store_64 addr:$a, GPR64:$v), (SD GPR64:$v, addr:$a)>,
ISA_MIPS3, GPR_64;
+// Patterns used for matching away redundant sign extensions.
+// MIPS32 arithmetic instructions sign extend their result implicitly.
+def : MipsPat<(i64 (sext (i32 (add GPR32:$src, immSExt16:$imm16)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (ADDiu GPR32:$src, immSExt16:$imm16), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (add GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (ADDu GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sub GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SUBu GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (mul GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MUL GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (MipsMFHI ACC64:$src)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (PseudoMFHI ACC64:$src), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (MipsMFLO ACC64:$src)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (PseudoMFLO ACC64:$src), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (shl GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SLL GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (shl GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SLLV GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (srl GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRL GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (srl GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRLV GPR32:$src, GPR32:$src2), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sra GPR32:$src, immZExt5:$imm5)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRA GPR32:$src, immZExt5:$imm5), sub_32)>;
+def : MipsPat<(i64 (sext (i32 (sra GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (SRAV GPR32:$src, GPR32:$src2), sub_32)>;
+
//===----------------------------------------------------------------------===//
// Instruction aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
index 853702c30dd..9df802cc30b 100644
--- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td
@@ -299,6 +299,21 @@ def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f),
(SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>,
ISA_MIPS64R6;
+// Patterns used for matching away redundant sign extensions.
+// MIPS32 arithmetic instructions sign extend their result implicitly.
+def : MipsPat<(i64 (sext (i32 (sdiv GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (DIV GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (udiv GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (DIVU GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (srem GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MOD GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+def : MipsPat<(i64 (sext (i32 (urem GPR32:$src, GPR32:$src2)))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
+ (MODU GPR32:$src, GPR32:$src2), sub_32)>, ISA_MIPS64R6;
+
// Pseudo instructions
let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index ba4dbefa21a..9ffc38356b7 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3714,6 +3714,13 @@ static std::pair<bool, bool> parsePhysicalReg(StringRef C, StringRef &Prefix,
true);
}
+EVT MipsTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
+ ISD::NodeType) const {
+ bool Cond = !Subtarget.isABI_O32() && VT.getSizeInBits() == 32;
+ EVT MinVT = getRegisterType(Context, Cond ? MVT::i64 : MVT::i32);
+ return VT.bitsLT(MinVT) ? MinVT : VT;
+}
+
std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {
const TargetRegisterInfo *TRI =
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 7e5d6a2a017..b58d92c370d 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -280,6 +280,9 @@ class TargetRegisterClass;
return MVT::i32;
}
+ EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
+ ISD::NodeType) const override;
+
bool isCheapToSpeculateCttz() const override;
bool isCheapToSpeculateCtlz() const override;
OpenPOWER on IntegriCloud