diff options
author | Zlatko Buljan <Zlatko.Buljan@imgtec.com> | 2016-03-24 09:22:45 +0000 |
---|---|---|
committer | Zlatko Buljan <Zlatko.Buljan@imgtec.com> | 2016-03-24 09:22:45 +0000 |
commit | 94af4cbcf4f9f937ee5eaf773cfb004e1b0385b2 (patch) | |
tree | 587efd255e18e666c43e50720f1083fec8a61f66 /llvm/lib | |
parent | ee675880b8df286b1271e9af1bfe8923c87ba9ba (diff) | |
download | bcm5719-llvm-94af4cbcf4f9f937ee5eaf773cfb004e1b0385b2.tar.gz bcm5719-llvm-94af4cbcf4f9f937ee5eaf773cfb004e1b0385b2.zip |
[mips][microMIPS] Add CodeGen support for DIV, MOD, DIVU, MODU, DDIV, DMOD, DDIVU and DMODU instructions
Differential Revision: http://reviews.llvm.org/D17137
llvm-svn: 264248
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 25 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 9 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 12 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 25 |
9 files changed, 89 insertions, 42 deletions
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index c8516ee4bc1..1c306048903 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -507,10 +507,27 @@ class RDHWR_MMR6_DESC : MMR6Arch<"rdhwr">, MipsR6Inst { class WAIT_MMR6_DESC : WaitMM<"wait">; class SSNOP_MMR6_DESC : Barrier<"ssnop">; class SLL_MMR6_DESC : shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>; -class DIV_MMR6_DESC : ArithLogicR<"div", GPR32Opnd>; -class DIVU_MMR6_DESC : ArithLogicR<"divu", GPR32Opnd>; -class MOD_MMR6_DESC : ArithLogicR<"mod", GPR32Opnd>; -class MODU_MMR6_DESC : ArithLogicR<"modu", GPR32Opnd>; + +class DIVMOD_MMR6_DESC_BASE<string opstr, RegisterOperand GPROpnd, + SDPatternOperator OpNode=null_frag> + : MipsR6Inst { + dag OutOperandList = (outs GPROpnd:$rd); + dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt); + string AsmString = !strconcat(opstr, "\t$rd, $rs, $rt"); + list<dag> Pattern = [(set GPROpnd:$rd, (OpNode GPROpnd:$rs, GPROpnd:$rt))]; + string BaseOpcode = opstr; + Format f = FrmR; + let isCommutable = 0; + let isReMaterializable = 1; + + // This instruction doesn't trap division by zero itself. We must insert + // teq instructions as well. + bit usesCustomInserter = 1; +} +class DIV_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"div", GPR32Opnd, sdiv>; +class DIVU_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"divu", GPR32Opnd, udiv>; +class MOD_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"mod", GPR32Opnd, srem>; +class MODU_MMR6_DESC : DIVMOD_MMR6_DESC_BASE<"modu", GPR32Opnd, urem>; class AND_MMR6_DESC : ArithLogicR<"and", GPR32Opnd>; class ANDI_MMR6_DESC : ArithLogicI<"andi", uimm16, GPR32Opnd>; class NOR_MMR6_DESC : ArithLogicR<"nor", GPR32Opnd>; diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td index febe62def7f..d091e6ac551 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -71,16 +71,16 @@ class POOL32S_DALIGN_FM_MMR6 { class POOL32A_DIVMOD_FM_MMR6<string instr_asm, bits<9> funct> : MMR6Arch<instr_asm> { - bits<5> rd; - bits<5> rs; bits<5> rt; + bits<5> rs; + bits<5> rd; bits<32> Inst; let Inst{31-26} = 0b010110; - let Inst{25-21} = rd; + let Inst{25-21} = rt; let Inst{20-16} = rs; - let Inst{15-11} = rt; + let Inst{15-11} = rd; let Inst{10-9} = 0b00; let Inst{8-0} = funct; } diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td index bf4404879dc..74e228728b4 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -91,10 +91,10 @@ class DALIGN_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, class DALIGN_MMR6_DESC : DALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>; -class DDIV_MM64R6_DESC : ArithLogicR<"ddiv", GPR32Opnd>; -class DMOD_MM64R6_DESC : ArithLogicR<"dmod", GPR32Opnd>; -class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>; -class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>; +class DDIV_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddiv", GPR64Opnd, sdiv>; +class DMOD_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmod", GPR64Opnd, srem>; +class DDIVU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddivu", GPR64Opnd, udiv>; +class DMODU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmodu", GPR64Opnd, urem>; class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32, uimm5_inssize_plus1, MipsIns>; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 3557a489332..3381c16c92e 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -696,9 +696,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def MULTu_MM : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM_MM<0x26c>; def SDIV_MM : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ac>; + MULT_FM_MM<0x2ac>, ISA_MIPS1_NOT_32R6_64R6; def UDIV_MM : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM_MM<0x2ec>; + MULT_FM_MM<0x2ec>, ISA_MIPS1_NOT_32R6_64R6; /// Arithmetic Instructions with PC and Immediate def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM; @@ -998,6 +998,11 @@ class UncondBranchMMPseudo<string opstr> : def B_MM_Pseudo : UncondBranchMMPseudo<"b">, ISA_MICROMIPS; +def SDIV_MM_Pseudo : MultDivPseudo<SDIV_MM, ACC64, GPR32Opnd, MipsDivRem, + II_DIV, 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; +def UDIV_MM_Pseudo : MultDivPseudo<UDIV_MM, ACC64, GPR32Opnd, MipsDivRemU, + II_DIVU, 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; + def : MipsInstAlias<"wait", (WAIT_MM 0x0), 1>; def : MipsInstAlias<"nop", (SLL_MM ZERO, ZERO, 0), 1>; def : MipsInstAlias<"nop", (MOVE16_MM ZERO, ZERO), 1>; diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index f3bd2bf275f..6247898cf92 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -746,8 +746,10 @@ def CLO_R6 : R6MMR6Rel, CLO_R6_ENC, CLO_R6_DESC, ISA_MIPS32R6; def CLZ_R6 : R6MMR6Rel, CLZ_R6_ENC, CLZ_R6_DESC, ISA_MIPS32R6; defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGR32Opnd>; defm D : CMP_CC_M<FIELD_CMP_FORMAT_D, "d", FGR64Opnd>; -def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; -def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; + def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; +} def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6; def JIC : R6MMR6Rel, JIC_ENC, JIC_DESC, ISA_MIPS32R6; def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6; @@ -769,8 +771,10 @@ let AdditionalPredicates = [NotInMicroMips] in { def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT; def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT; } -def MOD : R6MMR6Rel, MOD_ENC, MOD_DESC, ISA_MIPS32R6; -def MODU : R6MMR6Rel, MODU_ENC, MODU_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def MOD : R6MMR6Rel, MOD_ENC, MOD_DESC, ISA_MIPS32R6; + def MODU : R6MMR6Rel, MODU_ENC, MODU_DESC, ISA_MIPS32R6; +} let AdditionalPredicates = [NotInMicroMips] in { def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT; def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT; diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 206afad4a86..63ff4aba2e6 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -223,10 +223,12 @@ def PseudoDMULT : MultDivPseudo<DMULT, ACC128, GPR64Opnd, MipsMult, II_DMULT>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDMULTu : MultDivPseudo<DMULTu, ACC128, GPR64Opnd, MipsMultu, II_DMULTU>, ISA_MIPS3_NOT_32R6_64R6; -def DSDIV : Div<"ddiv", II_DDIV, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1e>, ISA_MIPS3_NOT_32R6_64R6; -def DUDIV : Div<"ddivu", II_DDIVU, GPR64Opnd, [HI0_64, LO0_64]>, - MULT_FM<0, 0x1f>, ISA_MIPS3_NOT_32R6_64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DSDIV : Div<"ddiv", II_DDIV, GPR64Opnd, [HI0_64, LO0_64]>, + MULT_FM<0, 0x1e>, ISA_MIPS3_NOT_32R6_64R6; + def DUDIV : Div<"ddivu", II_DDIVU, GPR64Opnd, [HI0_64, LO0_64]>, + MULT_FM<0, 0x1f>, ISA_MIPS3_NOT_32R6_64R6; +} def PseudoDSDIV : MultDivPseudo<DSDIV, ACC128, GPR64Opnd, MipsDivRem, II_DDIV, 0, 1, 1>, ISA_MIPS3_NOT_32R6_64R6; def PseudoDUDIV : MultDivPseudo<DUDIV, ACC128, GPR64Opnd, MipsDivRemU, diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index ab93314e20a..b9b248eee1f 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -91,11 +91,13 @@ let AdditionalPredicates = [NotInMicroMips] in { def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; def DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6; def DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6; -def DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6; -def DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6; + def DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6; + def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6; + def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6; +} def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6; -def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6; -def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6; def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6; def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6; def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6; diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 2d9667102c6..be5f63f449d 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -908,7 +908,7 @@ addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC) static MachineBasicBlock *insertDivByZeroTrap(MachineInstr *MI, MachineBasicBlock &MBB, const TargetInstrInfo &TII, - bool Is64Bit) { + bool Is64Bit, bool IsMicroMips) { if (NoZeroDivCheck) return &MBB; @@ -916,7 +916,8 @@ static MachineBasicBlock *insertDivByZeroTrap(MachineInstr *MI, MachineBasicBlock::iterator I(MI); MachineInstrBuilder MIB; MachineOperand &Divisor = MI->getOperand(2); - MIB = BuildMI(MBB, std::next(I), MI->getDebugLoc(), TII.get(Mips::TEQ)) + MIB = BuildMI(MBB, std::next(I), MI->getDebugLoc(), + TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ)) .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill())) .addReg(Mips::ZERO).addImm(7); @@ -1016,14 +1017,29 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case Mips::DIVU: case Mips::MOD: case Mips::MODU: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false); + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, + false); + case Mips::SDIV_MM_Pseudo: + case Mips::UDIV_MM_Pseudo: + case Mips::SDIV_MM: + case Mips::UDIV_MM: + case Mips::DIV_MMR6: + case Mips::DIVU_MMR6: + case Mips::MOD_MMR6: + case Mips::MODU_MMR6: + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, true); case Mips::PseudoDSDIV: case Mips::PseudoDUDIV: case Mips::DDIV: case Mips::DDIVU: case Mips::DMOD: case Mips::DMODU: - return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true); + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false); + case Mips::DDIV_MM64R6: + case Mips::DDIVU_MM64R6: + case Mips::DMOD_MM64R6: + case Mips::DMODU_MM64R6: + return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, true); case Mips::SEL_D: return emitSEL_D(MI, BB); diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 889124d5986..9969b3b71be 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1801,11 +1801,12 @@ def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6; def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6; -def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; -def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, - MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; - +let AdditionalPredicates = [NotInMicroMips] in { + def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; + def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; +} def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>, ISA_MIPS1_NOT_32R6_64R6; def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>, @@ -1873,12 +1874,12 @@ def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>, ISA_MIPS32_NOT_32R6_64R6; } -def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV, - 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; -def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU, - 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; let AdditionalPredicates = [NotInMicroMips] in { -def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM; + def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV, + 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; + def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU, + 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; + def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM; } // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5, @@ -2218,10 +2219,10 @@ def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6; -def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), +def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt), "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; -def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), +def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt), "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6; def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), |