summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-06-05 14:03:13 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-06-05 14:03:13 +0000
commit22e99c434fb65ca8a9d5e3dbf5db5965681ce5c3 (patch)
tree94160e71564d9458c544925ddc75eebf16f9a930 /llvm/lib/Target
parent66296dc3e4c5356b9c2b8443125b10b9ca41e435 (diff)
downloadbcm5719-llvm-22e99c434fb65ca8a9d5e3dbf5db5965681ce5c3.tar.gz
bcm5719-llvm-22e99c434fb65ca8a9d5e3dbf5db5965681ce5c3.zip
[MIPS GlobalISel] Select fcmp
Select floating point compare for MIPS32. Differential Revision: https://reviews.llvm.org/D62721 llvm-svn: 362603
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/MipsInstructionSelector.cpp79
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp4
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp11
3 files changed, 94 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 442244af609..8fddcca4cfe 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -11,6 +11,7 @@
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//
+#include "MCTargetDesc/MipsInstPrinter.h"
#include "MipsMachineFunction.h"
#include "MipsRegisterBankInfo.h"
#include "MipsTargetMachine.h"
@@ -492,6 +493,84 @@ bool MipsInstructionSelector::select(MachineInstr &I,
I.eraseFromParent();
return true;
}
+ case G_FCMP: {
+ unsigned MipsFCMPCondCode;
+ bool isLogicallyNegated;
+ switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
+ I.getOperand(1).getPredicate())) {
+ case CmpInst::FCMP_UNO: // Unordered
+ case CmpInst::FCMP_ORD: // Ordered (OR)
+ MipsFCMPCondCode = Mips::FCOND_UN;
+ isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
+ break;
+ case CmpInst::FCMP_OEQ: // Equal
+ case CmpInst::FCMP_UNE: // Not Equal (NEQ)
+ MipsFCMPCondCode = Mips::FCOND_OEQ;
+ isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
+ break;
+ case CmpInst::FCMP_UEQ: // Unordered or Equal
+ case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
+ MipsFCMPCondCode = Mips::FCOND_UEQ;
+ isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
+ break;
+ case CmpInst::FCMP_OLT: // Ordered or Less Than
+ case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
+ MipsFCMPCondCode = Mips::FCOND_OLT;
+ isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
+ break;
+ case CmpInst::FCMP_ULT: // Unordered or Less Than
+ case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
+ MipsFCMPCondCode = Mips::FCOND_ULT;
+ isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
+ break;
+ case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
+ case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
+ MipsFCMPCondCode = Mips::FCOND_OLE;
+ isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
+ break;
+ case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
+ case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
+ MipsFCMPCondCode = Mips::FCOND_ULE;
+ isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
+ break;
+ default:
+ return false;
+ }
+
+ // Default compare result in gpr register will be `true`.
+ // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
+ // using MOVF_I. When orignal predicate (Cond) is logically negated
+ // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
+ unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I;
+
+ unsigned TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
+ .addDef(TrueInReg)
+ .addUse(Mips::ZERO)
+ .addImm(1);
+
+ unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
+ unsigned FCMPOpcode =
+ Size == 32 ? Mips::FCMP_S32
+ : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32;
+ MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
+ .addUse(I.getOperand(2).getReg())
+ .addUse(I.getOperand(3).getReg())
+ .addImm(MipsFCMPCondCode);
+ if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI))
+ return false;
+
+ MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
+ .addDef(I.getOperand(0).getReg())
+ .addUse(Mips::ZERO)
+ .addUse(Mips::FCC0)
+ .addUse(TrueInReg);
+ if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
+ return false;
+
+ I.eraseFromParent();
+ return true;
+ }
default:
return false;
}
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index fcad2a9a857..cabaed8e303 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -97,6 +97,10 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
.legalFor({s32, s64});
+ getActionDefinitionsBuilder(G_FCMP)
+ .legalFor({{s32, s32}, {s32, s64}})
+ .minScalar(0, s32);
+
computeTables();
verify(*ST.getInstrInfo());
}
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 4814ef4b039..0f9d1064dda 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -149,6 +149,17 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
break;
}
+ case G_FCMP: {
+ unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
+ assert((Size == 32 || Size == 64) && "Unsupported floating point size");
+ const RegisterBankInfo::ValueMapping *FPRValueMapping =
+ Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
+ : &Mips::ValueMappings[Mips::DPRIdx];
+ OperandsMapping =
+ getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
+ FPRValueMapping, FPRValueMapping});
+ break;
+ }
case G_CONSTANT:
case G_FRAME_INDEX:
case G_GLOBAL_VALUE:
OpenPOWER on IntegriCloud