mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[mips][micromips] Implement SWM32 and LWM32 instructions
Differential Revision: http://reviews.llvm.org/D5519 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222367 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ca72befdb5
commit
d67cd80220
@ -146,6 +146,9 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
|
||||
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 &Operands) {
|
||||
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 =
|
||||
|
@ -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(MCInst &Inst,
|
||||
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(MCInst &Inst, unsigned Insn,
|
||||
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;
|
||||
}
|
||||
|
@ -225,6 +225,18 @@ printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) {
|
||||
// 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(const MCInst *MI, raw_ostream &O) {
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(const MCInst &MI, unsigned OpNo,
|
||||
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"
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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};
|
||||
}
|
||||
|
@ -271,6 +271,35 @@ class LoadWordIndexedScaledMM<string opstr, RegisterOperand RO,
|
||||
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", Predicates = [InMicroMips] in {
|
||||
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>;
|
||||
|
@ -645,6 +645,18 @@ printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
|
||||
// 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, int opNum, raw_ostream &O,
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user