Match_NonZeroOperandForSync,
Match_RequiresPosSizeRange0_32,
Match_RequiresPosSizeRange33_64,
+ Match_RequiresPosSizeUImm6,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "MipsGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
return Match_RequiresDifferentOperands;
return Match_Success;
- case Mips::DINS:
- case Mips::DINS_MM64R6: {
- assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
- "Operands must be immediates for dins!");
- const signed Pos = Inst.getOperand(2).getImm();
- const signed Size = Inst.getOperand(3).getImm();
- if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
- return Match_RequiresPosSizeRange0_32;
- return Match_Success;
- }
- case Mips::DINSM:
- case Mips::DINSM_MM64R6:
- case Mips::DINSU:
- case Mips::DINSU_MM64R6: {
- assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
- "Operands must be immediates for dinsm/dinsu!");
- const signed Pos = Inst.getOperand(2).getImm();
- const signed Size = Inst.getOperand(3).getImm();
- if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
- return Match_RequiresPosSizeRange33_64;
- return Match_Success;
- }
+ case Mips::DINS:
+ case Mips::DINS_MM64R6: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dins!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
+ return Match_RequiresPosSizeRange0_32;
+ return Match_Success;
+ }
+ case Mips::DINSM:
+ case Mips::DINSM_MM64R6:
+ case Mips::DINSU:
+ case Mips::DINSU_MM64R6: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dinsm/dinsu!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
+ return Match_RequiresPosSizeRange33_64;
+ return Match_Success;
+ }
+ case Mips::DEXT:
+ case Mips::DEXT_MM64R6: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for DEXTM!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
+ return Match_RequiresPosSizeUImm6;
+ return Match_Success;
+ }
+ case Mips::DEXTM:
+ case Mips::DEXTU:
+ case Mips::DEXTM_MM64R6:
+ case Mips::DEXTU_MM64R6: {
+ assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
+ "Operands must be immediates for dextm/dextu!");
+ const signed Pos = Inst.getOperand(2).getImm();
+ const signed Size = Inst.getOperand(3).getImm();
+ if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
+ return Match_RequiresPosSizeRange33_64;
+ return Match_Success;
+ }
}
uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
SMRange(ErrorStart, ErrorEnd));
}
+ case Match_RequiresPosSizeUImm6: {
+ SMLoc ErrorStart = Operands[3]->getStartLoc();
+ SMLoc ErrorEnd = Operands[4]->getEndLoc();
+ return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
+ SMRange(ErrorStart, ErrorEnd));
+ }
case Match_RequiresPosSizeRange33_64: {
SMLoc ErrorStart = Operands[3]->getStartLoc();
SMLoc ErrorEnd = Operands[4]->getEndLoc();
static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
const void *Decoder);
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder);
+
static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder);
return MCDisassembler::Success;
}
+// Override the generated disassembler to produce DEXT all the time. This is
+// for feature / behaviour parity with binutils.
+template <typename InsnType>
+static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
+ const void *Decoder) {
+ unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
+ unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
+ unsigned Size = 0;
+ unsigned Pos = 0;
+ bool IsMicroMips = false;
+
+ switch (MI.getOpcode()) {
+ case Mips::DEXT_MM64R6:
+ IsMicroMips = true;
+ LLVM_FALLTHROUGH;
+ case Mips::DEXT:
+ Pos = Lsb;
+ Size = Msbd + 1;
+ break;
+ case Mips::DEXTM_MM64R6:
+ IsMicroMips = true;
+ LLVM_FALLTHROUGH;
+ case Mips::DEXTM:
+ Pos = Lsb;
+ Size = Msbd + 1 + 32;
+ break;
+ case Mips::DEXTU_MM64R6:
+ IsMicroMips = true;
+ LLVM_FALLTHROUGH;
+ case Mips::DEXTU:
+ Pos = Lsb + 32;
+ Size = Msbd + 1;
+ break;
+ default:
+ llvm_unreachable("Unknown DEXT instruction!");
+ }
+
+ MI.setOpcode(IsMicroMips ? Mips::DEXT_MM64R6 : Mips::DEXT);
+
+ // Although the format of the instruction is similar, rs and rt are swapped
+ // for microMIPS64R6.
+ InsnType Rs = fieldFromInstruction(Insn, 21, 5);
+ InsnType Rt = fieldFromInstruction(Insn, 16, 5);
+ if (IsMicroMips)
+ std::swap(Rs, Rt);
+
+ MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
+ MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
+ MI.addOperand(MCOperand::createImm(Pos));
+ MI.addOperand(MCOperand::createImm(Size));
+
+ return MCDisassembler::Success;
+}
+
// Override the generated disassembler to produce DINS all the time. This is
// for feature / behaviour parity with binutils.
template <typename InsnType>
Format Form = FrmR;
string BaseOpcode = instr_asm;
}
-// TODO: Add 'pos + size' constraint check to dext* instructions
-// DEXT: 0 < pos + size <= 63
-// DEXTM, DEXTU: 32 < pos + size <= 64
class DEXT_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR64Opnd, uimm5_report_uimm6,
- uimm5_plus1, MipsExt>;
+ uimm5_plus1_report_uimm6, MipsExt>;
class DEXTM_MMR6_DESC : EXTBITS_DESC_BASE<"dextm", GPR64Opnd, uimm5,
uimm5_plus33, MipsExt>;
class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm5_plus32,
def DAHI_MM64R6 : StdMMR6Rel, DAHI_MMR6_DESC, DAHI_MMR6_ENC, ISA_MICROMIPS64R6;
def DATI_MM64R6 : StdMMR6Rel, DATI_MMR6_DESC, DATI_MMR6_ENC, ISA_MICROMIPS64R6;
}
- def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
- ISA_MICROMIPS64R6;
- def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
- ISA_MICROMIPS64R6;
+ let DecoderMethod = "DecodeDEXT" in {
+ def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
+ ISA_MICROMIPS64R6;
+ def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
+ ISA_MICROMIPS64R6;
+ def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
+ ISA_MICROMIPS64R6;
+ }
def DALIGN_MM64R6 : StdMMR6Rel, DALIGN_MMR6_DESC, DALIGN_MMR6_ENC,
ISA_MICROMIPS64R6;
def DDIV_MM64R6 : R6MMR6Rel, DDIV_MM64R6_DESC, DDIV_MM64R6_ENC,
(DINSU_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs,
uimm5_plus32:$pos, uimm5_plus1:$size), 0>,
ISA_MICROMIPS64R6;
+def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTM_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+ uimm5_plus33:$size), 0>,
+ ISA_MICROMIPS64R6;
+def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTU_MM64R6 GPR64Opnd:$rt, GPR64Opnd:$rs,
+ uimm5_plus32:$pos, uimm5_plus1:$size), 0>,
+ ISA_MICROMIPS64R6;
+
def RDHWR64 : ReadHardware<GPR64Opnd, HWRegsOpnd>, RDHWR_FM;
let AdditionalPredicates = [NotInMicroMips] in {
- // The 'pos + size' constraints are enforced by the code that lowers into
- // MipsISD::Ext.
- def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6, uimm5_plus1,
- immZExt5, immZExt5Plus1, MipsExt>, EXT_FM<3>,
- ISA_MIPS64R2;
- def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
- immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
- def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
- immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
- ISA_MIPS64R2;
+ // The 'pos + size' constraints for code generation are enforced by the
+ // code that lowers into MipsISD::Ext.
+ // For assembly parsing, we alias dextu and dextm to dext, and match by
+ // operand were possible then check the 'pos + size' in MipsAsmParser.
+ // We override the generated decoder to enforce that dext always comes out
+ // for dextm and dextu like binutils.
+ let DecoderMethod = "DecodeDEXT" in {
+ def DEXT : ExtBase<"dext", GPR64Opnd, uimm5_report_uimm6,
+ uimm5_plus1_report_uimm6, immZExt5, immZExt5Plus1,
+ MipsExt>, EXT_FM<3>, ISA_MIPS64R2;
+ def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5, uimm5_plus33, immZExt5,
+ immZExt5Plus33, MipsExt>, EXT_FM<1>, ISA_MIPS64R2;
+ def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm5_plus32, uimm5_plus1,
+ immZExt5Plus32, immZExt5Plus1, MipsExt>, EXT_FM<2>,
+ ISA_MIPS64R2;
+ }
// The 'pos + size' constraints for code generation are enforced by the
// code that lowers into MipsISD::Ins.
// For assembly parsing, we alias dinsu and dinsm to dins, and match by
def : MipsInstAlias<"dins $rt, $rs, $pos, $size",
(DINSU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
uimm5_plus1:$size), 0>, ISA_MIPS64R2;
+ def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTM GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5:$pos,
+ uimm5_plus33:$size), 0>, ISA_MIPS64R2;
+ def : MipsInstAlias<"dext $rt, $rs, $pos, $size",
+ (DEXTU GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32:$pos,
+ uimm5_plus1:$size), 0>, ISA_MIPS64R2;
// Two operand (implicit 0 selector) versions:
def : MipsInstAlias<"dmtc0 $rt, $rd",
// We must also subtract 32 when we render the operand.
let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
}
+def ConstantUImm5Plus1ReportUImm6AsmOperandClass
+ : ConstantUImmAsmOperandClass<
+ 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
+ let Name = "ConstantUImm5_Plus1_Report_UImm6";
+}
def ConstantUImm5Plus1AsmOperandClass
: ConstantUImmAsmOperandClass<
- 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
+ 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
def ConstantUImm5AsmOperandClass
: ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
def ConstantSImm5AsmOperandClass
let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
}
+def uimm5_plus1_report_uimm6 : Operand<i32> {
+ let PrintMethod = "printUImm<6, 1>";
+ let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
+ let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
+ let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
+}
+
def uimm5_plus32 : Operand<i32> {
let PrintMethod = "printUImm<5, 32>";
let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
0x42 0x23 0x00 0x04 # CHECK: dahi $3, $3, 4
0x42 0x03 0x00 0x04 # CHECK: dati $3, $3, 4
0x59 0x26 0x30 0xec # CHECK: dext $9, $6, 3, 7
-0x59 0x26 0x30 0xe4 # CHECK: dextm $9, $6, 3, 39
-0x59 0x26 0x30 0xd4 # CHECK: dextu $9, $6, 35, 7
+0x59 0x26 0x30 0xe4 # CHECK: dext $9, $6, 3, 39
+0x59 0x26 0x30 0xd4 # CHECK: dext $9, $6, 35, 7
0x58 0x43 0x25 0x1c # CHECK: dalign $4, $2, $3, 5
0x58 0xa4 0x19 0x18 # CHECK: ddiv $3, $4, $5
0x58 0xa4 0x19 0x58 # CHECK: dmod $3, $4, $5
daui $4, $4, -1 # CHECK: :[[@LINE]]:19: error: expected 16-bit unsigned immediate
dati $4, $4, -1 # CHECK: :[[@LINE]]:19: error: expected 16-bit unsigned immediate
dati $4, $5, 1 # CHECK: :[[@LINE]]:3: error: source and destination must match
- # FIXME: Check various 'pos + size' constraints on dext*
dext $2, $3, -1, 1 # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate
dext $2, $3, 64, 1 # CHECK: :[[@LINE]]:16: error: expected 6-bit unsigned immediate
dext $2, $3, 1, 0 # CHECK: :[[@LINE]]:19: error: expected immediate in range 1 .. 32
- dext $2, $3, 1, 33 # CHECK: :[[@LINE]]:19: error: expected immediate in range 1 .. 32
dextm $2, $3, -1, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
dextm $2, $3, 32, 1 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
dextm $2, $3, -1, 33 # CHECK: :[[@LINE]]:17: error: expected 5-bit unsigned immediate
# RUN: %s -o - | FileCheck --check-prefix=ASM %s
dext $2, $4, 5, 10 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
- dextu $2, $4, 34, 6 # OBJ: dextu ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
- dextm $2, $4, 5, 34 # OBJ: dextm ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
+ dextu $2, $4, 34, 6 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
+ dextm $2, $4, 5, 34 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
dins $4, $5, 8, 10 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 8, 10
dinsm $4, $5, 30, 6 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 30, 6
dinsu $4, $5, 40, 13 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 40, 13
dins $2, $4, 5, 10 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
dins $2, $4, 34, 6 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
dins $2, $4, 5, 34 # OBJ: dins ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
+ dext $2, $4, 5, 10 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
+ dext $2, $4, 34, 6 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 34, 6
+ dext $2, $4, 5, 34 # OBJ: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 34
# check the edge values
- dins $3, $4, 31, 1 # ASM: dins $3, $4, 31, 1
+ dins $3, $4, 31, 1 # ASM: dins $3, $4, 31, 1
dins $3, $4, 31, 33 # ASM: dinsm $3, $4, 31, 33
dins $3, $4, 32, 32 # ASM: dinsu $3, $4, 32, 32
+ dext $3, $4, 31, 32 # ASM: dext $3, $4, 31, 32
+ dext $3, $4, 31, 33 # ASM: dextm $3, $4, 31, 33
+ dext $3, $4, 32, 32 # ASM: dextu $3, $4, 32, 32
+
andi $2, $3, 65536 # CHECK: :[[@LINE]]:22: error: expected 16-bit unsigned immediate
cache -1, 255($7) # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate
cache 32, 255($7) # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate
- # FIXME: Check various 'pos + size' constraints on dext*
dext $2, $3, -1, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
dext $2, $3, 64, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
dext $2, $3, 1, 0 # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 32
- dext $2, $3, 1, 33 # CHECK: :[[@LINE]]:25: error: expected immediate in range 1 .. 32
dextm $2, $3, -1, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
dextm $2, $3, 32, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
dextm $2, $3, -1, 33 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
dextm $2, $3, 32, 33 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
dextm $2, $3, 1, 32 # CHECK: :[[@LINE]]:26: error: expected immediate in range 33 .. 64
dextm $2, $3, 1, 65 # CHECK: :[[@LINE]]:26: error: expected immediate in range 33 .. 64
+ dextm $3, $4, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
dextu $2, $3, 31, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
dextu $2, $3, 64, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
dextu $2, $3, 32, 0 # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32
dextu $2, $3, 32, 33 # CHECK: :[[@LINE]]:27: error: expected immediate in range 1 .. 32
+ dextu $3, $4, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
# FIXME: Check size on dins*
dins $2, $3, -1, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
dins $2, $3, 64, 1 # CHECK: :[[@LINE]]:22: error: expected 6-bit unsigned immediate
dinsm $2, $3, -1, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
dinsm $2, $3, 32, 1 # CHECK: :[[@LINE]]:23: error: expected 5-bit unsigned immediate
+ dinsm $4, $5, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
dinsu $2, $3, 31, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
dinsu $2, $3, 64, 1 # CHECK: :[[@LINE]]:23: error: expected immediate in range 32 .. 63
+ dinsu $4, $5, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
drotr $2, $3, -1 # CHECK: :[[@LINE]]:23: error: expected 6-bit unsigned immediate
drotr $2, $3, 64 # CHECK: :[[@LINE]]:23: error: expected 6-bit unsigned immediate
drotr32 $2, $3, -1 # CHECK: :[[@LINE]]:25: error: expected 5-bit unsigned immediate
break 7, 1024 # CHECK: :[[@LINE]]:18: error: expected 10-bit unsigned immediate
break 1024, 1024 # CHECK: :[[@LINE]]:15: error: expected 10-bit unsigned immediate
dati $2, $3, 1 # CHECK: :[[@LINE]]:9: error: source and destination must match
+ dextm $3, $4, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+ dextu $3, $4, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+ dinsm $4, $5, 31, 34 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
+ dinsu $4, $5, 33, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: size plus position are not in the range 33 .. 64
lh $33, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lhe $34, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
lhu $35, 8($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction