diff options
| author | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-06-05 14:03:13 +0000 |
|---|---|---|
| committer | Petar Avramovic <Petar.Avramovic@rt-rk.com> | 2019-06-05 14:03:13 +0000 |
| commit | 22e99c434fb65ca8a9d5e3dbf5db5965681ce5c3 (patch) | |
| tree | 94160e71564d9458c544925ddc75eebf16f9a930 /llvm/lib/Target | |
| parent | 66296dc3e4c5356b9c2b8443125b10b9ca41e435 (diff) | |
| download | bcm5719-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.cpp | 79 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp | 11 |
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: |

