diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2019-07-09 12:55:42 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2019-07-09 12:55:42 +0000 |
| commit | 00df4d92edac5abbcc1aac4b9bf4aadcf40a2ece (patch) | |
| tree | 181d58a377ab536a7368735974ac2d8da31a3d86 /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | |
| parent | 8447b419a7c59a15651689668fa12441b96d0255 (diff) | |
| download | bcm5719-llvm-00df4d92edac5abbcc1aac4b9bf4aadcf40a2ece.tar.gz bcm5719-llvm-00df4d92edac5abbcc1aac4b9bf4aadcf40a2ece.zip | |
[mips] Implement sgt/sgtu pseudo instructions with immediate operand
The `sgt/sgtu Dst, Src1, Src2/Imm` pseudo instructions set register
`Dst` to 1 if register `Src1` is greater than `Src2/Imm` and to 0 otherwise.
Differential Revision: https://reviews.llvm.org/D64313
llvm-svn: 365475
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 1a7c22f3198..928b8edd310 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -275,6 +275,9 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); + bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + bool expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, @@ -2473,6 +2476,11 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, case Mips::NORImm: case Mips::NORImm64: return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; + case Mips::SGTImm: + case Mips::SGTUImm: + case Mips::SGTImm64: + case Mips::SGTUImm64: + return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; case Mips::SLTImm64: if (isInt<16>(Inst.getOperand(2).getImm())) { Inst.setOpcode(Mips::SLTi64); @@ -4285,6 +4293,53 @@ bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, return false; } +bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI) { + MipsTargetStreamer &TOut = getTargetStreamer(); + + assert(Inst.getNumOperands() == 3 && "Invalid operand count"); + assert(Inst.getOperand(0).isReg() && + Inst.getOperand(1).isReg() && + Inst.getOperand(2).isImm() && "Invalid instruction operand."); + + unsigned DstReg = Inst.getOperand(0).getReg(); + unsigned SrcReg = Inst.getOperand(1).getReg(); + unsigned ImmReg = DstReg; + int64_t ImmValue = Inst.getOperand(2).getImm(); + unsigned OpCode; + + warnIfNoMacro(IDLoc); + + switch (Inst.getOpcode()) { + case Mips::SGTImm: + case Mips::SGTImm64: + OpCode = Mips::SLT; + break; + case Mips::SGTUImm: + case Mips::SGTUImm64: + OpCode = Mips::SLTu; + break; + default: + llvm_unreachable("unexpected 'sgt' opcode with immediate"); + } + + if (DstReg == SrcReg) { + unsigned ATReg = getATReg(Inst.getLoc()); + if (!ATReg) + return true; + ImmReg = ATReg; + } + + if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue), + false, IDLoc, Out, STI)) + return true; + + // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg + TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI); + + return false; +} + bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) { |

