Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -249,6 +249,12 @@ bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); + 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); @@ -2210,6 +2216,10 @@ return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; case Mips::ABSMacro: return expandAbs(Inst, IDLoc, Out, STI) ? 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; } } @@ -3816,6 +3826,74 @@ 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(); + + int64_t Imm = Inst.getOperand(2).getImm(); + if (!isUInt<16>(Imm)) { + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + + if (Imm < 0) { + Imm = -Imm; + TOut.emitRRI(Mips::ADDiu, 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; + } + + if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, false, 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(Mips::XORi, Inst.getOperand(0).getReg(), + Inst.getOperand(1).getReg(), Inst.getOperand(2).getImm(), 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) { Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -201,6 +201,8 @@ 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">; @@ -322,6 +324,10 @@ list InsnPredicates = [HasCnMips]; } +class NOT_ASE_CNMIPS { + list InsnPredicates = [NotCnMips]; +} + class ASE_MIPS64_CNMIPS { list InsnPredicates = [HasMips64, HasCnMips]; } @@ -2218,6 +2224,21 @@ 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:$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 //===----------------------------------------------------------------------===// @@ -2306,6 +2327,9 @@ def : MipsInstAlias< "not $rt, $rs", (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; + def : MipsInstAlias< + "not $rt", + (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>; def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; } def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>; Index: test/MC/Mips/macro-seq.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-seq.s @@ -0,0 +1,28 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips1 < %s | FileCheck %s + +# CHECK: .text +seq $2, $11, $0 +# CHECK: sltiu $2, $11, 1 +seq $2, $0, $11 +# CHECK: sltiu $2, $11, 1 +seq $2, $0, $0 +# CHECK: sltiu $2, $zero, 1 +seq $2, $11, $12 +# CHECK: xor $2, $11, $12 +# CHECK: sltiu $2, $2, 1 +seq $2, $11, 45 +# CHECK: xori $2, $11, 45 +seq $2, $12, 0x76666 +# CHECK: lui $1, 7 +# CHECK: ori $1, $1, 26214 +# CHECK: xor $2, $12, $1 +# CHECK: sltiu $2, $2, 1 +seq $2, $3 +# CHECK: xor $2, $2, $3 +# CHECK: sltiu $2, $2, 1 +seq $2, 0x8888 +# CHECK: xori $2, $2, 34952 +# CHECK: sltiu $2, $2, 1 +seq $2, $3, -1546 +# CHECK: addiu $2, $3, 1546 +# CHECK: sltiu $2, $2, 1 Index: test/MC/Mips/mips1/valid.s =================================================================== --- test/MC/Mips/mips1/valid.s +++ test/MC/Mips/mips1/valid.s @@ -85,6 +85,8 @@ neg.s $f1,$f15 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] sb $s6,-19857($14) Index: test/MC/Mips/mips2/valid.s =================================================================== --- test/MC/Mips/mips2/valid.s +++ test/MC/Mips/mips2/valid.s @@ -107,6 +107,8 @@ neg.s $f1,$f15 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] round.w.d $f6,$f4 Index: test/MC/Mips/mips3/valid.s =================================================================== --- test/MC/Mips/mips3/valid.s +++ test/MC/Mips/mips3/valid.s @@ -167,6 +167,8 @@ neg.s $f1,$f15 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] round.l.d $f12,$f1 Index: test/MC/Mips/mips32/valid.s =================================================================== --- test/MC/Mips/mips32/valid.s +++ test/MC/Mips/mips32/valid.s @@ -135,6 +135,8 @@ neg.s $f1,$f15 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] Index: test/MC/Mips/mips32r2/valid.s =================================================================== --- test/MC/Mips/mips32r2/valid.s +++ test/MC/Mips/mips32r2/valid.s @@ -157,6 +157,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips32r3/valid.s =================================================================== --- test/MC/Mips/mips32r3/valid.s +++ test/MC/Mips/mips32r3/valid.s @@ -157,6 +157,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips32r5/valid.s =================================================================== --- test/MC/Mips/mips32r5/valid.s +++ test/MC/Mips/mips32r5/valid.s @@ -158,6 +158,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips32r6/valid.s =================================================================== --- test/MC/Mips/mips32r6/valid.s +++ test/MC/Mips/mips32r6/valid.s @@ -132,6 +132,8 @@ neg $2, $3 # CHECK: neg $2, $3 # encoding: [0x00,0x03,0x10,0x22] negu $2 # CHECK: negu $2, $2 # encoding: [0x00,0x02,0x10,0x23] negu $2,$3 # CHECK: negu $2, $3 # encoding: [0x00,0x03,0x10,0x23] + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x7c,0xa1,0x04,0x35] # FIXME: Use the code generator in order to print the .set directives # instead of the instruction printer. Index: test/MC/Mips/mips4/valid.s =================================================================== --- test/MC/Mips/mips4/valid.s +++ test/MC/Mips/mips4/valid.s @@ -193,6 +193,8 @@ nmsub.s $f0, $f24, $f20, $f4 # encoding: [0x4f,0x04,0xa0,0x38] nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] Index: test/MC/Mips/mips5/valid.s =================================================================== --- test/MC/Mips/mips5/valid.s +++ test/MC/Mips/mips5/valid.s @@ -194,6 +194,8 @@ nmsub.s $f0, $f24, $f20, $f4 # encoding: [0x4f,0x04,0xa0,0x38] nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] Index: test/MC/Mips/mips64/valid.s =================================================================== --- test/MC/Mips/mips64/valid.s +++ test/MC/Mips/mips64/valid.s @@ -210,6 +210,8 @@ nmsub.s $f0, $f24, $f20, $f4 # encoding: [0x4f,0x04,0xa0,0x38] nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] Index: test/MC/Mips/mips64r2/valid.s =================================================================== --- test/MC/Mips/mips64r2/valid.s +++ test/MC/Mips/mips64r2/valid.s @@ -224,6 +224,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips64r3/valid.s =================================================================== --- test/MC/Mips/mips64r3/valid.s +++ test/MC/Mips/mips64r3/valid.s @@ -224,6 +224,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips64r5/valid.s =================================================================== --- test/MC/Mips/mips64r5/valid.s +++ test/MC/Mips/mips64r5/valid.s @@ -225,6 +225,8 @@ nmsub.s $f1,$f24,$f19,$f4 nop nor $a3,$zero,$a3 + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $12,$s0,$sp or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] Index: test/MC/Mips/mips64r6/valid.s =================================================================== --- test/MC/Mips/mips64r6/valid.s +++ test/MC/Mips/mips64r6/valid.s @@ -186,6 +186,8 @@ neg $2, $3 # CHECK: neg $2, $3 # encoding: [0x00,0x03,0x10,0x22] negu $2 # CHECK: negu $2, $2 # encoding: [0x00,0x02,0x10,0x23] negu $2,$3 # CHECK: negu $2, $3 # encoding: [0x00,0x03,0x10,0x23] + not $3, $4 # CHECK: not $3, $4 # encoding: [0x00,0x80,0x18,0x27] + not $3 # CHECK: not $3, $3 # encoding: [0x00,0x60,0x18,0x27] or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x7c,0xa1,0x04,0x35] # FIXME: Use the code generator in order to print the .set directives