From 426286dbce37b9558f46b5d1ada7a813836ae703 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Mon, 21 Nov 2016 20:30:41 +0000 Subject: [PATCH] [mips] seq macro support This patch adds the seq macro. This partially resolves PR/30381. Thanks to Sean Bruno for reporting the issue! Reviewers: zoran.jovanovic, vkalintiris, seanbruno Differential Revision: https://reviews.llvm.org/D24607 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287573 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 89 +++++++++++++++++++++++++++++ lib/Target/Mips/MipsInstrInfo.td | 21 +++++++ test/MC/Mips/macro-seq.s | 52 +++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 test/MC/Mips/macro-seq.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 23d8831b40f..8daba92d354 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -252,6 +252,12 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI, bool IsLoad); + bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + + bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI); + bool reportParseError(Twine ErrorMsg); bool reportParseError(SMLoc Loc, Twine ErrorMsg); @@ -2223,6 +2229,10 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, Inst.getOpcode() == Mips::LDMacro) ? MER_Fail : MER_Success; + case Mips::SEQMacro: + return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; + case Mips::SEQIMacro: + return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; } } @@ -3915,6 +3925,85 @@ bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, return false; } +bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI) { + + warnIfNoMacro(IDLoc); + MipsTargetStreamer &TOut = getTargetStreamer(); + + if (Inst.getOperand(1).getReg() != Mips::ZERO && + Inst.getOperand(2).getReg() != Mips::ZERO) { + TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(), + Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(), + IDLoc, STI); + TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), + Inst.getOperand(0).getReg(), 1, IDLoc, STI); + return false; + } + + unsigned Reg = 0; + if (Inst.getOperand(1).getReg() == Mips::ZERO) { + Reg = Inst.getOperand(2).getReg(); + } else { + Reg = Inst.getOperand(1).getReg(); + } + TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI); + return false; +} + +bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI) { + + warnIfNoMacro(IDLoc); + MipsTargetStreamer &TOut = getTargetStreamer(); + + unsigned Opc; + int64_t Imm = Inst.getOperand(2).getImm(); + unsigned Reg = Inst.getOperand(1).getReg(); + + if (Imm == 0) { + TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), + Inst.getOperand(1).getReg(), 1, IDLoc, STI); + return false; + } else { + + if (Reg == Mips::ZERO) { + Warning(IDLoc, "comparison is always false"); + TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, + Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI); + return false; + } + + if (Imm > -0x8000 && Imm < 0) { + Imm = -Imm; + Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu; + } else { + Opc = Mips::XORi; + } + } + if (!isUInt<16>(Imm)) { + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + + if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc, + Out, STI)) + return true; + + TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(), + Inst.getOperand(1).getReg(), ATReg, IDLoc, STI); + TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), + Inst.getOperand(0).getReg(), 1, IDLoc, STI); + return false; + } + + TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), + Imm, IDLoc, STI); + TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), + Inst.getOperand(0).getReg(), 1, IDLoc, STI); + return false; +} + unsigned MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands) { diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 22060dfc70e..1c825b442d0 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -203,6 +203,8 @@ def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; def HasCnMips : Predicate<"Subtarget->hasCnMips()">, AssemblerPredicate<"FeatureCnMips">; +def NotCnMips : Predicate<"!Subtarget->hasCnMips()">, + AssemblerPredicate<"!FeatureCnMips">; def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">; def RelocPIC : Predicate<"TM.isPositionIndependent()">; def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; @@ -335,6 +337,10 @@ class ASE_CNMIPS { list InsnPredicates = [HasCnMips]; } +class NOT_ASE_CNMIPS { + list InsnPredicates = [NotCnMips]; +} + class ASE_MIPS64_CNMIPS { list InsnPredicates = [HasMips64, HasCnMips]; } @@ -2260,6 +2266,21 @@ def : MipsInstAlias<"dror $rd, $imm", def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), "abs\t$rd, $rs">; +def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS; + +def : MipsInstAlias<"seq $rd, $rs", + (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, + NOT_ASE_CNMIPS; + +def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), + (ins GPR32Opnd:$rs, simm32_relaxed:$imm), + "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS; + +def : MipsInstAlias<"seq $rd, $imm", + (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>, + NOT_ASE_CNMIPS; //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// diff --git a/test/MC/Mips/macro-seq.s b/test/MC/Mips/macro-seq.s new file mode 100644 index 00000000000..814f198a07b --- /dev/null +++ b/test/MC/Mips/macro-seq.s @@ -0,0 +1,52 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips1 < %s | FileCheck --check-prefixes=ALL,MIPS32 %s +# RUN: llvm-mc -arch=mips -mcpu=mips64 < %s | FileCheck --check-prefixes=ALL,MIPS64 %s + +# ALL: .text +seq $2, $11, $0 +# ALL: sltiu $2, $11, 1 +seq $2, $0, $11 +# ALL: sltiu $2, $11, 1 +seq $2, $0, $0 +# ALL: sltiu $2, $zero, 1 +seq $2, $11, $12 +# ALL: xor $2, $11, $12 +# ALL: sltiu $2, $2, 1 +seq $2, $11, 45 +# ALL: xori $2, $11, 45 +seq $2, $12, 0x76666 +# ALL: lui $1, 7 +# ALL: ori $1, $1, 26214 +# ALL: xor $2, $12, $1 +# ALL: sltiu $2, $2, 1 +seq $2, $3 +# ALL: xor $2, $2, $3 +# ALL: sltiu $2, $2, 1 +seq $2, 0x8888 +# ALL: xori $2, $2, 34952 +# ALL: sltiu $2, $2, 1 +seq $2, $3, -1546 +# MIPS32: addiu $2, $3, 1546 +# MIPS64: daddiu $2, $3, 1546 +# ALL: sltiu $2, $2, 1 +seq $2, -7546 +# MIPS32: addiu $2, $2, 7546 +# MIPS64: daddiu $2, $2, 7546 +# ALL: sltiu $2, $2, 1 +seq $4, $5, -66666 +# ALL: lui $1, 65534 +# ALL: ori $1, $1, 64406 +# ALL: xor $4, $5, $1 +# ALL: sltiu $4, $4, 1 +seq $4, $5, -2147483648 +# ALL: lui $1, 32768 +# ALL: xor $4, $5, $1 +# ALL: sltiu $4, $4, 1 +seq $4, -2147483648 +# ALL: lui $1, 32768 +# ALL: xor $4, $4, $1 +# ALL: sltiu $4, $4, 1 +seq $4, $5, 0 +# ALL: sltiu $4, $5, 1 +seq $4, $zero, 1 +# MIPS32: move $4, $zero +# MIPS64: daddu $4, $zero, $zero -- 2.11.0