@@ -68,6 +68,7 @@ class MCInstrInfo;
6868} // end namespace llvm
6969
7070extern cl::opt<bool > EmitJalrReloc;
71+ extern cl::opt<bool > NoZeroDivCheck;
7172
7273namespace {
7374
@@ -4237,7 +4238,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42374238 if (!ATReg)
42384239 return true ;
42394240
4240- if (ImmValue == 0 ) {
4241+ if (!NoZeroDivCheck && ImmValue == 0 ) {
42414242 if (UseTraps)
42424243 TOut.emitRRI (Mips::TEQ, ZeroReg, ZeroReg, 0x7 , IDLoc, STI);
42434244 else
@@ -4269,7 +4270,7 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42694270 // break, insert the trap/break and exit. This gives a different result to
42704271 // GAS. GAS has an inconsistency/missed optimization in that not all cases
42714272 // are handled equivalently. As the observed behaviour is the same, we're ok.
4272- if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4273+ if (!NoZeroDivCheck && ( RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) ) {
42734274 if (UseTraps) {
42744275 TOut.emitRRI (Mips::TEQ, ZeroReg, ZeroReg, 0x7 , IDLoc, STI);
42754276 return false ;
@@ -4290,62 +4291,25 @@ bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
42904291 MCSymbol *BrTarget;
42914292 MCOperand LabelOp;
42924293
4293- if (UseTraps) {
4294- TOut.emitRRI (Mips::TEQ, RtReg, ZeroReg, 0x7 , IDLoc, STI);
4295- } else {
4296- // Branch to the li instruction.
4297- BrTarget = Context.createTempSymbol ();
4298- LabelOp = MCOperand::createExpr (MCSymbolRefExpr::create (BrTarget, Context));
4299- TOut.emitRRX (Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4300- }
4301-
43024294 TOut.emitRR (DivOp, RsReg, RtReg, IDLoc, STI);
4295+ if (!NoZeroDivCheck) {
4296+ if (UseTraps) {
4297+ TOut.emitRRI (Mips::TEQ, RtReg, ZeroReg, 0x7 , IDLoc, STI);
4298+ } else {
4299+ // Branch to the li instruction.
4300+ BrTarget = Context.createTempSymbol ();
4301+ LabelOp =
4302+ MCOperand::createExpr (MCSymbolRefExpr::create (BrTarget, Context));
4303+ TOut.emitRRX (Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4304+ }
43034305
4304- if (!UseTraps)
4305- TOut.emitII (Mips::BREAK, 0x7 , 0 , IDLoc, STI);
4306+ if (!UseTraps)
4307+ TOut.emitII (Mips::BREAK, 0x7 , 0 , IDLoc, STI);
43064308
4307- if (!Signed) {
43084309 if (!UseTraps)
43094310 TOut.getStreamer ().emitLabel (BrTarget);
4310-
4311- TOut.emitR (isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4312- return false ;
4313- }
4314-
4315- MCRegister ATReg = getATReg (IDLoc);
4316- if (!ATReg)
4317- return true ;
4318-
4319- if (!UseTraps)
4320- TOut.getStreamer ().emitLabel (BrTarget);
4321-
4322- TOut.emitRRI (Mips::ADDiu, ATReg, ZeroReg, -1 , IDLoc, STI);
4323-
4324- // Temporary label for the second branch target.
4325- MCSymbol *BrTargetEnd = Context.createTempSymbol ();
4326- MCOperand LabelOpEnd =
4327- MCOperand::createExpr (MCSymbolRefExpr::create (BrTargetEnd, Context));
4328-
4329- // Branch to the mflo instruction.
4330- TOut.emitRRX (Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4331-
4332- if (IsMips64) {
4333- TOut.emitRRI (Mips::ADDiu, ATReg, ZeroReg, 1 , IDLoc, STI);
4334- TOut.emitDSLL (ATReg, ATReg, 63 , IDLoc, STI);
4335- } else {
4336- TOut.emitRI (Mips::LUi, ATReg, (uint16_t )0x8000 , IDLoc, STI);
4337- }
4338-
4339- if (UseTraps)
4340- TOut.emitRRI (Mips::TEQ, RsReg, ATReg, 0x6 , IDLoc, STI);
4341- else {
4342- // Branch to the mflo instruction.
4343- TOut.emitRRX (Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4344- TOut.emitNop (IDLoc, STI);
4345- TOut.emitII (Mips::BREAK, 0x6 , 0 , IDLoc, STI);
43464311 }
43474312
4348- TOut.getStreamer ().emitLabel (BrTargetEnd);
43494313 TOut.emitR (isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
43504314 return false ;
43514315}
0 commit comments