@@ -432,23 +432,44 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
432432  Register OldVal = I->getOperand (6 ).getReg ();
433433  Register BinOpRes = I->getOperand (7 ).getReg ();
434434  Register StoreVal = I->getOperand (8 ).getReg ();
435+   bool  NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4 () && !STI->hasMips32 ();
435436
436437  const  BasicBlock *LLVM_BB = BB.getBasicBlock ();
437438  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock (LLVM_BB);
439+   MachineBasicBlock *loop1MBB = nullptr ;
440+   MachineBasicBlock *loop2MBB = nullptr ;
441+   if  (NoMovnInstr) {
442+     loop1MBB = MF->CreateMachineBasicBlock (LLVM_BB);
443+     loop2MBB = MF->CreateMachineBasicBlock (LLVM_BB);
444+   }
438445  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock (LLVM_BB);
439446  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock (LLVM_BB);
440447  MachineFunction::iterator It = ++BB.getIterator ();
441448  MF->insert (It, loopMBB);
449+   if  (NoMovnInstr) {
450+     MF->insert (It, loop1MBB);
451+     MF->insert (It, loop2MBB);
452+   }
442453  MF->insert (It, sinkMBB);
443454  MF->insert (It, exitMBB);
444455
445456  exitMBB->splice (exitMBB->begin (), &BB, std::next (I), BB.end ());
446457  exitMBB->transferSuccessorsAndUpdatePHIs (&BB);
447458
448459  BB.addSuccessor (loopMBB, BranchProbability::getOne ());
449-   loopMBB->addSuccessor (sinkMBB);
450-   loopMBB->addSuccessor (loopMBB);
451-   loopMBB->normalizeSuccProbs ();
460+   if  (NoMovnInstr) {
461+     loopMBB->addSuccessor (loop1MBB);
462+     loopMBB->addSuccessor (loop2MBB);
463+   } else  {
464+     loopMBB->addSuccessor (sinkMBB);
465+     loopMBB->addSuccessor (loopMBB);
466+     loopMBB->normalizeSuccProbs ();
467+   }
468+   if  (NoMovnInstr) {
469+     loop1MBB->addSuccessor (loop2MBB);
470+     loop2MBB->addSuccessor (loopMBB);
471+     loop2MBB->addSuccessor (sinkMBB);
472+   }
452473
453474  BuildMI (loopMBB, DL, TII->get (LL), OldVal).addReg (Ptr).addImm (0 );
454475  if  (IsNand) {
@@ -525,7 +546,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
525546      BuildMI (loopMBB, DL, TII->get (OR), BinOpRes)
526547          .addReg (BinOpRes)
527548          .addReg (Scratch4);
528-     } else  {
549+     } else  if  (STI-> hasMips4 () || STI-> hasMips32 ())  {
529550      //  max: move BinOpRes, StoreVal
530551      //       movn BinOpRes, Incr, Scratch4, BinOpRes
531552      //  min: move BinOpRes, StoreVal
@@ -537,12 +558,59 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
537558          .addReg (Incr)
538559          .addReg (Scratch4)
539560          .addReg (BinOpRes);
561+     } else  {
562+       //  if min:
563+       //  loopMBB:  move BinOpRes, StoreVal
564+       //            beq Scratch4, 0, loop1MBB
565+       //            j loop2MBB
566+       //  loop1MBB: move BinOpRes, Incr
567+       //  loop2MBB: and BinOpRes, BinOpRes, Mask
568+       //            and StoreVal, OlddVal, Mask2
569+       //            or StoreVal, StoreVal, BinOpRes
570+       //            StoreVal<tied1> = sc StoreVal, 0(Ptr)
571+       //            beq StoreVal, zero, loopMBB
572+       // 
573+       //  if max:
574+       //  loopMBB:  move BinOpRes, Incr
575+       //            beq Scratch4, 0, loop1MBB
576+       //            j loop2MBB
577+       //  loop1MBB: move BinOpRes, StoreVal
578+       //  loop2MBB: and BinOpRes, BinOpRes, Mask
579+       //            and StoreVal, OlddVal, Mask2
580+       //            or StoreVal, StoreVal, BinOpRes
581+       //            StoreVal<tied1> = sc StoreVal, 0(Ptr)
582+       //            beq StoreVal, zero, loopMBB
583+       if  (IsMin) {
584+         BuildMI (loopMBB, DL, TII->get (OR), BinOpRes)
585+             .addReg (StoreVal)
586+             .addReg (Mips::ZERO);
587+         BuildMI (loop1MBB, DL, TII->get (OR), BinOpRes)
588+             .addReg (Incr)
589+             .addReg (Mips::ZERO);
590+       } else  {
591+         BuildMI (loopMBB, DL, TII->get (OR), BinOpRes)
592+             .addReg (Incr)
593+             .addReg (Mips::ZERO);
594+         BuildMI (loop1MBB, DL, TII->get (OR), BinOpRes)
595+             .addReg (StoreVal)
596+             .addReg (Mips::ZERO);
597+       }
598+       BuildMI (loopMBB, DL, TII->get (BEQ))
599+           .addReg (Scratch4)
600+           .addReg (Mips::ZERO)
601+           .addMBB (loop1MBB);
602+       BuildMI (loopMBB, DL, TII->get (Mips::J)).addMBB (loop2MBB);
540603    }
541604
542605    //   and BinOpRes, BinOpRes, Mask
543-     BuildMI (loopMBB, DL, TII->get (Mips::AND), BinOpRes)
544-         .addReg (BinOpRes)
545-         .addReg (Mask);
606+     if  (NoMovnInstr)
607+       BuildMI (loop2MBB, DL, TII->get (Mips::AND), BinOpRes)
608+           .addReg (BinOpRes)
609+           .addReg (Mask);
610+     else 
611+       BuildMI (loopMBB, DL, TII->get (Mips::AND), BinOpRes)
612+           .addReg (BinOpRes)
613+           .addReg (Mask);
546614
547615  } else  if  (!IsSwap) {
548616    //   <binop> binopres, oldval, incr2
@@ -564,14 +632,37 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
564632  //  or StoreVal, StoreVal, BinOpRes
565633  //  StoreVal<tied1> = sc StoreVal, 0(Ptr)
566634  //  beq StoreVal, zero, loopMBB
567-   BuildMI (loopMBB, DL, TII->get (Mips::AND), StoreVal)
568-     .addReg (OldVal).addReg (Mask2);
569-   BuildMI (loopMBB, DL, TII->get (Mips::OR), StoreVal)
570-     .addReg (StoreVal).addReg (BinOpRes);
571-   BuildMI (loopMBB, DL, TII->get (SC), StoreVal)
572-     .addReg (StoreVal).addReg (Ptr).addImm (0 );
573-   BuildMI (loopMBB, DL, TII->get (BEQ))
574-     .addReg (StoreVal).addReg (Mips::ZERO).addMBB (loopMBB);
635+   if  (NoMovnInstr) {
636+     BuildMI (loop2MBB, DL, TII->get (Mips::AND), StoreVal)
637+         .addReg (OldVal)
638+         .addReg (Mask2);
639+     BuildMI (loop2MBB, DL, TII->get (Mips::OR), StoreVal)
640+         .addReg (StoreVal)
641+         .addReg (BinOpRes);
642+     BuildMI (loop2MBB, DL, TII->get (SC), StoreVal)
643+         .addReg (StoreVal)
644+         .addReg (Ptr)
645+         .addImm (0 );
646+     BuildMI (loop2MBB, DL, TII->get (BEQ))
647+         .addReg (StoreVal)
648+         .addReg (Mips::ZERO)
649+         .addMBB (loopMBB);
650+   } else  {
651+     BuildMI (loopMBB, DL, TII->get (Mips::AND), StoreVal)
652+         .addReg (OldVal)
653+         .addReg (Mask2);
654+     BuildMI (loopMBB, DL, TII->get (Mips::OR), StoreVal)
655+         .addReg (StoreVal)
656+         .addReg (BinOpRes);
657+     BuildMI (loopMBB, DL, TII->get (SC), StoreVal)
658+         .addReg (StoreVal)
659+         .addReg (Ptr)
660+         .addImm (0 );
661+     BuildMI (loopMBB, DL, TII->get (BEQ))
662+         .addReg (StoreVal)
663+         .addReg (Mips::ZERO)
664+         .addMBB (loopMBB);
665+   }
575666
576667  //   sinkMBB:
577668  //     and     maskedoldval1,oldval,mask
@@ -600,6 +691,11 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
600691
601692  LivePhysRegs LiveRegs;
602693  computeAndAddLiveIns (LiveRegs, *loopMBB);
694+   if  (loop1MBB) {
695+     assert (loop2MBB && " should have 2 loop blocks"  );
696+     computeAndAddLiveIns (LiveRegs, *loop1MBB);
697+     computeAndAddLiveIns (LiveRegs, *loop2MBB);
698+   }
603699  computeAndAddLiveIns (LiveRegs, *sinkMBB);
604700  computeAndAddLiveIns (LiveRegs, *exitMBB);
605701
@@ -746,20 +842,41 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
746842    llvm_unreachable (" Unknown pseudo atomic!"  );
747843  }
748844
845+   bool  NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4 () && !STI->hasMips32 ();
749846  const  BasicBlock *LLVM_BB = BB.getBasicBlock ();
750847  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock (LLVM_BB);
848+   MachineBasicBlock *loop1MBB = nullptr ;
849+   MachineBasicBlock *loop2MBB = nullptr ;
850+   if  (NoMovnInstr) {
851+     loop1MBB = MF->CreateMachineBasicBlock (LLVM_BB);
852+     loop2MBB = MF->CreateMachineBasicBlock (LLVM_BB);
853+   }
751854  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock (LLVM_BB);
752855  MachineFunction::iterator It = ++BB.getIterator ();
753856  MF->insert (It, loopMBB);
857+   if  (NoMovnInstr) {
858+     MF->insert (It, loop1MBB);
859+     MF->insert (It, loop2MBB);
860+   }
754861  MF->insert (It, exitMBB);
755862
756863  exitMBB->splice (exitMBB->begin (), &BB, std::next (I), BB.end ());
757864  exitMBB->transferSuccessorsAndUpdatePHIs (&BB);
758865
759866  BB.addSuccessor (loopMBB, BranchProbability::getOne ());
760-   loopMBB->addSuccessor (exitMBB);
761-   loopMBB->addSuccessor (loopMBB);
867+   if  (NoMovnInstr) {
868+     loopMBB->addSuccessor (loop1MBB);
869+     loopMBB->addSuccessor (loop2MBB);
870+   } else  {
871+     loopMBB->addSuccessor (exitMBB);
872+     loopMBB->addSuccessor (loopMBB);
873+   }
762874  loopMBB->normalizeSuccProbs ();
875+   if  (NoMovnInstr) {
876+     loop1MBB->addSuccessor (loop2MBB);
877+     loop2MBB->addSuccessor (loopMBB);
878+     loop2MBB->addSuccessor (exitMBB);
879+   }
763880
764881  BuildMI (loopMBB, DL, TII->get (LL), OldVal).addReg (Ptr).addImm (0 );
765882  assert ((OldVal != Ptr) && " Clobbered the wrong ptr reg!"  );
@@ -802,7 +919,7 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
802919      BuildMI (loopMBB, DL, TII->get (OR), Scratch)
803920          .addReg (Scratch)
804921          .addReg (Scratch2);
805-     } else  {
922+     } else  if  (STI-> hasMips4 () || STI-> hasMips32 ())  {
806923      //  max: move Scratch, OldVal
807924      //       movn Scratch, Incr, Scratch2, Scratch
808925      //  min: move Scratch, OldVal
@@ -814,6 +931,38 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
814931          .addReg (Incr)
815932          .addReg (Scratch2)
816933          .addReg (Scratch);
934+     } else  {
935+       //  if min:
936+       //  loopMBB:  move Scratch, OldVal
937+       //            beq Scratch2_32, 0, loop1MBB
938+       //            j loop2MBB
939+       //  loop1MBB: move Scratch, Incr
940+       //  loop2MBB: sc $2, 0($4)
941+       //            beqz	$2, $BB0_1
942+       //            nop
943+       // 
944+       //  if max:
945+       //  loopMBB:  move Scratch, Incr
946+       //            beq Scratch2_32, 0, loop1MBB
947+       //            j loop2MBB
948+       //  loop1MBB: move Scratch, OldVal
949+       //  loop2MBB: sc $2, 0($4)
950+       //            beqz	$2, $BB0_1
951+       //            nop
952+       if  (IsMin) {
953+         BuildMI (loopMBB, DL, TII->get (OR), Scratch).addReg (OldVal).addReg (ZERO);
954+         BuildMI (loop1MBB, DL, TII->get (OR), Scratch).addReg (Incr).addReg (ZERO);
955+       } else  {
956+         BuildMI (loopMBB, DL, TII->get (OR), Scratch).addReg (Incr).addReg (ZERO);
957+         BuildMI (loop1MBB, DL, TII->get (OR), Scratch)
958+             .addReg (OldVal)
959+             .addReg (ZERO);
960+       }
961+       BuildMI (loopMBB, DL, TII->get (BEQ))
962+           .addReg (Scratch2_32)
963+           .addReg (ZERO)
964+           .addMBB (loop1MBB);
965+       BuildMI (loopMBB, DL, TII->get (Mips::J)).addMBB (loop2MBB);
817966    }
818967
819968  } else  if  (Opcode) {
@@ -829,20 +978,36 @@ bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
829978    BuildMI (loopMBB, DL, TII->get (OR), Scratch).addReg (Incr).addReg (ZERO);
830979  }
831980
832-   BuildMI (loopMBB, DL, TII->get (SC), Scratch)
833-       .addReg (Scratch)
834-       .addReg (Ptr)
835-       .addImm (0 );
836-   BuildMI (loopMBB, DL, TII->get (BEQ))
837-       .addReg (Scratch)
838-       .addReg (ZERO)
839-       .addMBB (loopMBB);
981+   if  (NoMovnInstr) {
982+     BuildMI (loop2MBB, DL, TII->get (SC), Scratch)
983+         .addReg (Scratch)
984+         .addReg (Ptr)
985+         .addImm (0 );
986+     BuildMI (loop2MBB, DL, TII->get (BEQ))
987+         .addReg (Scratch)
988+         .addReg (ZERO)
989+         .addMBB (loopMBB);
990+   } else  {
991+     BuildMI (loopMBB, DL, TII->get (SC), Scratch)
992+         .addReg (Scratch)
993+         .addReg (Ptr)
994+         .addImm (0 );
995+     BuildMI (loopMBB, DL, TII->get (BEQ))
996+         .addReg (Scratch)
997+         .addReg (ZERO)
998+         .addMBB (loopMBB);
999+   }
8401000
8411001  NMBBI = BB.end ();
8421002  I->eraseFromParent ();
8431003
8441004  LivePhysRegs LiveRegs;
8451005  computeAndAddLiveIns (LiveRegs, *loopMBB);
1006+   if  (loop1MBB) {
1007+     assert (loop2MBB && " should have 2 loop blocks"  );
1008+     computeAndAddLiveIns (LiveRegs, *loop1MBB);
1009+     computeAndAddLiveIns (LiveRegs, *loop2MBB);
1010+   }
8461011  computeAndAddLiveIns (LiveRegs, *exitMBB);
8471012
8481013  return  true ;
0 commit comments