diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsExpandPseudo.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 60 |
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) |