diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2019-07-09 12:55:55 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2019-07-09 12:55:55 +0000 |
commit | 2fa6b546356394bb60dfc8090d4594c6c4c0cbd8 (patch) | |
tree | 092dfdb9555afa68857b382253eb4d3c3b2e2b3d /llvm/lib | |
parent | 00df4d92edac5abbcc1aac4b9bf4aadcf40a2ece (diff) | |
download | bcm5719-llvm-2fa6b546356394bb60dfc8090d4594c6c4c0cbd8.tar.gz bcm5719-llvm-2fa6b546356394bb60dfc8090d4594c6c4c0cbd8.zip |
[mips] Implement sge/sgeu pseudo instructions
The `sge/sgeu Dst, Src1, Src2/Imm` pseudo instructions set register
`Dst` to 1 if register `Src1` is greater than or equal `Src2/Imm` and
to 0 otherwise.
Differential Revision: https://reviews.llvm.org/D64314
llvm-svn: 365476
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 104 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 14 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 29 |
3 files changed, 147 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 928b8edd310..0d968674faa 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -275,6 +275,12 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); + bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + + bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); @@ -2476,6 +2482,14 @@ 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::SGE: + case Mips::SGEU: + return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; + case Mips::SGEImm: + case Mips::SGEUImm: + case Mips::SGEImm64: + case Mips::SGEUImm64: + return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; case Mips::SGTImm: case Mips::SGTUImm: case Mips::SGTImm64: @@ -4293,6 +4307,96 @@ bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, return false; } +bool MipsAsmParser::expandSge(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).isReg() && "Invalid instruction operand."); + + unsigned DstReg = Inst.getOperand(0).getReg(); + unsigned SrcReg = Inst.getOperand(1).getReg(); + unsigned OpReg = Inst.getOperand(2).getReg(); + unsigned OpCode; + + warnIfNoMacro(IDLoc); + + switch (Inst.getOpcode()) { + case Mips::SGE: + OpCode = Mips::SLT; + break; + case Mips::SGEU: + OpCode = Mips::SLTu; + break; + default: + llvm_unreachable("unexpected 'sge' opcode"); + } + + // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg)) + TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI); + TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); + + return false; +} + +bool MipsAsmParser::expandSgeImm(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(); + int64_t ImmValue = Inst.getOperand(2).getImm(); + unsigned OpRegCode, OpImmCode; + + warnIfNoMacro(IDLoc); + + switch (Inst.getOpcode()) { + case Mips::SGEImm: + case Mips::SGEImm64: + OpRegCode = Mips::SLT; + OpImmCode = Mips::SLTi; + break; + case Mips::SGEUImm: + case Mips::SGEUImm64: + OpRegCode = Mips::SLTu; + OpImmCode = Mips::SLTiu; + break; + default: + llvm_unreachable("unexpected 'sge' opcode with immediate"); + } + + // $SrcReg >= Imm is equal to (not ($SrcReg < Imm)) + if (isInt<16>(ImmValue)) { + // Use immediate version of STL. + TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI); + TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); + } else { + unsigned ImmReg = DstReg; + 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; + + TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI); + TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); + } + + return false; +} + bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) { MipsTargetStreamer &TOut = getTargetStreamer(); diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 2e8de5e09eb..b5711004f70 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -1155,6 +1155,20 @@ def SLTUImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rs), def : MipsInstAlias<"sltu\t$rs, $imm", (SLTUImm64 GPR64Opnd:$rs, GPR64Opnd:$rs, imm64:$imm)>, GPR_64; +def SGEImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, imm64:$imm), + "sge\t$rd, $rs, $imm">, GPR_64; +def : MipsInstAlias<"sge $rs, $imm", (SGEImm64 GPR64Opnd:$rs, + GPR64Opnd:$rs, + imm64:$imm), 0>, GPR_64; + +def SGEUImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, imm64:$imm), + "sgeu\t$rd, $rs, $imm">, GPR_64; +def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm64 GPR64Opnd:$rs, + GPR64Opnd:$rs, + imm64:$imm), 0>, GPR_64; + def SGTImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), (ins GPR64Opnd:$rs, imm64:$imm), "sgt\t$rd, $rs, $imm">, GPR_64; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index f17218acf40..ab353c92e27 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -2693,6 +2693,35 @@ let AdditionalPredicates = [NotInMicroMips] in { (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1; def : MipsInstAlias<"negu $rt", (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1; + + def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "sge\t$rd, $rs, $rt">, ISA_MIPS1; + def : MipsInstAlias<"sge $rs, $rt", + (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>, + ISA_MIPS1; + def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, simm32:$imm), + "sge\t$rd, $rs, $imm">, GPR_32; + def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs, + GPR32Opnd:$rs, + simm32:$imm), 0>, + GPR_32; + + def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "sgeu\t$rd, $rs, $rt">, ISA_MIPS1; + def : MipsInstAlias<"sgeu $rs, $rt", + (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>, + ISA_MIPS1; + def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, uimm32_coerced:$imm), + "sgeu\t$rd, $rs, $imm">, GPR_32; + def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs, + GPR32Opnd:$rs, + uimm32_coerced:$imm), 0>, + GPR_32; + def : MipsInstAlias< "sgt $rd, $rs, $rt", (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1; |