Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -216,6 +216,10 @@ bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); + bool expandDiv(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions, const bool IsMips64, + const bool Signed); + bool expandUlhu(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -488,6 +492,10 @@ return STI.getFeatureBits()[Mips::FeatureMips16]; } + bool useTraps() const { + return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV]; + } + bool useSoftFloat() const { return STI.getFeatureBits()[Mips::FeatureSoftFloat]; } @@ -1821,6 +1829,10 @@ case Mips::BLEU: case Mips::BGEU: case Mips::BGTU: + case Mips::SDivMacro: + case Mips::UDivMacro: + case Mips::DSDivMacro: + case Mips::DUDivMacro: case Mips::Ulhu: case Mips::Ulw: return true; @@ -1876,6 +1888,14 @@ case Mips::BGEU: case Mips::BGTU: return expandCondBranches(Inst, IDLoc, Instructions); + case Mips::SDivMacro: + return expandDiv(Inst, IDLoc, Instructions, false, true); + case Mips::DSDivMacro: + return expandDiv(Inst, IDLoc, Instructions, true, true); + case Mips::UDivMacro: + return expandDiv(Inst, IDLoc, Instructions, false, false); + case Mips::DUDivMacro: + return expandDiv(Inst, IDLoc, Instructions, true, false); case Mips::Ulhu: return expandUlhu(Inst, IDLoc, Instructions); case Mips::Ulw: @@ -1899,6 +1919,29 @@ emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions); } +void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions); +} +void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + MCInst tmpInst; + tmpInst.setOpcode(Opcode); + tmpInst.addOperand(MCOperand::createImm(Imm1)); + tmpInst.addOperand(MCOperand::createImm(Imm2)); + tmpInst.setLoc(IDLoc); + Instructions.push_back(tmpInst); +} + +void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + MCInst tmpInst; + tmpInst.setOpcode(Opcode); + tmpInst.addOperand(MCOperand::createReg(Reg0)); + tmpInst.setLoc(IDLoc); + Instructions.push_back(tmpInst); +} + void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, SmallVectorImpl &Instructions) { MCInst tmpInst; @@ -2724,6 +2767,122 @@ return false; } +bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions, + const bool IsMips64, const bool Signed) { + if (hasMips32r6()) { + Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); + return false; + } + + warnIfNoMacro(IDLoc); + + const MCOperand &RsRegOp = Inst.getOperand(0); + assert(RsRegOp.isReg() && "expected register operand kind"); + unsigned RsReg = RsRegOp.getReg(); + + const MCOperand &RtRegOp = Inst.getOperand(1); + assert(RtRegOp.isReg() && "expected register operand kind"); + unsigned RtReg = RtRegOp.getReg(); + unsigned DivOp; + unsigned ZeroReg; + + if (IsMips64) { + DivOp = Signed ? Mips::DSDIV : Mips::DUDIV; + ZeroReg = Mips::ZERO_64; + } else { + DivOp = Signed ? Mips::SDIV : Mips::UDIV; + ZeroReg = Mips::ZERO; + } + + bool UseTraps = useTraps(); + + if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) { + if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) + Warning(IDLoc, "dividing zero by zero"); + if (IsMips64) { + if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) { + if (UseTraps) { + emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions); + return false; + } + + emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions); + return false; + } + } else { + emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions); + return false; + } + } + + if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) { + Warning(IDLoc, "division by zero"); + if (Signed) { + if (UseTraps) { + emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions); + return false; + } + + emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions); + return false; + } + } + + // FIXME: The values for these two BranchTarget variables may be different in + // micromips. These magic numbers need to be removed. + unsigned BranchTargetNoTraps; + unsigned BranchTarget; + + if (UseTraps) { + BranchTarget = IsMips64 ? 12 : 8; + emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions); + } else { + BranchTarget = IsMips64 ? 20 : 16; + BranchTargetNoTraps = 8; + // Branch to the li instruction. + emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, + Instructions); + } + + emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions); + + if (!UseTraps) + emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions); + + if (!Signed) { + emitR(Mips::MFLO, RsReg, IDLoc, Instructions); + return false; + } + + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + + emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions); + if (IsMips64) { + // Branch to the mflo instruction. + emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions); + emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions); + emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions); + } else { + // Branch to the mflo instruction. + emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions); + emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions); + } + + if (UseTraps) + emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions); + else { + // Branch to the mflo instruction. + emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions); + emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions); + emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions); + } + emitR(Mips::MFLO, RsReg, IDLoc, Instructions); + return false; +} + bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions) { if (hasMips32r6() || hasMips64r6()) { Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -164,6 +164,11 @@ "true", "Octeon cnMIPS Support", [FeatureMips64r2]>; +def FeatureUseTCCInDIV : SubtargetFeature< + "use-tcc-in-div", + "UseTCCInDIV", "false", + "Force the assembler to use trapping">; + //===----------------------------------------------------------------------===// // Mips processors supported. //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -205,6 +205,7 @@ def IsLE : Predicate<"Subtarget->isLittle()">; def IsBE : Predicate<"!Subtarget->isLittle()">; def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; +def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">; //===----------------------------------------------------------------------===// // Mips GPR size adjectives. @@ -1733,6 +1734,18 @@ def BGEU : CondBranchPseudo<"bgeu">; def BGTU : CondBranchPseudo<"bgtu">; +def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "div\t$rs, $rt">, ISA_MIPS1_NOT_32R6_64R6; + +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), + "ddiv\t$rs, $rt">, ISA_MIPS64_NOT_64R6; + +def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "ddivu\t$rs, $rt">, ISA_MIPS64_NOT_64R6; + def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), "ulhu\t$rt, $addr">, ISA_MIPS1_NOT_32R6_64R6; Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -130,6 +130,9 @@ // HasMSA -- supports MSA ASE. bool HasMSA; + // UseTCCInDIV -- Enables the use of trapping in the assembler. + bool UseTCCInDIV; + InstrItineraryData InstrItins; // We can override the determination of whether we are in mips16 mode Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -70,7 +70,7 @@ HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), - HasMSA(false), TM(TM), TargetTriple(TT), TSInfo(), + HasMSA(false), UseTCCInDIV(false), TM(TM), TargetTriple(TT), TSInfo(), InstrInfo( MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))), FrameLowering(MipsFrameLowering::create(*this)), Index: test/MC/Mips/macro-ddiv-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-ddiv-bad.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 + + .text + ddiv $25, $11 + # R6: :[[@LINE-1]]:3: error: instruction not supported on mips32r6 or mips64r6 + + ddiv $25, $0 + # NOT-R6: :[[@LINE-1]]:3: warning: division by zero + + ddiv $0,$0 + # NOT-R6: :[[@LINE-1]]:3: warning: dividing zero by zero Index: test/MC/Mips/macro-ddiv.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-ddiv.s @@ -0,0 +1,85 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r2 | \ +# RUN: FileCheck %s --check-prefix=CHECK-NOTRAP +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r2 \ +# RUN: -mattr=+use-tcc-in-div | FileCheck %s --check-prefix=CHECK-TRAP + + ddiv $25, $11 +# CHECK-NOTRAP: bne $11, $zero, 8 # encoding: [0x15,0x60,0x00,0x02] +# CHECK-NOTRAP: ddiv $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1e] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-NOTRAP: bne $11, $1, 20 # encoding: [0x15,0x61,0x00,0x05] +# CHECK-NOTRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-NOTRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-NOTRAP: bne $25, $1, 8 # encoding: [0x17,0x21,0x00,0x02] +# CHECK-NOTRAP: sll $zero, $zero, 0 # encoding: [0x00,0x00,0x00,0x00] +# CHECK-NOTRAP: break 6 # encoding: [0x00,0x06,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddiv $24,$12 +# CHECK-NOTRAP: bne $12, $zero, 8 # encoding: [0x15,0x80,0x00,0x02] +# CHECK-NOTRAP: ddiv $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1e] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-NOTRAP: bne $12, $1, 20 # encoding: [0x15,0x81,0x00,0x05] +# CHECK-NOTRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-NOTRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-NOTRAP: bne $24, $1, 8 # encoding: [0x17,0x01,0x00,0x02] +# CHECK-NOTRAP: sll $zero, $zero, 0 # encoding: [0x00,0x00,0x00,0x00] +# CHECK-NOTRAP: break 6 # encoding: [0x00,0x06,0x00,0x0d] +# CHECK-NOTRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + ddiv $25,$0 +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] + + ddiv $0,$9 +# CHECK-NOTRAP: bne $9, $zero, 8 # encoding: [0x15,0x20,0x00,0x02] +# CHECK-NOTRAP: ddiv $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1e] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-NOTRAP: bne $9, $1, 20 # encoding: [0x15,0x21,0x00,0x05] +# CHECK-NOTRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-NOTRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-NOTRAP: bne $zero, $1, 8 # encoding: [0x14,0x01,0x00,0x02] +# CHECK-NOTRAP: sll $zero, $zero, 0 # encoding: [0x00,0x00,0x00,0x00] +# CHECK-NOTRAP: break 6 # encoding: [0x00,0x06,0x00,0x0d] +# CHECK-NOTRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] + + ddiv $0,$0 +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] + + ddiv $25,$11 +# CHECK-TRAP: teq $11, $zero, 7 # encoding: [0x01,0x60,0x01,0xf4] +# CHECK-TRAP: ddiv $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1e] +# CHECK-TRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-TRAP: bne $11, $1, 12 # encoding: [0x15,0x61,0x00,0x03] +# CHECK-TRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-TRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-TRAP: teq $25, $1, 6 # encoding: [0x03,0x21,0x01,0xb4] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddiv $24,$12 +# CHECK-TRAP: teq $12, $zero, 7 # encoding: [0x01,0x80,0x01,0xf4] +# CHECK-TRAP: ddiv $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1e] +# CHECK-TRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-TRAP: bne $12, $1, 12 # encoding: [0x15,0x81,0x00,0x03] +# CHECK-TRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-TRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-TRAP: teq $24, $1, 6 # encoding: [0x03,0x01,0x01,0xb4] +# CHECK-TRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + ddiv $25,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] + + ddiv $0,$9 +# CHECK-TRAP: teq $9, $zero, 7 # encoding: [0x01,0x20,0x01,0xf4] +# CHECK-TRAP: ddiv $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1e] +# CHECK-TRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-TRAP: bne $9, $1, 12 # encoding: [0x15,0x21,0x00,0x03] +# CHECK-TRAP: addiu $1, $zero, 1 # encoding: [0x24,0x01,0x00,0x01] +# CHECK-TRAP: dsll32 $1, $1, 31 # encoding: [0x00,0x01,0x0f,0xfc] +# CHECK-TRAP: teq $zero, $1, 6 # encoding: [0x00,0x01,0x01,0xb4] +# CHECK-TRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] + + ddiv $0,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] Index: test/MC/Mips/macro-ddivu-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-ddivu-bad.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 + + .text + ddivu $25, $11 + # R6: :[[@LINE-1]]:3: error: instruction not supported on mips32r6 or mips64r6 + + ddivu $25, $0 + # NOT-R6: :[[@LINE-1]]:3: warning: division by zero + + ddivu $0,$0 + # NOT-R6: :[[@LINE-1]]:3: warning: dividing zero by zero Index: test/MC/Mips/macro-ddivu.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-ddivu.s @@ -0,0 +1,59 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r2 | \ +# RUN: FileCheck %s --check-prefix=CHECK-NOTRAP +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r2 \ +# RUN: -mattr=+use-tcc-in-div | FileCheck %s --check-prefix=CHECK-TRAP + + ddivu $25,$11 +# CHECK-NOTRAP: bne $11, $zero, 8 # encoding: [0x15,0x60,0x00,0x02] +# CHECK-NOTRAP: ddivu $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1f] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddivu $24,$12 +# CHECK-NOTRAP: bne $12, $zero, 8 # encoding: [0x15,0x80,0x00,0x02] +# CHECK-NOTRAP: ddivu $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1f] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + ddivu $25,$0 +# CHECK-NOTRAP: bne $zero, $zero, 8 # encoding: [0x14,0x00,0x00,0x02] +# CHECK-NOTRAP: ddivu $zero, $25, $zero # encoding: [0x03,0x20,0x00,0x1f] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddivu $0,$9 +# CHECK-NOTRAP: bne $9, $zero, 8 # encoding: [0x15,0x20,0x00,0x02] +# CHECK-NOTRAP: ddivu $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1f] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] + + ddivu $0,$0 +# CHECK-NOTRAP: bne $zero, $zero, 8 # encoding: [0x14,0x00,0x00,0x02] +# CHECK-NOTRAP: ddivu $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1f] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] + + ddivu $25, $11 +# CHECK-TRAP: teq $11, $zero, 7 # encoding: [0x01,0x60,0x01,0xf4] +# CHECK-TRAP: ddivu $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1f] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddivu $24,$12 +# CHECK-TRAP: teq $12, $zero, 7 # encoding: [0x01,0x80,0x01,0xf4] +# CHECK-TRAP: ddivu $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1f] +# CHECK-TRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + ddivu $25,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] +# CHECK-TRAP: ddivu $zero, $25, $zero # encoding: [0x03,0x20,0x00,0x1f] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + ddivu $0,$9 +# CHECK-TRAP: teq $9, $zero, 7 # encoding: [0x01,0x20,0x01,0xf4] +# CHECK-TRAP: ddivu $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1f] +# CHECK-TRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] + + ddivu $0,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] +# CHECK-TRAP: ddivu $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1f] +# CHECK-TRAP: mflo $zero # encoding: [0x00,0x00,0x00,0x12] Index: test/MC/Mips/macro-div-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-div-bad.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 + + .text + div $25, $11 + # R6: :[[@LINE-1]]:3: error: instruction not supported on mips32r6 or mips64r6 + + div $25, $0 + # NOT-R6: :[[@LINE-1]]:3: warning: division by zero + + div $0,$0 + # NOT-R6: :[[@LINE-1]]:3: warning: dividing zero by zero Index: test/MC/Mips/macro-div.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-div.s @@ -0,0 +1,64 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s --check-prefix=CHECK-NOTRAP +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 \ +# RUN: -mattr=+use-tcc-in-div | FileCheck %s --check-prefix=CHECK-TRAP + + div $25,$11 +# CHECK-NOTRAP: bnez $11, 8 # encoding: [0x15,0x60,0x00,0x02] +# CHECK-NOTRAP: div $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1a] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-NOTRAP: bne $11, $1, 16 # encoding: [0x15,0x61,0x00,0x04] +# CHECK-NOTRAP: lui $1, 32768 # encoding: [0x3c,0x01,0x80,0x00] +# CHECK-NOTRAP: bne $25, $1, 8 # encoding: [0x17,0x21,0x00,0x02] +# CHECK-NOTRAP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-NOTRAP: break 6 # encoding: [0x00,0x06,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + div $24,$12 +# CHECK-NOTRAP: bnez $12, 8 # encoding: [0x15,0x80,0x00,0x02] +# CHECK-NOTRAP: div $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1a] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-NOTRAP: bne $12, $1, 16 # encoding: [0x15,0x81,0x00,0x04] +# CHECK-NOTRAP: lui $1, 32768 # encoding: [0x3c,0x01,0x80,0x00] +# CHECK-NOTRAP: bne $24, $1, 8 # encoding: [0x17,0x01,0x00,0x02] +# CHECK-NOTRAP: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-NOTRAP: break 6 # encoding: [0x00,0x06,0x00,0x0d] +# CHECK-NOTRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + div $25,$0 +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] + + div $0,$9 +# CHECK-NOTRAP: div $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1a] + + div $0,$0 +# CHECK-NOTRAP: div $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1a] + + div $25, $11 +# CHECK-TRAP: teq $11, $zero, 7 # encoding: [0x01,0x60,0x01,0xf4] +# CHECK-TRAP: div $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1a] +# CHECK-TRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-TRAP: bne $11, $1, 8 # encoding: [0x15,0x61,0x00,0x02] +# CHECK-TRAP: lui $1, 32768 # encoding: [0x3c,0x01,0x80,0x00] +# CHECK-TRAP: teq $25, $1, 6 # encoding: [0x03,0x21,0x01,0xb4] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + div $24,$12 +# CHECK-TRAP: teq $12, $zero, 7 # encoding: [0x01,0x80,0x01,0xf4] +# CHECK-TRAP: div $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1a] +# CHECK-TRAP: addiu $1, $zero, -1 # encoding: [0x24,0x01,0xff,0xff] +# CHECK-TRAP: bne $12, $1, 8 # encoding: [0x15,0x81,0x00,0x02] +# CHECK-TRAP: lui $1, 32768 # encoding: [0x3c,0x01,0x80,0x00] +# CHECK-TRAP: teq $24, $1, 6 # encoding: [0x03,0x01,0x01,0xb4] +# CHECK-TRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + div $25,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] + + div $0,$9 +# CHECK-TRAP: div $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1a] + + div $0,$0 +# CHECK-TRAP: div $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1a] Index: test/MC/Mips/macro-divu-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-divu-bad.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 2>&1 | \ +# RUN: FileCheck %s --check-prefix=R6 +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64r2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=NOT-R6 + + .text + divu $25, $11 + # R6: :[[@LINE-1]]:3: error: instruction not supported on mips32r6 or mips64r6 + + divu $25, $0 + # NOT-R6: :[[@LINE-1]]:3: warning: division by zero + + divu $0,$0 + # NOT-R6: :[[@LINE-1]]:3: warning: dividing zero by zero Index: test/MC/Mips/macro-divu.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-divu.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s --check-prefix=CHECK-NOTRAP +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 \ +# RUN: -mattr=+use-tcc-in-div | FileCheck %s --check-prefix=CHECK-TRAP + + divu $25,$11 +# CHECK-NOTRAP: bnez $11, 8 # encoding: [0x15,0x60,0x00,0x02] +# CHECK-NOTRAP: divu $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1b] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + divu $24,$12 +# CHECK-NOTRAP: bnez $12, 8 # encoding: [0x15,0x80,0x00,0x02] +# CHECK-NOTRAP: divu $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1b] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + divu $25,$0 +# CHECK-NOTRAP: bnez $zero, 8 # encoding: [0x14,0x00,0x00,0x02] +# CHECK-NOTRAP: divu $zero, $25, $zero # encoding: [0x03,0x20,0x00,0x1b] +# CHECK-NOTRAP: break 7 # encoding: [0x00,0x07,0x00,0x0d] +# CHECK-NOTRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + divu $0,$9 +# CHECK-NOTRAP: divu $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1b] + + divu $0,$0 +# CHECK-NOTRAP: divu $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1b] + + divu $25, $11 +# CHECK-TRAP: teq $11, $zero, 7 # encoding: [0x01,0x60,0x01,0xf4] +# CHECK-TRAP: divu $zero, $25, $11 # encoding: [0x03,0x2b,0x00,0x1b] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + divu $24,$12 +# CHECK-TRAP: teq $12, $zero, 7 # encoding: [0x01,0x80,0x01,0xf4] +# CHECK-TRAP: divu $zero, $24, $12 # encoding: [0x03,0x0c,0x00,0x1b] +# CHECK-TRAP: mflo $24 # encoding: [0x00,0x00,0xc0,0x12] + + divu $25,$0 +# CHECK-TRAP: teq $zero, $zero, 7 # encoding: [0x00,0x00,0x01,0xf4] +# CHECK-TRAP: divu $zero, $25, $zero # encoding: [0x03,0x20,0x00,0x1b] +# CHECK-TRAP: mflo $25 # encoding: [0x00,0x00,0xc8,0x12] + + divu $0,$9 +# CHECK-TRAP: divu $zero, $zero, $9 # encoding: [0x00,0x09,0x00,0x1b] + + divu $0,$0 +# CHECK-TRAP: divu $zero, $zero, $zero # encoding: [0x00,0x00,0x00,0x1b]