diff options
author | Petar Jovanovic <petar.jovanovic@mips.com> | 2018-10-08 23:59:37 +0000 |
---|---|---|
committer | Petar Jovanovic <petar.jovanovic@mips.com> | 2018-10-08 23:59:37 +0000 |
commit | aa97890d664508b93986942f28357e8540c47673 (patch) | |
tree | 2c857e85b66bdb16c94d52719b5eb555f83a0be1 /llvm/lib/Target | |
parent | c9dac6b9b4b06db99fc21251c104a77086a08c15 (diff) | |
download | bcm5719-llvm-aa97890d664508b93986942f28357e8540c47673.tar.gz bcm5719-llvm-aa97890d664508b93986942f28357e8540c47673.zip |
[MIPS GlobalISel] Legalize i64 add
Custom legalize s64 G_ADD for MIPS32.
Patch by Petar Avramovic.
Differential Revision: https://reviews.llvm.org/D52652
llvm-svn: 344007
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsLegalizerInfo.h | 3 |
2 files changed, 50 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp index 4da1fb205e5..6a16e7955a1 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -13,6 +13,7 @@ #include "MipsLegalizerInfo.h" #include "MipsTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" using namespace llvm; @@ -20,11 +21,13 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { using namespace TargetOpcode; const LLT s32 = LLT::scalar(32); + const LLT s64 = LLT::scalar(64); const LLT p0 = LLT::pointer(0, 32); getActionDefinitionsBuilder(G_ADD) .legalFor({s32}) - .minScalar(0, s32); + .minScalar(0, s32) + .customFor({s64}); getActionDefinitionsBuilder({G_LOAD, G_STORE}) .legalForCartesianProduct({p0, s32}, {p0}); @@ -51,3 +54,46 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { computeTables(); verify(*ST.getInstrInfo()); } + +bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI, + MachineRegisterInfo &MRI, + MachineIRBuilder &MIRBuilder) const { + + using namespace TargetOpcode; + + MIRBuilder.setInstr(MI); + + switch (MI.getOpcode()) { + case G_ADD: { + unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); + + const LLT sHalf = LLT::scalar(Size / 2); + + unsigned RHSLow = MRI.createGenericVirtualRegister(sHalf); + unsigned RHSHigh = MRI.createGenericVirtualRegister(sHalf); + unsigned LHSLow = MRI.createGenericVirtualRegister(sHalf); + unsigned LHSHigh = MRI.createGenericVirtualRegister(sHalf); + unsigned ResLow = MRI.createGenericVirtualRegister(sHalf); + unsigned ResHigh = MRI.createGenericVirtualRegister(sHalf); + unsigned Carry = MRI.createGenericVirtualRegister(sHalf); + unsigned TmpResHigh = MRI.createGenericVirtualRegister(sHalf); + + MIRBuilder.buildUnmerge({RHSHigh, RHSLow}, MI.getOperand(2).getReg()); + MIRBuilder.buildUnmerge({LHSHigh, LHSLow}, MI.getOperand(1).getReg()); + + MIRBuilder.buildAdd(TmpResHigh, LHSHigh, RHSHigh); + MIRBuilder.buildAdd(ResLow, LHSLow, RHSLow); + MIRBuilder.buildICmp(CmpInst::ICMP_ULT, Carry, ResLow, LHSLow); + MIRBuilder.buildAdd(ResHigh, TmpResHigh, Carry); + + MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {ResHigh, ResLow}); + + MI.eraseFromParent(); + break; + } + default: + return false; + } + + return true; +} diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.h b/llvm/lib/Target/Mips/MipsLegalizerInfo.h index 36dd39c8c1c..96d95746ac8 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.h +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.h @@ -24,6 +24,9 @@ class MipsSubtarget; class MipsLegalizerInfo : public LegalizerInfo { public: MipsLegalizerInfo(const MipsSubtarget &ST); + + bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, + MachineIRBuilder &MIRBuilder) const override; }; } // end namespace llvm #endif |