[mips][microMIPS] Implement LWM16, SB16, SH16, SW16, SWSP and SWM16 instructions

Differential Revision: http://reviews.llvm.org/D11406

llvm-svn: 252885
This commit is contained in:
Zlatko Buljan 2015-11-12 13:21:33 +00:00
parent d38860610d
commit 797c2aec6b
14 changed files with 242 additions and 17 deletions

View File

@ -1007,8 +1007,13 @@ public:
return false;
int Size = RegList.List->size();
if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
RegList.List->back() != Mips::RA)
if (Size < 2 || Size > 5)
return false;
unsigned R0 = RegList.List->front();
unsigned R1 = RegList.List->back();
if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
(R0 == Mips::S0_64 && R1 == Mips::RA_64)))
return false;
int PrevReg = *RegList.List->begin();
@ -1841,6 +1846,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
case Mips::TLTU_MM:
case Mips::TNE_MM:
case Mips::SB16_MM:
case Mips::SB16_MMR6:
Opnd = Inst.getOperand(2);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
@ -1850,6 +1856,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
break;
case Mips::LHU16_MM:
case Mips::SH16_MM:
case Mips::SH16_MMR6:
Opnd = Inst.getOperand(2);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
@ -1859,6 +1866,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
break;
case Mips::LW16_MM:
case Mips::SW16_MM:
case Mips::SW16_MMR6:
Opnd = Inst.getOperand(2);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
@ -2612,10 +2620,16 @@ MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
Inst.getOperand(OpNum - 1).getImm() >= 0 &&
Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
(Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
(Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
// It can be implemented as SWM16 or LWM16 instruction.
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
if (inMicroMipsMode() && hasMips32r6())
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
else
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
}
Inst.setOpcode(NewOpcode);
Instructions.push_back(Inst);
@ -4145,12 +4159,15 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) {
if (RegRange) {
// Remove last register operand because registers from register range
// should be inserted first.
if (RegNo == Mips::RA) {
if ((isGP64bit() && RegNo == Mips::RA_64) ||
(!isGP64bit() && RegNo == Mips::RA)) {
Regs.push_back(RegNo);
} else {
unsigned TmpReg = PrevReg + 1;
while (TmpReg <= RegNo) {
if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
(((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
isGP64bit())) {
Error(E, "invalid register operand");
return MatchOperand_ParseFail;
}
@ -4162,16 +4179,23 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) {
RegRange = false;
} else {
if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
(RegNo != Mips::RA)) {
if ((PrevReg == Mips::NoRegister) &&
((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
(!isGP64bit() && (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)) {
} else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
(RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
!isGP64bit()) ||
((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
(RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
isGP64bit()))) {
Error(E, "invalid register operand");
return MatchOperand_ParseFail;
} else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
(RegNo != Mips::FP) && (RegNo != Mips::RA)) {
((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
(RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
isGP64bit()))) {
Error(E, "consecutive register numbers expected");
return MatchOperand_ParseFail;
}

View File

@ -1380,8 +1380,11 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
return MCDisassembler::Fail;
break;
case Mips::SB16_MM:
case Mips::SB16_MMR6:
case Mips::SH16_MM:
case Mips::SH16_MMR6:
case Mips::SW16_MM:
case Mips::SW16_MMR6:
if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
== MCDisassembler::Fail)
return MCDisassembler::Fail;
@ -1400,14 +1403,17 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
Inst.addOperand(MCOperand::createImm(Offset));
break;
case Mips::SB16_MM:
case Mips::SB16_MMR6:
Inst.addOperand(MCOperand::createImm(Offset));
break;
case Mips::LHU16_MM:
case Mips::SH16_MM:
case Mips::SH16_MMR6:
Inst.addOperand(MCOperand::createImm(Offset << 1));
break;
case Mips::LW16_MM:
case Mips::SW16_MM:
case Mips::SW16_MMR6:
Inst.addOperand(MCOperand::createImm(Offset << 2));
break;
}
@ -1451,7 +1457,16 @@ static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder) {
int Offset = SignExtend32<4>(Insn & 0xf);
int Offset;
switch (Inst.getOpcode()) {
case Mips::LWM16_MMR6:
case Mips::SWM16_MMR6:
Offset = fieldFromInstruction(Insn, 4, 4);
break;
default:
Offset = SignExtend32<4>(Insn & 0xf);
break;
}
if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
== MCDisassembler::Fail)
@ -2009,7 +2024,16 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder) {
unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
unsigned RegLst = fieldFromInstruction(Insn, 4, 2);
unsigned RegLst;
switch(Inst.getOpcode()) {
default:
RegLst = fieldFromInstruction(Insn, 4, 2);
break;
case Mips::LWM16_MMR6:
case Mips::SWM16_MMR6:
RegLst = fieldFromInstruction(Insn, 8, 2);
break;
}
unsigned RegNum = RegLst & 0x3;
for (unsigned i = 0; i <= RegNum; i++)

View File

@ -235,7 +235,9 @@ printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) {
case Mips::SWM32_MM:
case Mips::LWM32_MM:
case Mips::SWM16_MM:
case Mips::SWM16_MMR6:
case Mips::LWM16_MM:
case Mips::LWM16_MMR6:
opNum = MI->getNumOperands() - 2;
break;
}

View File

@ -832,7 +832,9 @@ getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
default:
break;
case Mips::SWM16_MM:
case Mips::SWM16_MMR6:
case Mips::LWM16_MM:
case Mips::LWM16_MMR6:
OpNo = MI.getNumOperands() - 2;
break;
}

View File

@ -62,6 +62,18 @@ class POOL16C_JRCADDIUSP_FM_MM16R6<bits<5> op> {
let Inst{4-0} = op;
}
class POOL16C_LWM_SWM_FM_MM16R6<bits<4> funct> {
bits<2> rt;
bits<4> addr;
bits<16> Inst;
let Inst{15-10} = 0x11;
let Inst{9-8} = rt;
let Inst{7-4} = addr;
let Inst{3-0} = funct;
}
class POOL32A_BITSWAP_FM_MMR6<bits<6> funct> : MipsR6Inst {
bits<5> rd;
bits<5> rt;

View File

@ -55,6 +55,7 @@ class JRC16_MMR6_ENC: POOL16C_JALRC_FM_MM16R6<0x3>;
class JRCADDIUSP_MMR6_ENC : POOL16C_JRCADDIUSP_FM_MM16R6<0x13>;
class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>;
class LWPC_MMR6_ENC : PCREL19_FM_MMR6<0b01>;
class LWM16_MMR6_ENC : POOL16C_LWM_SWM_FM_MM16R6<0x2>;
class MOD_MMR6_ENC : ARITH_FM_MMR6<"mod", 0x158>;
class MODU_MMR6_ENC : ARITH_FM_MMR6<"modu", 0x1d8>;
class MUL_MMR6_ENC : ARITH_FM_MMR6<"mul", 0x18>;
@ -65,15 +66,20 @@ class NOR_MMR6_ENC : ARITH_FM_MMR6<"nor", 0x2d0>;
class OR_MMR6_ENC : ARITH_FM_MMR6<"or", 0x290>;
class ORI_MMR6_ENC : ADDI_FM_MMR6<"ori", 0x14>;
class PREF_MMR6_ENC : CACHE_PREF_FM_MMR6<0b011000, 0b0010>;
class SB16_MMR6_ENC : LOAD_STORE_FM_MM16<0x22>;
class SEB_MMR6_ENC : SIGN_EXTEND_FM_MMR6<"seb", 0b0010101100>;
class SEH_MMR6_ENC : SIGN_EXTEND_FM_MMR6<"seh", 0b0011101100>;
class SELEQZ_MMR6_ENC : POOL32A_FM_MMR6<0b0101000000>;
class SELNEZ_MMR6_ENC : POOL32A_FM_MMR6<0b0110000000>;
class SH16_MMR6_ENC : LOAD_STORE_FM_MM16<0x2a>;
class SLL_MMR6_ENC : SHIFT_MMR6_ENC<"sll", 0x00, 0b0>;
class SUB_MMR6_ENC : ARITH_FM_MMR6<"sub", 0x190>;
class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>;
class SW_MMR6_ENC : SW32_FM_MMR6<"sw", 0x3e>;
class SWE_MMR6_ENC : POOL32C_SWE_FM_MMR6<"swe", 0x18, 0xa, 0x7>;
class SW16_MMR6_ENC : LOAD_STORE_FM_MM16<0x3a>;
class SWM16_MMR6_ENC : POOL16C_LWM_SWM_FM_MM16R6<0xa>;
class SWSP_MMR6_ENC : LOAD_STORE_SP_FM_MM16<0x32>;
class PREFE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b010>;
class CACHEE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b011>;
class WRPGPR_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x3c5>;
@ -814,6 +820,52 @@ class SDBBP_MMR6_DESC : MipsR6Inst {
list<dag> Pattern = [];
}
class LWM16_MMR6_DESC
: MicroMipsInst16<(outs reglist16:$rt), (ins mem_mm_4sp:$addr),
!strconcat("lwm16", "\t$rt, $addr"), [],
NoItinerary, FrmI>,
MMR6Arch<"lwm16">, MicroMipsR6Inst16 {
let DecoderMethod = "DecodeMemMMReglistImm4Lsl2";
let mayLoad = 1;
InstrItinClass Itin = NoItinerary;
ComplexPattern Addr = addr;
}
class SWM16_MMR6_DESC
: MicroMipsInst16<(outs), (ins reglist16:$rt, mem_mm_4sp:$addr),
!strconcat("swm16", "\t$rt, $addr"), [],
NoItinerary, FrmI>,
MMR6Arch<"swm16">, MicroMipsR6Inst16 {
let DecoderMethod = "DecodeMemMMReglistImm4Lsl2";
let mayStore = 1;
InstrItinClass Itin = NoItinerary;
ComplexPattern Addr = addr;
}
class SB16_MMR6_DESC_BASE<string opstr, DAGOperand RTOpnd, DAGOperand RO,
SDPatternOperator OpNode, InstrItinClass Itin,
Operand MemOpnd>
: MicroMipsInst16<(outs), (ins RTOpnd:$rt, MemOpnd:$addr),
!strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI>,
MMR6Arch<opstr>, MicroMipsR6Inst16 {
let DecoderMethod = "DecodeMemMMImm4";
let mayStore = 1;
}
class SB16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sb16", GPRMM16OpndZero, GPRMM16Opnd,
truncstorei8, II_SB, mem_mm_4>;
class SH16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sh16", GPRMM16OpndZero, GPRMM16Opnd,
truncstorei16, II_SH, mem_mm_4_lsl1>;
class SW16_MMR6_DESC : SB16_MMR6_DESC_BASE<"sw16", GPRMM16OpndZero, GPRMM16Opnd,
store, II_SW, mem_mm_4_lsl2>;
class SWSP_MMR6_DESC
: MicroMipsInst16<(outs), (ins GPR32Opnd:$rt, mem_mm_sp_imm5_lsl2:$offset),
!strconcat("sw", "\t$rt, $offset"), [], II_SW, FrmI>,
MMR6Arch<"sw">, MicroMipsR6Inst16 {
let DecoderMethod = "DecodeMemMMSPImm5Lsl2";
let mayStore = 1;
}
//===----------------------------------------------------------------------===//
//
// Instruction Definitions
@ -874,6 +926,7 @@ def JRCADDIUSP_MMR6 : R6MMR6Rel, JRCADDIUSP_MMR6_DESC, JRCADDIUSP_MMR6_ENC,
ISA_MICROMIPS32R6;
def LSA_MMR6 : R6MMR6Rel, LSA_MMR6_ENC, LSA_MMR6_DESC, ISA_MICROMIPS32R6;
def LWPC_MMR6 : R6MMR6Rel, LWPC_MMR6_ENC, LWPC_MMR6_DESC, ISA_MICROMIPS32R6;
def LWM16_MMR6 : StdMMR6Rel, LWM16_MMR6_DESC, LWM16_MMR6_ENC, ISA_MICROMIPS32R6;
def MOD_MMR6 : R6MMR6Rel, MOD_MMR6_DESC, MOD_MMR6_ENC, ISA_MICROMIPS32R6;
def MODU_MMR6 : R6MMR6Rel, MODU_MMR6_DESC, MODU_MMR6_ENC, ISA_MICROMIPS32R6;
def MUL_MMR6 : R6MMR6Rel, MUL_MMR6_DESC, MUL_MMR6_ENC, ISA_MICROMIPS32R6;
@ -884,15 +937,20 @@ def NOR_MMR6 : StdMMR6Rel, NOR_MMR6_DESC, NOR_MMR6_ENC, ISA_MICROMIPS32R6;
def OR_MMR6 : StdMMR6Rel, OR_MMR6_DESC, OR_MMR6_ENC, ISA_MICROMIPS32R6;
def ORI_MMR6 : StdMMR6Rel, ORI_MMR6_DESC, ORI_MMR6_ENC, ISA_MICROMIPS32R6;
def PREF_MMR6 : R6MMR6Rel, PREF_MMR6_ENC, PREF_MMR6_DESC, ISA_MICROMIPS32R6;
def SB16_MMR6 : StdMMR6Rel, SB16_MMR6_DESC, SB16_MMR6_ENC, ISA_MICROMIPS32R6;
def SEB_MMR6 : StdMMR6Rel, SEB_MMR6_DESC, SEB_MMR6_ENC, ISA_MICROMIPS32R6;
def SEH_MMR6 : StdMMR6Rel, SEH_MMR6_DESC, SEH_MMR6_ENC, ISA_MICROMIPS32R6;
def SELEQZ_MMR6 : R6MMR6Rel, SELEQZ_MMR6_ENC, SELEQZ_MMR6_DESC,
ISA_MICROMIPS32R6;
def SELNEZ_MMR6 : R6MMR6Rel, SELNEZ_MMR6_ENC, SELNEZ_MMR6_DESC,
ISA_MICROMIPS32R6;
def SH16_MMR6 : StdMMR6Rel, SH16_MMR6_DESC, SH16_MMR6_ENC, ISA_MICROMIPS32R6;
def SLL_MMR6 : StdMMR6Rel, SLL_MMR6_DESC, SLL_MMR6_ENC, ISA_MICROMIPS32R6;
def SUB_MMR6 : StdMMR6Rel, SUB_MMR6_DESC, SUB_MMR6_ENC, ISA_MICROMIPS32R6;
def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6;
def SW16_MMR6 : StdMMR6Rel, SW16_MMR6_DESC, SW16_MMR6_ENC, ISA_MICROMIPS32R6;
def SWM16_MMR6 : StdMMR6Rel, SWM16_MMR6_DESC, SWM16_MMR6_ENC, ISA_MICROMIPS32R6;
def SWSP_MMR6 : StdMMR6Rel, SWSP_MMR6_DESC, SWSP_MMR6_ENC, ISA_MICROMIPS32R6;
def PREFE_MMR6 : StdMMR6Rel, PREFE_MMR6_ENC, PREFE_MMR6_DESC, ISA_MICROMIPS32R6;
def CACHEE_MMR6 : StdMMR6Rel, CACHEE_MMR6_ENC, CACHEE_MMR6_DESC,
ISA_MICROMIPS32R6;
@ -1075,3 +1133,12 @@ def : MipsInstAlias<"sdbbp", (SDBBP_MMR6 0), 1>, ISA_MICROMIPS32R6;
def : MipsInstAlias<"rdhwr $rt, $rs",
(RDHWR_MMR6 GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>,
ISA_MICROMIPS32R6;
//===----------------------------------------------------------------------===//
//
// MicroMips arbitrary patterns that map to one or more instructions
//
//===----------------------------------------------------------------------===//
def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
(SW16_MMR6 GPRMM16:$src, addrimm4lsl2:$addr)>, ISA_MICROMIPS32R6;

View File

@ -943,7 +943,7 @@ class LWM_FM_MM<bits<4> funct> : MMArch {
let Inst{11-0} = addr{11-0};
}
class LWM_FM_MM16<bits<4> funct> : MMArch {
class LWM_FM_MM16<bits<4> funct> : MMArch, PredicateControl {
bits<2> rt;
bits<4> addr;

View File

@ -660,6 +660,14 @@ def BREAK16_MM : BrkSdbbp16MM<"break16">, BRKSDBBP16_FM_MM<0x28>,
def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16">, BRKSDBBP16_FM_MM<0x2C>,
ISA_MICROMIPS_NOT_32R6_64R6;
let DecoderNamespace = "MicroMips" in {
/// Load and Store Instructions - multiple
def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>,
ISA_MICROMIPS32_NOT_MIPS32R6;
def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>,
ISA_MICROMIPS32_NOT_MIPS32R6;
}
class WaitMM<string opstr> :
InstSE<(outs), (ins uimm10:$code_), !strconcat(opstr, "\t$code_"), [],
NoItinerary, FrmOther, opstr>;
@ -790,8 +798,6 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
/// Load and Store Instructions - multiple
def SWM32_MM : StoreMultMM<"swm32">, LWM_FM_MM<0xd>;
def LWM32_MM : LoadMultMM<"lwm32">, LWM_FM_MM<0x5>;
def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>;
def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>;
/// Load and Store Pair Instructions
def SWP_MM : StorePairMM<"swp">, LWM_FM_MM<0x9>;

View File

@ -230,3 +230,10 @@
0x00 0x69 0xe1 0x7c # CHECK: rdpgpr $3, $9
0x00 0x00 0xdb 0x7c # CHECK: sdbbp
0x00 0x22 0xdb 0x7c # CHECK: sdbbp 34
0x45 0x22 # CHECK: lwm16 $16, $17, $ra, 8($sp)
0x89 0x84 # CHECK: sb16 $3, 4($16)
0xaa 0x14 # CHECK: sh16 $4, 8($17)
0xc8 0x9f # CHECK: sw $4, 124($sp)
0xea 0x11 # CHECK: sw16 $4, 4($17)
0xe8 0x11 # CHECK: sw16 $zero, 4($17)
0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp)

View File

@ -143,3 +143,10 @@
0x46 0x3b # CHECK: sdbbp16 8
0x04 0x3b # CHECK: subu16 $5, $16, $3
0x44 0xd8 # CHECK: xor16 $17, $5
0x45 0x22 # CHECK: lwm16 $16, $17, $ra, 8($sp)
0x89 0x84 # CHECK: sb16 $3, 4($16)
0xaa 0x14 # CHECK: sh16 $4, 8($17)
0xc8 0x9f # CHECK: sw $4, 124($sp)
0xea 0x11 # CHECK: sw16 $4, 4($17)
0xe8 0x11 # CHECK: sw16 $zero, 4($17)
0x45 0x2a # CHECK: swm16 $16, $17, $ra, 8($sp)

View File

@ -73,3 +73,31 @@
jrcaddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
jrcaddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
jrcaddiusp 132 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
lwm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
lwm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
lwm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sb16 $16, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $7, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $4, 68($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sh16 $16, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $7, 8($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $9, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $4, 64($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sw16 $16, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $7, 4($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
swm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
swm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
swm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction

View File

@ -54,6 +54,8 @@
jrcaddiusp 20 # CHECK: jrcaddiusp 20 # encoding: [0x44,0xb3]
lsa $2, $3, $4, 3 # CHECK: lsa $2, $3, $4, 3 # encoding: [0x00,0x43,0x24,0x0f]
lwpc $2,268 # CHECK: lwpc $2, 268 # encoding: [0x78,0x48,0x00,0x43]
lwm $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22]
lwm16 $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22]
mod $3, $4, $5 # CHECK: mod $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x58]
modu $3, $4, $5 # CHECK: modu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd8]
mul $3, $4, $5 # CHECK mul $3, $4, $5 # encoding: [0x00,0xa4,0x18,0x18]
@ -65,13 +67,20 @@
or $3, $4, $5 # CHECK: or $3, $4, $5 # encoding: [0x00,0xa4,0x1a,0x90]
ori $3, $4, 1234 # CHECK: ori $3, $4, 1234 # encoding: [0x50,0x64,0x04,0xd2]
pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x60,0x25,0x20,0x08]
sb16 $3, 4($16) # CHECK: sb16 $3, 4($16) # encoding: [0x89,0x84]
seb $3, $4 # CHECK: seb $3, $4 # encoding: [0x00,0x64,0x2b,0x3c]
seh $3, $4 # CHECK: seh $3, $4 # encoding: [0x00,0x64,0x3b,0x3c]
seleqz $2,$3,$4 # CHECK: seleqz $2, $3, $4 # encoding: [0x00,0x83,0x11,0x40]
selnez $2,$3,$4 # CHECK: selnez $2, $3, $4 # encoding: [0x00,0x83,0x11,0x80]
sh16 $4, 8($17) # CHECK: sh16 $4, 8($17) # encoding: [0xaa,0x14]
sll $4, $3, 7 # CHECK: sll $4, $3, 7 # encoding: [0x00,0x83,0x38,0x00]
sub $3, $4, $5 # CHECK: sub $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x90]
subu $3, $4, $5 # CHECK: subu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd0]
sw $4, 124($sp) # CHECK: sw $4, 124($sp) # encoding: [0xc8,0x9f]
sw16 $4, 4($17) # CHECK: sw16 $4, 4($17) # encoding: [0xea,0x11]
sw16 $0, 4($17) # CHECK: sw16 $zero, 4($17) # encoding: [0xe8,0x11]
swm $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a]
swm16 $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a]
wrpgpr $3, $4 # CHECK: wrpgpr $3, $4 # encoding: [0x00,0x64,0xf1,0x7c]
wsbh $3, $4 # CHECK: wsbh $3, $4 # encoding: [0x00,0x64,0x7b,0x3c]
pause # CHECK: pause # encoding: [0x00,0x00,0x28,0x00]

View File

@ -81,3 +81,31 @@
jrcaddiusp 33 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
jrcaddiusp 125 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
jrcaddiusp 132 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
lwm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
lwm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
lwm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lwm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $3, 64($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sb16 $16, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sb16 $7, 4($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $4, 68($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sh16 $16, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sh16 $7, 8($9) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $9, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $4, 64($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
sw16 $16, 4($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
sw16 $7, 4($10) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $5, $6, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected
swm16 $16, $19, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected
swm16 $16-$25, $ra, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand
swm16 $16, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16-$20, 8($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, $ra, 8($fp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
swm16 $16, $17, $ra, 64($sp) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction

View File

@ -121,5 +121,14 @@ a:
sdbbp16 8 # CHECK: sdbbp16 8 # encoding: [0x46,0x3b]
subu16 $5, $16, $3 # CHECK: subu16 $5, $16, $3 # encoding: [0x04,0x3b]
xor16 $17, $5 # CHECK: xor16 $17, $5 # encoding: [0x44,0xd8]
lwm $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22]
lwm16 $16, $17, $ra, 8($sp) # CHECK: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x22]
sb16 $3, 4($16) # CHECK: sb16 $3, 4($16) # encoding: [0x89,0x84]
sh16 $4, 8($17) # CHECK: sh16 $4, 8($17) # encoding: [0xaa,0x14]
sw $4, 124($sp) # CHECK: sw $4, 124($sp) # encoding: [0xc8,0x9f]
sw16 $4, 4($17) # CHECK: sw16 $4, 4($17) # encoding: [0xea,0x11]
sw16 $0, 4($17) # CHECK: sw16 $zero, 4($17) # encoding: [0xe8,0x11]
swm $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a]
swm16 $16, $17, $ra, 8($sp) # CHECK: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x2a]
1: