[llvm] r222367 - [mips][micromips] Implement SWM32 and LWM32 instructions
Zoran Jovanovic
zoran.jovanovic at imgtec.com
Wed Nov 19 08:44:03 PST 2014
Author: zjovanovic
Date: Wed Nov 19 10:44:02 2014
New Revision: 222367
URL: http://llvm.org/viewvc/llvm-project?rev=222367&view=rev
Log:
[mips][micromips] Implement SWM32 and LWM32 instructions
Differential Revision: http://reviews.llvm.org/D5519
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td
llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h
llvm/trunk/test/MC/Disassembler/Mips/micromips.txt
llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt
llvm/trunk/test/MC/Mips/micromips-invalid.s
llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Wed Nov 19 10:44:02 2014
@@ -146,6 +146,9 @@ class MipsAsmParser : public MCTargetAsm
MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
+ MipsAsmParser::OperandMatchResultTy
+ parseRegisterList (OperandVector &Operands);
+
bool searchSymbolAlias(OperandVector &Operands);
bool parseOperand(OperandVector &, StringRef Mnemonic);
@@ -424,7 +427,8 @@ private:
k_Memory, /// Base + Offset Memory Address
k_PhysRegister, /// A physical register from the Mips namespace
k_RegisterIndex, /// A register index in one or more RegKind.
- k_Token /// A simple token
+ k_Token, /// A simple token
+ k_RegList /// A physical register list
} Kind;
public:
@@ -459,12 +463,17 @@ private:
const MCExpr *Off;
};
+ struct RegListOp {
+ SmallVector<unsigned, 10> *List;
+ };
+
union {
struct Token Tok;
struct PhysRegOp PhysReg;
struct RegIdxOp RegIdx;
struct ImmOp Imm;
struct MemOp Mem;
+ struct RegListOp RegList;
};
SMLoc StartLoc, EndLoc;
@@ -751,6 +760,13 @@ public:
addExpr(Inst, Expr);
}
+ void addRegListOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+
+ for (auto RegNo : getRegList())
+ Inst.addOperand(MCOperand::CreateReg(RegNo));
+ }
+
bool isReg() const override {
// As a special case until we sort out the definition of div/divu, pretend
// that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
@@ -783,6 +799,7 @@ public:
int64_t Val = getConstantImm();
return 1 <= Val && Val <= 4;
}
+ bool isRegList() const { return Kind == k_RegList; }
StringRef getToken() const {
assert(Kind == k_Token && "Invalid access!");
@@ -824,6 +841,11 @@ public:
return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
}
+ const SmallVectorImpl<unsigned> &getRegList() const {
+ assert((Kind == k_RegList) && "Invalid access!");
+ return *(RegList.List);
+ }
+
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_Token, Parser);
@@ -919,6 +941,20 @@ public:
return Op;
}
+ static std::unique_ptr<MipsOperand>
+ CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
+ MipsAsmParser &Parser) {
+ assert (Regs.size() > 0 && "Empty list not allowed");
+
+ auto Op = make_unique<MipsOperand>(k_RegList, Parser);
+ Op->RegList.List = new SmallVector<unsigned, 10>();
+ for (auto Reg : Regs)
+ Op->RegList.List->push_back(Reg);
+ Op->StartLoc = StartLoc;
+ Op->EndLoc = EndLoc;
+ return Op;
+ }
+
bool isGPRAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
}
@@ -973,6 +1009,8 @@ public:
case k_Memory:
delete Mem.Base;
break;
+ case k_RegList:
+ delete RegList.List;
case k_PhysRegister:
case k_RegisterIndex:
case k_Token:
@@ -1003,6 +1041,12 @@ public:
case k_Token:
OS << Tok.Data;
break;
+ case k_RegList:
+ OS << "RegList< ";
+ for (auto Reg : (*RegList.List))
+ OS << Reg << " ";
+ OS << ">";
+ break;
}
}
}; // class MipsOperand
@@ -2522,6 +2566,82 @@ MipsAsmParser::parseLSAImm(OperandVector
return MatchOperand_Success;
}
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseRegisterList(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ SmallVector<unsigned, 10> Regs;
+ unsigned RegNo;
+ unsigned PrevReg = Mips::NoRegister;
+ bool RegRange = false;
+ SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
+
+ if (Parser.getTok().isNot(AsmToken::Dollar))
+ return MatchOperand_ParseFail;
+
+ SMLoc S = Parser.getTok().getLoc();
+ while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
+ SMLoc E = getLexer().getLoc();
+ MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
+ RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
+ if (RegRange) {
+ // Remove last register operand because registers from register range
+ // should be inserted first.
+ if (RegNo == Mips::RA) {
+ Regs.push_back(RegNo);
+ } else {
+ unsigned TmpReg = PrevReg + 1;
+ while (TmpReg <= RegNo) {
+ if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
+ Error(E, "invalid register operand");
+ return MatchOperand_ParseFail;
+ }
+
+ PrevReg = TmpReg;
+ Regs.push_back(TmpReg++);
+ }
+ }
+
+ RegRange = false;
+ } else {
+ if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
+ (RegNo != Mips::RA)) {
+ Error(E, "$16 or $31 expected");
+ return MatchOperand_ParseFail;
+ } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
+ (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
+ Error(E, "invalid register operand");
+ return MatchOperand_ParseFail;
+ } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
+ (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
+ Error(E, "consecutive register numbers expected");
+ return MatchOperand_ParseFail;
+ }
+
+ Regs.push_back(RegNo);
+ }
+
+ if (Parser.getTok().is(AsmToken::Minus))
+ RegRange = true;
+
+ if (!Parser.getTok().isNot(AsmToken::Minus) &&
+ !Parser.getTok().isNot(AsmToken::Comma)) {
+ Error(E, "',' or '-' expected");
+ return MatchOperand_ParseFail;
+ }
+
+ Lex(); // Consume comma or minus
+ if (Parser.getTok().isNot(AsmToken::Dollar))
+ break;
+
+ PrevReg = RegNo;
+ }
+
+ SMLoc E = Parser.getTok().getLoc();
+ Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
+ parseMemOperand(Operands);
+ return MatchOperand_Success;
+}
+
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
MCSymbolRefExpr::VariantKind VK =
Modified: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp Wed Nov 19 10:44:02 2014
@@ -341,6 +341,10 @@ static DecodeStatus
DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
namespace llvm {
extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
TheMips64elTarget;
@@ -1034,12 +1038,23 @@ static DecodeStatus DecodeMemMMImm12(MCI
Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
- if (Inst.getOpcode() == Mips::SC_MM)
+ switch (Inst.getOpcode()) {
+ case Mips::SWM32_MM:
+ case Mips::LWM32_MM:
+ if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
+ == MCDisassembler::Fail)
+ return MCDisassembler::Fail;
+ Inst.addOperand(MCOperand::CreateReg(Base));
+ Inst.addOperand(MCOperand::CreateImm(Offset));
+ break;
+ case Mips::SC_MM:
Inst.addOperand(MCOperand::CreateReg(Reg));
-
- Inst.addOperand(MCOperand::CreateReg(Reg));
- Inst.addOperand(MCOperand::CreateReg(Base));
- Inst.addOperand(MCOperand::CreateImm(Offset));
+ // fallthrough
+ default:
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ Inst.addOperand(MCOperand::CreateReg(Base));
+ Inst.addOperand(MCOperand::CreateImm(Offset));
+ }
return MCDisassembler::Success;
}
@@ -1375,3 +1390,26 @@ static DecodeStatus DecodeSimm18Lsl3(MCI
Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
return MCDisassembler::Success;
}
+
+static DecodeStatus DecodeRegListOperand(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
+ Mips::S6, Mips::FP};
+ unsigned RegNum;
+
+ unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
+ // Empty register lists are not allowed.
+ if (RegLst == 0)
+ return MCDisassembler::Fail;
+
+ RegNum = RegLst & 0xf;
+ for (unsigned i = 0; i < RegNum; i++)
+ Inst.addOperand(MCOperand::CreateReg(Regs[i]));
+
+ if (RegLst & 0x10)
+ Inst.addOperand(MCOperand::CreateReg(Mips::RA));
+
+ return MCDisassembler::Success;
+}
Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp Wed Nov 19 10:44:02 2014
@@ -225,6 +225,18 @@ printMemOperand(const MCInst *MI, int op
// Load/Store memory operands -- imm($reg)
// If PIC target the target is loaded as the
// pattern lw $25,%call16($28)
+
+ // opNum can be invalid if instruction had reglist as operand.
+ // MemOperand is always last operand of instruction (base + offset).
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case Mips::SWM32_MM:
+ case Mips::LWM32_MM:
+ opNum = MI->getNumOperands() - 2;
+ break;
+ }
+
printOperand(MI, opNum+1, O);
O << "(";
printOperand(MI, opNum, O);
@@ -324,3 +336,13 @@ void MipsInstPrinter::printSaveRestore(c
}
}
+void MipsInstPrinter::
+printRegisterList(const MCInst *MI, int opNum, raw_ostream &O) {
+ // - 2 because register List is always first operand of instruction and it is
+ // always followed by memory operand (base + offset).
+ for (int i = opNum, e = MI->getNumOperands() - 2; i != e; ++i) {
+ if (i != opNum)
+ O << ", ";
+ printRegName(O, MI->getOperand(i).getReg());
+ }
+}
Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h (original)
+++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.h Wed Nov 19 10:44:02 2014
@@ -107,6 +107,7 @@ private:
unsigned OpNo1, raw_ostream &OS);
bool printAlias(const MCInst &MI, raw_ostream &OS);
void printSaveRestore(const MCInst *MI, raw_ostream &O);
+ void printRegisterList(const MCInst *MI, int opNum, raw_ostream &O);
};
} // end namespace llvm
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Wed Nov 19 10:44:02 2014
@@ -638,6 +638,17 @@ unsigned MipsMCCodeEmitter::
getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
+ // opNum can be invalid if instruction had reglist as operand.
+ // MemOperand is always last operand of instruction (base + offset).
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case Mips::SWM32_MM:
+ case Mips::LWM32_MM:
+ OpNo = MI.getNumOperands() - 2;
+ break;
+ }
+
// Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
assert(MI.getOperand(OpNo).isReg());
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
@@ -757,4 +768,24 @@ MipsMCCodeEmitter::getUImm4AndValue(cons
llvm_unreachable("Unexpected value");
}
+unsigned
+MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ unsigned res = 0;
+
+ // Register list operand is always first operand of instruction and it is
+ // placed before memory operand (register + imm).
+
+ for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
+ unsigned Reg = MI.getOperand(I).getReg();
+ unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
+ if (RegNo != 31)
+ res++;
+ else
+ res |= 0x10;
+ }
+ return res;
+}
+
#include "MipsGenMCCodeEmitter.inc"
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h Wed Nov 19 10:44:02 2014
@@ -175,6 +175,9 @@ public:
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ unsigned getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
}; // class MipsMCCodeEmitter
} // namespace llvm.
Modified: llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td Wed Nov 19 10:44:02 2014
@@ -804,3 +804,16 @@ class LWXS_FM_MM<bits<10> funct> {
let Inst{10} = 0;
let Inst{9-0} = funct;
}
+
+class LWM_FM_MM<bits<4> funct> : MMArch {
+ bits<5> rt;
+ bits<21> addr;
+
+ bits<32> Inst;
+
+ let Inst{31-26} = 0x8;
+ let Inst{25-21} = rt;
+ let Inst{20-16} = addr{20-16};
+ let Inst{15-12} = funct;
+ let Inst{11-0} = addr{11-0};
+}
Modified: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td Wed Nov 19 10:44:02 2014
@@ -271,6 +271,35 @@ class LoadWordIndexedScaledMM<string ops
InstSE<(outs RO:$rd), (ins PtrRC:$base, PtrRC:$index),
!strconcat(opstr, "\t$rd, ${index}(${base})"), [], Itin, FrmFI>;
+/// A list of registers used by load/store multiple instructions.
+def RegListAsmOperand : AsmOperandClass {
+ let Name = "RegList";
+ let ParserMethod = "parseRegisterList";
+}
+
+def reglist : Operand<i32> {
+ let EncoderMethod = "getRegisterListOpValue";
+ let ParserMatchClass = RegListAsmOperand;
+ let PrintMethod = "printRegisterList";
+ let DecoderMethod = "DecodeRegListOperand";
+}
+
+class StoreMultMM<string opstr,
+ InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
+ InstSE<(outs), (ins reglist:$rt, mem_mm_12:$addr),
+ !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
+ let DecoderMethod = "DecodeMemMMImm12";
+ let mayStore = 1;
+}
+
+class LoadMultMM<string opstr,
+ InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
+ InstSE<(outs reglist:$rt), (ins mem_mm_12:$addr),
+ !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
+ let DecoderMethod = "DecodeMemMMImm12";
+ let mayLoad = 1;
+}
+
def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>,
ARITH_FM_MM16<0>;
def SUBU16_MM : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
@@ -402,6 +431,10 @@ let DecoderNamespace = "MicroMips", Pred
def SWR_MM : StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12>,
LWL_FM_MM<0x9>;
+ /// Load and Store Instructions - multiple
+ def SWM32_MM : StoreMultMM<"swm32">, LWM_FM_MM<0xd>;
+ def LWM32_MM : LoadMultMM<"lwm32">, LWM_FM_MM<0x5>;
+
/// Move Conditional
def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
NoItinerary>, ADD_FM_MM<0, 0x58>;
Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Wed Nov 19 10:44:02 2014
@@ -645,6 +645,18 @@ printMemOperand(const MachineInstr *MI,
// Load/Store memory operands -- imm($reg)
// If PIC target the target is loaded as the
// pattern lw $25,%call16($28)
+
+ // opNum can be invalid if instruction has reglist as operand.
+ // MemOperand is always last operand of instruction (base + offset).
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case Mips::SWM32_MM:
+ case Mips::LWM32_MM:
+ opNum = MI->getNumOperands() - 2;
+ break;
+ }
+
printOperand(MI, opNum+1, O);
O << "(";
printOperand(MI, opNum, O);
@@ -668,6 +680,14 @@ printFCCOperand(const MachineInstr *MI,
O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
}
+void MipsAsmPrinter::
+printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
+ for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
+ if (i != opNum) O << ", ";
+ printOperand(MI, i, O);
+ }
+}
+
void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
bool IsABICalls = Subtarget->isABICalls();
if (IsABICalls) {
Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.h Wed Nov 19 10:44:02 2014
@@ -134,6 +134,7 @@ public:
void printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O);
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = nullptr);
+ void printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O);
void EmitStartOfAsmFile(Module &M) override;
void EmitEndOfAsmFile(Module &M) override;
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
Modified: llvm/trunk/test/MC/Disassembler/Mips/micromips.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/micromips.txt?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/micromips.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Mips/micromips.txt Wed Nov 19 10:44:02 2014
@@ -315,3 +315,9 @@
# CHECK: jalrs $ra, $6
0x03 0xe6 0x4f 0x3c
+
+# CHECK: lwm32 $16, $17, 8($4)
+0x20 0x44 0x50 0x08
+
+# CHECK: swm32 $16, $17, 8($4)
+0x20 0x44 0xd0 0x08
Modified: llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt (original)
+++ llvm/trunk/test/MC/Disassembler/Mips/micromips_le.txt Wed Nov 19 10:44:02 2014
@@ -315,3 +315,9 @@
# CHECK: jalrs $ra, $6
0xe6 0x03 0x3c 0x4f
+
+# CHECK: lwm32 $16, $17, 8($4)
+0x44 0x20 0x08 0x50
+
+# CHECK: swm32 $16, $17, 8($4)
+0x44 0x20 0x08 0xd0
Modified: llvm/trunk/test/MC/Mips/micromips-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips-invalid.s?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips-invalid.s (original)
+++ llvm/trunk/test/MC/Mips/micromips-invalid.s Wed Nov 19 10:44:02 2014
@@ -22,3 +22,10 @@
li16 $4, -2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
addiur2 $9, $7, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
addiur2 $6, $7, 10 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
+ lwm32 $5, $6, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
+ lwm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
+ lwm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
+ swm32 $5, $6, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
+ swm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
+ swm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
+ lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $24, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
Modified: llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s?rev=222367&r1=222366&r2=222367&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s (original)
+++ llvm/trunk/test/MC/Mips/micromips-loadstore-instructions.s Wed Nov 19 10:44:02 2014
@@ -9,33 +9,49 @@
#------------------------------------------------------------------------------
# Little endian
#------------------------------------------------------------------------------
-# CHECK-EL: lb $5, 8($4) # encoding: [0xa4,0x1c,0x08,0x00]
-# CHECK-EL: lbu $6, 8($4) # encoding: [0xc4,0x14,0x08,0x00]
-# CHECK-EL: lh $2, 8($4) # encoding: [0x44,0x3c,0x08,0x00]
-# CHECK-EL: lhu $4, 8($2) # encoding: [0x82,0x34,0x08,0x00]
-# CHECK-EL: lw $6, 4($5) # encoding: [0xc5,0xfc,0x04,0x00]
-# CHECK-EL: sb $5, 8($4) # encoding: [0xa4,0x18,0x08,0x00]
-# CHECK-EL: sh $2, 8($4) # encoding: [0x44,0x38,0x08,0x00]
-# CHECK-EL: sw $5, 4($6) # encoding: [0xa6,0xf8,0x04,0x00]
-# CHECK-EL: ll $2, 8($4) # encoding: [0x44,0x60,0x08,0x30]
-# CHECK-EL: sc $2, 8($4) # encoding: [0x44,0x60,0x08,0xb0]
-# CHECK-EL: lwu $2, 8($4) # encoding: [0x44,0x60,0x08,0xe0]
-# CHECK-EL: lwxs $2, $3($4) # encoding: [0x64,0x00,0x18,0x11]
+# CHECK-EL: lb $5, 8($4) # encoding: [0xa4,0x1c,0x08,0x00]
+# CHECK-EL: lbu $6, 8($4) # encoding: [0xc4,0x14,0x08,0x00]
+# CHECK-EL: lh $2, 8($4) # encoding: [0x44,0x3c,0x08,0x00]
+# CHECK-EL: lhu $4, 8($2) # encoding: [0x82,0x34,0x08,0x00]
+# CHECK-EL: lw $6, 4($5) # encoding: [0xc5,0xfc,0x04,0x00]
+# CHECK-EL: sb $5, 8($4) # encoding: [0xa4,0x18,0x08,0x00]
+# CHECK-EL: sh $2, 8($4) # encoding: [0x44,0x38,0x08,0x00]
+# CHECK-EL: sw $5, 4($6) # encoding: [0xa6,0xf8,0x04,0x00]
+# CHECK-EL: ll $2, 8($4) # encoding: [0x44,0x60,0x08,0x30]
+# CHECK-EL: sc $2, 8($4) # encoding: [0x44,0x60,0x08,0xb0]
+# CHECK-EL: lwu $2, 8($4) # encoding: [0x44,0x60,0x08,0xe0]
+# CHECK-EL: lwxs $2, $3($4) # encoding: [0x64,0x00,0x18,0x11]
+# CHECK-EL: lwm32 $16, $17, 8($4) # encoding: [0x44,0x20,0x08,0x50]
+# CHECK-EL: lwm32 $16, $17, $18, $19, 8($4) # encoding: [0x84,0x20,0x08,0x50]
+# CHECK-EL: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, 8($4) # encoding: [0x24,0x21,0x08,0x50]
+# CHECK-EL: lwm32 $16, $17, $18, $19, $ra, 8($4) # encoding: [0x84,0x22,0x08,0x50]
+# CHECK-EL: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x24,0x23,0x08,0x50]
+# CHECK-EL: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x24,0x23,0x08,0x50]
+# CHECK-EL: swm32 $16, $17, 8($4) # encoding: [0x44,0x20,0x08,0xd0]
+# CHECK-EL: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x84,0x20,0x08,0xd0]
#------------------------------------------------------------------------------
# Big endian
#------------------------------------------------------------------------------
-# CHECK-EB: lb $5, 8($4) # encoding: [0x1c,0xa4,0x00,0x08]
-# CHECK-EB: lbu $6, 8($4) # encoding: [0x14,0xc4,0x00,0x08]
-# CHECK-EB: lh $2, 8($4) # encoding: [0x3c,0x44,0x00,0x08]
-# CHECK-EB: lhu $4, 8($2) # encoding: [0x34,0x82,0x00,0x08]
-# CHECK-EB: lw $6, 4($5) # encoding: [0xfc,0xc5,0x00,0x04]
-# CHECK-EB: sb $5, 8($4) # encoding: [0x18,0xa4,0x00,0x08]
-# CHECK-EB: sh $2, 8($4) # encoding: [0x38,0x44,0x00,0x08]
-# CHECK-EB: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04]
-# CHECK-EB: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08]
-# CHECK-EB: sc $2, 8($4) # encoding: [0x60,0x44,0xb0,0x08]
-# CHECK-EB: lwu $2, 8($4) # encoding: [0x60,0x44,0xe0,0x08]
-# CHECK-EB: lwxs $2, $3($4) # encoding: [0x00,0x64,0x11,0x18]
+# CHECK-EB: lb $5, 8($4) # encoding: [0x1c,0xa4,0x00,0x08]
+# CHECK-EB: lbu $6, 8($4) # encoding: [0x14,0xc4,0x00,0x08]
+# CHECK-EB: lh $2, 8($4) # encoding: [0x3c,0x44,0x00,0x08]
+# CHECK-EB: lhu $4, 8($2) # encoding: [0x34,0x82,0x00,0x08]
+# CHECK-EB: lw $6, 4($5) # encoding: [0xfc,0xc5,0x00,0x04]
+# CHECK-EB: sb $5, 8($4) # encoding: [0x18,0xa4,0x00,0x08]
+# CHECK-EB: sh $2, 8($4) # encoding: [0x38,0x44,0x00,0x08]
+# CHECK-EB: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04]
+# CHECK-EB: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08]
+# CHECK-EB: sc $2, 8($4) # encoding: [0x60,0x44,0xb0,0x08]
+# CHECK-EB: lwu $2, 8($4) # encoding: [0x60,0x44,0xe0,0x08]
+# CHECK-EB: lwxs $2, $3($4) # encoding: [0x00,0x64,0x11,0x18]
+# CHECK-EB: lwm32 $16, $17, 8($4) # encoding: [0x20,0x44,0x50,0x08]
+# CHECK-EB: lwm32 $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0x50,0x08]
+# CHECK-EB: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, 8($4) # encoding: [0x21,0x24,0x50,0x08]
+# CHECK-EB: lwm32 $16, $17, $18, $19, $ra, 8($4) # encoding: [0x22,0x84,0x50,0x08]
+# CHECK-EB: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x23,0x24,0x50,0x08]
+# CHECK-EB: lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $fp, $ra, 8($4) # encoding: [0x23,0x24,0x50,0x08]
+# CHECK-EB: swm32 $16, $17, 8($4) # encoding: [0x20,0x44,0xd0,0x08]
+# CHECK-EB: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0xd0,0x08]
lb $5, 8($4)
lbu $6, 8($4)
lh $2, 8($4)
@@ -48,3 +64,11 @@
sc $2, 8($4)
lwu $2, 8($4)
lwxs $2, $3($4)
+ lwm32 $16, $17, 8($4)
+ lwm32 $16 - $19, 8($4)
+ lwm32 $16-$23, $30, 8($4)
+ lwm32 $16-$19, $31, 8($4)
+ lwm32 $16-$23, $30, $31, 8($4)
+ lwm32 $16-$23, $30 - $31, 8($4)
+ swm32 $16, $17, 8($4)
+ swm32 $16 - $19, 8($4)
More information about the llvm-commits
mailing list