aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/MipsExpandPseudo.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsExpandPseudo.cpp60
1 files changed, 51 insertions, 9 deletions
diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 2c2554b5b4bc..c30129743a96 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -388,18 +388,32 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
Opcode = Mips::XOR;
break;
case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
+ IsUnsigned = true;
+ IsMin = true;
+ break;
case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
IsUnsigned = true;
- [[fallthrough]];
+ IsMin = true;
+ break;
case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
+ SEOp = Mips::SEB;
+ IsMin = true;
+ break;
case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
IsMin = true;
break;
case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
+ IsUnsigned = true;
+ IsMax = true;
+ break;
case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
IsUnsigned = true;
- [[fallthrough]];
+ IsMax = true;
+ break;
case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
+ SEOp = Mips::SEB;
+ IsMax = true;
+ break;
case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
IsMax = true;
break;
@@ -461,14 +475,42 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
// For little endian we need to clear uninterested bits.
if (STI->isLittle()) {
- // and OldVal, OldVal, Mask
- // and Incr, Incr, Mask
- BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
- .addReg(OldVal)
- .addReg(Mask);
- BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr).addReg(Incr).addReg(Mask);
+ if (!IsUnsigned) {
+ BuildMI(loopMBB, DL, TII->get(Mips::SRAV), OldVal)
+ .addReg(OldVal)
+ .addReg(ShiftAmnt);
+ BuildMI(loopMBB, DL, TII->get(Mips::SRAV), Incr)
+ .addReg(Incr)
+ .addReg(ShiftAmnt);
+ if (STI->hasMips32r2()) {
+ BuildMI(loopMBB, DL, TII->get(SEOp), OldVal).addReg(OldVal);
+ BuildMI(loopMBB, DL, TII->get(SEOp), Incr).addReg(Incr);
+ } else {
+ const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
+ BuildMI(loopMBB, DL, TII->get(Mips::SLL), OldVal)
+ .addReg(OldVal, RegState::Kill)
+ .addImm(ShiftImm);
+ BuildMI(loopMBB, DL, TII->get(Mips::SRA), OldVal)
+ .addReg(OldVal, RegState::Kill)
+ .addImm(ShiftImm);
+ BuildMI(loopMBB, DL, TII->get(Mips::SLL), Incr)
+ .addReg(Incr, RegState::Kill)
+ .addImm(ShiftImm);
+ BuildMI(loopMBB, DL, TII->get(Mips::SRA), Incr)
+ .addReg(Incr, RegState::Kill)
+ .addImm(ShiftImm);
+ }
+ } else {
+ // and OldVal, OldVal, Mask
+ // and Incr, Incr, Mask
+ BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
+ .addReg(OldVal)
+ .addReg(Mask);
+ BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr)
+ .addReg(Incr)
+ .addReg(Mask);
+ }
}
-
// unsigned: sltu Scratch4, oldVal, Incr
// signed: slt Scratch4, oldVal, Incr
BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)