summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
diff options
context:
space:
mode:
authorPetar Jovanovic <petar.jovanovic@mips.com>2018-09-10 15:56:52 +0000
committerPetar Jovanovic <petar.jovanovic@mips.com>2018-09-10 15:56:52 +0000
commitce4dd0ae38378b30281e24cd0d2126e6912eb110 (patch)
tree54e7720c3c0199a86c66ef554e112194723b0164 /llvm/lib/Target/Mips/MipsInstructionSelector.cpp
parentd76177869a9005f71f134dc0a1920c12665f347d (diff)
downloadbcm5719-llvm-ce4dd0ae38378b30281e24cd0d2126e6912eb110.tar.gz
bcm5719-llvm-ce4dd0ae38378b30281e24cd0d2126e6912eb110.zip
[MIPS GlobalISel] Select icmp
Select 32bit integer compare instructions for MIPS32. Patch by Petar Avramovic. Differential Revision: https://reviews.llvm.org/D51489 llvm-svn: 341840
Diffstat (limited to 'llvm/lib/Target/Mips/MipsInstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 6c5b83021f7..fbc15649c8a 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -15,6 +15,7 @@
#include "MipsRegisterBankInfo.h"
#include "MipsTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#define DEBUG_TYPE "mips-isel"
@@ -193,7 +194,85 @@ bool MipsInstructionSelector::select(MachineInstr &I,
I.eraseFromParent();
return true;
}
+ case G_ICMP: {
+ struct Instr {
+ unsigned Opcode, Def, LHS, RHS;
+ Instr(unsigned Opcode, unsigned Def, unsigned LHS, unsigned RHS)
+ : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
+
+ bool hasImm() const {
+ if (Opcode == Mips::SLTiu || Opcode == Mips::XORi)
+ return true;
+ return false;
+ }
+ };
+
+ SmallVector<struct Instr, 2> Instructions;
+ unsigned ICMPReg = I.getOperand(0).getReg();
+ unsigned Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+ unsigned LHS = I.getOperand(2).getReg();
+ unsigned RHS = I.getOperand(3).getReg();
+ CmpInst::Predicate Cond =
+ static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
+
+ switch (Cond) {
+ case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
+ Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
+ Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
+ break;
+ case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
+ Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
+ Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
+ break;
+ case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS
+ Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
+ break;
+ case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
+ Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
+ Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
+ break;
+ case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS
+ Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
+ break;
+ case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
+ Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
+ Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
+ break;
+ case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS
+ Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
+ break;
+ case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
+ Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
+ Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
+ break;
+ case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS
+ Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
+ break;
+ case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
+ Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
+ Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
+ break;
+ default:
+ return false;
+ }
+
+ MachineIRBuilder B(I);
+ for (const struct Instr &Instruction : Instructions) {
+ MachineInstrBuilder MIB =
+ B.buildInstr(Instruction.Opcode, Instruction.Def, Instruction.LHS);
+
+ if (Instruction.hasImm())
+ MIB.addImm(Instruction.RHS);
+ else
+ MIB.addUse(Instruction.RHS);
+
+ if (!MIB.constrainAllUses(TII, TRI, RBI))
+ return false;
+ }
+ I.eraseFromParent();
+ return true;
+ }
default:
return false;
}
OpenPOWER on IntegriCloud