Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -214,6 +214,11 @@ bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); + bool expandRotation(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); + bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions); + void createNop(bool hasShortDelaySlot, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -372,11 +377,11 @@ // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - + // Remember the initial assembler options. The user can not modify these. AssemblerOptions.push_back( llvm::make_unique(STI.getFeatureBits())); - + // Create an assembler options environment for the user to modify. AssemblerOptions.push_back( llvm::make_unique(STI.getFeatureBits())); @@ -1249,14 +1254,14 @@ static bool hasShortDelaySlot(unsigned Opcode) { switch (Opcode) { - case Mips::JALS_MM: - case Mips::JALRS_MM: - case Mips::JALRS16_MM: - case Mips::BGEZALS_MM: - case Mips::BLTZALS_MM: - return true; - default: - return false; + case Mips::JALS_MM: + case Mips::JALRS_MM: + case Mips::JALRS16_MM: + case Mips::BGEZALS_MM: + case Mips::BLTZALS_MM: + return true; + default: + return false; } } @@ -1278,7 +1283,7 @@ case Mips::BBIT1: case Mips::BBIT132: assert(hasCnMips() && "instruction only valid for octeon cpus"); - // Fall through + // Fall through case Mips::BEQ: case Mips::BNE: @@ -1348,65 +1353,65 @@ int Imm; switch (Opcode) { - default: - break; + default: + break; - case Mips::BBIT0: - case Mips::BBIT032: - case Mips::BBIT1: - case Mips::BBIT132: - assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); - // The offset is handled above - Opnd = Inst.getOperand(1); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); + case Mips::BBIT0: + case Mips::BBIT032: + case Mips::BBIT1: + case Mips::BBIT132: + assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); + // The offset is handled above + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 || Opcode == Mips::BBIT1 ? 63 : 31)) - return Error(IDLoc, "immediate operand value out of range"); - if (Imm > 31) { + return Error(IDLoc, "immediate operand value out of range"); + if (Imm > 31) { Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032 : Mips::BBIT132); - Inst.getOperand(1).setImm(Imm - 32); - } - break; + Inst.getOperand(1).setImm(Imm - 32); + } + break; - case Mips::CINS: - case Mips::CINS32: - case Mips::EXTS: - case Mips::EXTS32: - assert(MCID.getNumOperands() == 4 && "unexpected number of operands"); - // Check length - Opnd = Inst.getOperand(3); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < 0 || Imm > 31) - return Error(IDLoc, "immediate operand value out of range"); - // Check position - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); + case Mips::CINS: + case Mips::CINS32: + case Mips::EXTS: + case Mips::EXTS32: + assert(MCID.getNumOperands() == 4 && "unexpected number of operands"); + // Check length + Opnd = Inst.getOperand(3); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > 31) + return Error(IDLoc, "immediate operand value out of range"); + // Check position + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); if (Imm < 0 || Imm > (Opcode == Mips::CINS || Opcode == Mips::EXTS ? 63 : 31)) - return Error(IDLoc, "immediate operand value out of range"); - if (Imm > 31) { - Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32); - Inst.getOperand(2).setImm(Imm - 32); - } - break; + return Error(IDLoc, "immediate operand value out of range"); + if (Imm > 31) { + Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32); + Inst.getOperand(2).setImm(Imm - 32); + } + break; - case Mips::SEQi: - case Mips::SNEi: - assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (!isInt<10>(Imm)) - return Error(IDLoc, "immediate operand value out of range"); - break; + case Mips::SEQi: + case Mips::SNEi: + assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (!isInt<10>(Imm)) + return Error(IDLoc, "immediate operand value out of range"); + break; } } @@ -1480,122 +1485,122 @@ int Imm; switch (Inst.getOpcode()) { - default: - break; - case Mips::ADDIUS5_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < -8 || Imm > 7) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::ADDIUSP_MM: - Opnd = Inst.getOperand(0); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); + default: + break; + case Mips::ADDIUS5_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -8 || Imm > 7) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::ADDIUSP_MM: + Opnd = Inst.getOperand(0); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) || Imm % 4 != 0) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::SLL16_MM: - case Mips::SRL16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < 1 || Imm > 8) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::LI16_MM: - Opnd = Inst.getOperand(1); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < -1 || Imm > 126) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::ADDIUR2_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::SLL16_MM: + case Mips::SRL16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 1 || Imm > 8) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::LI16_MM: + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -1 || Imm > 126) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::ADDIUR2_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); if (!(Imm == 1 || Imm == -1 || ((Imm % 4 == 0) && Imm < 28 && Imm > 0))) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::ADDIUR1SP_MM: - Opnd = Inst.getOperand(1); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (OffsetToAlignment(Imm, 4LL)) - return Error(IDLoc, "misaligned immediate operand value"); - if (Imm < 0 || Imm > 255) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::ANDI16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 || - Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 || - Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::LBU16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < -1 || Imm > 14) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::SB16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < 0 || Imm > 15) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::LHU16_MM: - case Mips::SH16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < 0 || Imm > 30 || (Imm % 2 != 0)) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::LW16_MM: - case Mips::SW16_MM: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::CACHE: - case Mips::PREF: - Opnd = Inst.getOperand(2); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - Imm = Opnd.getImm(); - if (!isUInt<5>(Imm)) - return Error(IDLoc, "immediate operand value out of range"); - break; - case Mips::ADDIUPC_MM: - MCOperand Opnd = Inst.getOperand(1); - if (!Opnd.isImm()) - return Error(IDLoc, "expected immediate operand kind"); - int Imm = Opnd.getImm(); - if ((Imm % 4 != 0) || !isIntN(25, Imm)) - return Error(IDLoc, "immediate operand value out of range"); - break; + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::ADDIUR1SP_MM: + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (OffsetToAlignment(Imm, 4LL)) + return Error(IDLoc, "misaligned immediate operand value"); + if (Imm < 0 || Imm > 255) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::ANDI16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 || + Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 || + Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::LBU16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -1 || Imm > 14) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::SB16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > 15) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::LHU16_MM: + case Mips::SH16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > 30 || (Imm % 2 != 0)) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::LW16_MM: + case Mips::SW16_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::CACHE: + case Mips::PREF: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (!isUInt<5>(Imm)) + return Error(IDLoc, "immediate operand value out of range"); + break; + case Mips::ADDIUPC_MM: + MCOperand Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + int Imm = Opnd.getImm(); + if ((Imm % 4 != 0) || !isIntN(25, Imm)) + return Error(IDLoc, "immediate operand value out of range"); + break; } } @@ -1635,6 +1640,10 @@ case Mips::BLEU: case Mips::BGEU: case Mips::BGTU: + case Mips::ROL: + case Mips::ROLImm: + case Mips::ROR: + case Mips::RORImm: return true; default: return false; @@ -1644,7 +1653,8 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions) { switch (Inst.getOpcode()) { - default: llvm_unreachable("unimplemented expansion"); + default: + llvm_unreachable("unimplemented expansion"); case Mips::LoadImm32: return expandLoadImm(Inst, true, IDLoc, Instructions); case Mips::LoadImm64: @@ -1673,6 +1683,12 @@ case Mips::BGEU: case Mips::BGTU: return expandCondBranches(Inst, IDLoc, Instructions); + case Mips::ROL: + case Mips::ROR: + return expandRotation(Inst, IDLoc, Instructions); + case Mips::ROLImm: + case Mips::RORImm: + return expandRotationImm(Inst, IDLoc, Instructions); } } @@ -1925,7 +1941,7 @@ bool MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, - SmallVectorImpl &Instructions) { + SmallVectorImpl &Instructions) { const MCOperand &DstRegOp = Inst.getOperand(0); assert(DstRegOp.isReg() && "expected register operand kind"); @@ -1953,7 +1969,7 @@ bool MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, - SmallVectorImpl &Instructions) { + SmallVectorImpl &Instructions) { const MCOperand &DstRegOp = Inst.getOperand(0); assert(DstRegOp.isReg() && "expected register operand kind"); @@ -2086,15 +2102,15 @@ unsigned OpCode = 0; switch(Inst.getOpcode()) { - case Mips::BneImm: - OpCode = Mips::BNE; - break; - case Mips::BeqImm: - OpCode = Mips::BEQ; - break; - default: - llvm_unreachable("Unknown immediate branch pseudo-instruction."); - break; + case Mips::BneImm: + OpCode = Mips::BNE; + break; + case Mips::BeqImm: + OpCode = Mips::BEQ; + break; + default: + llvm_unreachable("Unknown immediate branch pseudo-instruction."); + break; } int64_t ImmValue = ImmOp.getImm(); @@ -2234,8 +2250,8 @@ unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; assert (Inst.getOperand(OpNum - 1).isImm() && - Inst.getOperand(OpNum - 2).isReg() && - Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); + Inst.getOperand(OpNum - 2).isReg() && + Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && Inst.getOperand(OpNum - 1).getImm() >= 0 && @@ -2449,6 +2465,134 @@ return false; } +bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + + unsigned ATReg = Mips::NoRegister; + unsigned DReg = Mips::NoRegister; + unsigned SReg = Mips::NoRegister; + unsigned TReg = Mips::NoRegister; + + unsigned FirstShift = Mips::NOP; + unsigned SecondShift = Mips::NOP; + + switch (Inst.getOpcode()) { + default: + llvm_unreachable("unexpected instruction opcode"); + case Mips::ROL: + FirstShift = Mips::SRLV; + SecondShift = Mips::SLLV; + break; + case Mips::ROR: + FirstShift = Mips::SLLV; + SecondShift = Mips::SRLV; + break; + } + + DReg = Inst.getOperand(0).getReg(); + SReg = Inst.getOperand(1).getReg(); + if (Inst.getOperand(2).isReg()) + TReg = Inst.getOperand(2).getReg(); + + ATReg = getATReg(Inst.getLoc()); + + MCInst TmpInst; + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(Mips::SUBu); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + TmpInst.addOperand(MCOperand::createReg(Mips::ZERO)); + TmpInst.addOperand(MCOperand::createReg(TReg)); + Instructions.push_back(TmpInst); + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(FirstShift); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + TmpInst.addOperand(MCOperand::createReg(SReg)); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + Instructions.push_back(TmpInst); + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(SecondShift); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(SReg)); + TmpInst.addOperand(MCOperand::createReg(TReg)); + Instructions.push_back(TmpInst); + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(Mips::OR); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + Instructions.push_back(TmpInst); + + return false; +} + +bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + + unsigned ATReg = Mips::NoRegister; + unsigned DReg = Mips::NoRegister; + unsigned SReg = Mips::NoRegister; + int64_t ImmValue = 0; + + unsigned FrstShift = Mips::NOP; + unsigned ScndShift = Mips::NOP; + + switch (Inst.getOpcode()) { + default: + llvm_unreachable("unexpected instruction opcode"); + case Mips::ROLImm: + FrstShift = Mips::SLL; + ScndShift = Mips::SRL; + break; + case Mips::RORImm: + FrstShift = Mips::SRL; + ScndShift = Mips::SLL; + break; + } + + DReg = Inst.getOperand(0).getReg(); + SReg = Inst.getOperand(1).getReg(); + if (Inst.getOperand(2).isImm()) + ImmValue = Inst.getOperand(2).getImm(); + + ATReg = getATReg(Inst.getLoc()); + + MCInst TmpInst; + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(FrstShift); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + TmpInst.addOperand(MCOperand::createReg(SReg)); + TmpInst.addOperand(MCOperand::createImm(ImmValue)); + Instructions.push_back(TmpInst); + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(ScndShift); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(SReg)); + TmpInst.addOperand(MCOperand::createImm(32 - ImmValue)); + Instructions.push_back(TmpInst); + + TmpInst.clear(); + TmpInst.setLoc(Inst.getLoc()); + TmpInst.setOpcode(Mips::OR); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(DReg)); + TmpInst.addOperand(MCOperand::createReg(ATReg)); + Instructions.push_back(TmpInst); + + return false; +} + void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc, SmallVectorImpl &Instructions) { MCInst NopInst; @@ -2545,7 +2689,7 @@ void MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, - SMRange Range, bool ShowColors) { + SMRange Range, bool ShowColors) { getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg, Range, SMFixIt(Range, FixMsg), ShowColors); @@ -2633,12 +2777,12 @@ int CC; CC = StringSwitch(Name) - .Case("hwr_cpunum", 0) - .Case("hwr_synci_step", 1) - .Case("hwr_cc", 2) - .Case("hwr_ccres", 3) - .Case("hwr_ulr", 29) - .Default(-1); + .Case("hwr_cpunum", 0) + .Case("hwr_synci_step", 1) + .Case("hwr_cc", 2) + .Case("hwr_ccres", 3) + .Case("hwr_ulr", 29) + .Default(-1); return CC; } @@ -3897,7 +4041,7 @@ // Create a copy of the current assembler options environment and push it. AssemblerOptions.push_back( - make_unique(AssemblerOptions.back().get())); + make_unique(AssemblerOptions.back().get())); getTargetStreamer().emitDirectiveSetPush(); return false; @@ -4341,8 +4485,8 @@ getParser().getStreamer().EmitGPRel32Value(Value); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getLoc(), - "unexpected token, expected end of statement"); + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); Parser.Lex(); // Eat EndOfStatement token. return false; } @@ -4359,8 +4503,8 @@ getParser().getStreamer().EmitGPRel64Value(Value); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getLoc(), - "unexpected token, expected end of statement"); + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); Parser.Lex(); // Eat EndOfStatement token. return false; } @@ -4401,7 +4545,7 @@ } // Unknown option. - Warning(Parser.getTok().getLoc(), + Warning(Parser.getTok().getLoc(), "unknown option, expected 'pic0' or 'pic2'"); Parser.eatToEndOfStatement(); return false; @@ -4800,7 +4944,7 @@ if (IDVal == ".abicalls") { getTargetStreamer().emitDirectiveAbiCalls(); if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { - Error(Parser.getTok().getLoc(), + Error(Parser.getTok().getLoc(), "unexpected token, expected end of statement"); // Clear line Parser.eatToEndOfStatement(); Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -1554,6 +1554,28 @@ def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>, INSN_MIPS3_32_NOT_32R6_64R6; +def ROL : MipsAsmPseudoInst<(outs), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), + "rol\t$rs, $rt, $rd"> ; +def ROLImm : MipsAsmPseudoInst<(outs), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), + "rol\t$rs, $rt, $imm"> ; +def : MipsInstAlias<"rol $rd, $rs", + (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; +def : MipsInstAlias<"rol $rd, $imm", + (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>; + +def ROR : MipsAsmPseudoInst<(outs), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), + "ror\t$rs, $rt, $rd"> ; +def RORImm : MipsAsmPseudoInst<(outs), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), + "ror\t$rs, $rt, $imm"> ; +def : MipsInstAlias<"ror $rd, $rs", + (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; +def : MipsInstAlias<"ror $rd, $imm", + (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>; + //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// @@ -1620,7 +1642,7 @@ def : MipsInstAlias<"beqzl $rs,$offset", (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; def : MipsInstAlias<"syscall", (SYSCALL 0), 1>; - + def : MipsInstAlias<"break", (BREAK 0, 0), 1>; def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>; def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2; Index: test/MC/Mips/rotations.s =================================================================== --- test/MC/Mips/rotations.s +++ test/MC/Mips/rotations.s @@ -0,0 +1,73 @@ +# RUN: llvm-mc %s -triple mips-unknown-linux -show-encoding | FileCheck %s + + .text +foo: + rol $4,$5 +# CHECK: negu $1, $5 # encoding: [0x00,0x05,0x08,0x23] +# CHECK: srlv $1, $4, $1 # encoding: [0x00,0x24,0x08,0x06] +# CHECK: sllv $4, $4, $5 # encoding: [0x00,0xa4,0x20,0x04] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,$5,$6 +# CHECK: negu $1, $6 # encoding: [0x00,0x06,0x08,0x23] +# CHECK: srlv $1, $5, $1 # encoding: [0x00,0x25,0x08,0x06] +# CHECK: sllv $4, $5, $6 # encoding: [0x00,0xc5,0x20,0x04] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,0 +# CHECK: sll $1, $4, 0 # encoding: [0x00,0x04,0x08,0x00] +# CHECK: srl $4, $4, 32 # encoding: [0x00,0x04,0x20,0x02] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,$5,0 +# CHECK: sll $1, $5, 0 # encoding: [0x00,0x05,0x08,0x00] +# CHECK: srl $4, $5, 32 # encoding: [0x00,0x05,0x20,0x02] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,1 +# CHECK: sll $1, $4, 1 # encoding: [0x00,0x04,0x08,0x40] +# CHECK: srl $4, $4, 31 # encoding: [0x00,0x04,0x27,0xc2] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,$5,1 +# CHECK: sll $1, $5, 1 # encoding: [0x00,0x05,0x08,0x40] +# CHECK: srl $4, $5, 31 # encoding: [0x00,0x05,0x27,0xc2] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,2 +# CHECK: sll $1, $4, 2 # encoding: [0x00,0x04,0x08,0x80] +# CHECK: srl $4, $4, 30 # encoding: [0x00,0x04,0x27,0x82] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + rol $4,$5,2 +# CHECK: sll $1, $5, 2 # encoding: [0x00,0x05,0x08,0x80] +# CHECK: srl $4, $5, 30 # encoding: [0x00,0x05,0x27,0x82] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + + ror $4,$5 +# CHECK: negu $1, $5 # encoding: [0x00,0x05,0x08,0x23] +# CHECK: sllv $1, $4, $1 # encoding: [0x00,0x24,0x08,0x04] +# CHECK: srlv $4, $4, $5 # encoding: [0x00,0xa4,0x20,0x06] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,$5,$6 +# CHECK: negu $1, $6 # encoding: [0x00,0x06,0x08,0x23] +# CHECK: sllv $1, $5, $1 # encoding: [0x00,0x25,0x08,0x04] +# CHECK: srlv $4, $5, $6 # encoding: [0x00,0xc5,0x20,0x06] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,0 +# CHECK: srl $1, $4, 0 # encoding: [0x00,0x04,0x08,0x02] +# CHECK: sll $4, $4, 32 # encoding: [0x00,0x04,0x20,0x00] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,$5,0 +# CHECK: srl $1, $5, 0 # encoding: [0x00,0x05,0x08,0x02] +# CHECK: sll $4, $5, 32 # encoding: [0x00,0x05,0x20,0x00] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,1 +# CHECK: srl $1, $4, 1 # encoding: [0x00,0x04,0x08,0x42] +# CHECK: sll $4, $4, 31 # encoding: [0x00,0x04,0x27,0xc0] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,$5,1 +# CHECK: srl $1, $5, 1 # encoding: [0x00,0x05,0x08,0x42] +# CHECK: sll $4, $5, 31 # encoding: [0x00,0x05,0x27,0xc0] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,2 +# CHECK: srl $1, $4, 2 # encoding: [0x00,0x04,0x08,0x82] +# CHECK: sll $4, $4, 30 # encoding: [0x00,0x04,0x27,0x80] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25] + ror $4,$5,2 +# CHECK: srl $1, $5, 2 # encoding: [0x00,0x05,0x08,0x82] +# CHECK: sll $4, $5, 30 # encoding: [0x00,0x05,0x27,0x80] +# CHECK: or $4, $4, $1 # encoding: [0x00,0x81,0x20,0x25]