diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -123,11 +123,17 @@ #include "RISCVGenAsmMatcher.inc" OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); + OperandMatchResultTy parseImmediateOp(std::unique_ptr &Res); OperandMatchResultTy parseImmediate(OperandVector &Operands); OperandMatchResultTy parseRegister(OperandVector &Operands, - bool AllowParens = false); - OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); + bool AllowParens = false, + bool PushParens = true); + OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands, + bool PushParens = true); + OperandMatchResultTy + parseOperandWithModifierOp(std::unique_ptr &Res); OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); + OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); OperandMatchResultTy parseBareSymbol(OperandVector &Operands); OperandMatchResultTy parseCallSymbol(OperandVector &Operands); OperandMatchResultTy parseJALOffset(OperandVector &Operands); @@ -575,6 +581,15 @@ bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } + bool isImmZero() const { + if (!isImm()) + return false; + int64_t Imm; + RISCVMCExpr::VariantKind VK; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; + } + /// getStartLoc - Gets location of the first token of this operand SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Gets location of the last token of this operand @@ -994,7 +1009,8 @@ } OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, - bool AllowParens) { + bool AllowParens, + bool PushParens) { SMLoc FirstS = getLoc(); bool HadParens = false; AsmToken LParen; @@ -1026,7 +1042,7 @@ getLexer().UnLex(LParen); return MatchOperand_NoMatch; } - if (HadParens) + if (HadParens && PushParens) Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); @@ -1035,8 +1051,10 @@ } if (HadParens) { + SMLoc S = getLoc(); getParser().Lex(); // Eat ')' - Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); + if (PushParens) + Operands.push_back(RISCVOperand::createToken(")", S, isRV64())); } return MatchOperand_Success; @@ -1110,10 +1128,12 @@ return MatchOperand_NoMatch; } -OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { + +OperandMatchResultTy +RISCVAsmParser::parseImmediateOp(std::unique_ptr &Res) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); - const MCExpr *Res; + const MCExpr *Expr; switch (getLexer().getKind()) { default: @@ -1127,19 +1147,29 @@ case AsmToken::Integer: case AsmToken::String: case AsmToken::Identifier: - if (getParser().parseExpression(Res)) + if (getParser().parseExpression(Expr)) return MatchOperand_ParseFail; break; case AsmToken::Percent: - return parseOperandWithModifier(Operands); + return parseOperandWithModifierOp(Res); } - Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); + Res = RISCVOperand::createImm(Expr, S, E, isRV64()); return MatchOperand_Success; } +OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { + std::unique_ptr Res; + + OperandMatchResultTy Result = parseImmediateOp(Res); + if (Result == MatchOperand_Success) + Operands.push_back(std::move(Res)); + + return Result; +} + OperandMatchResultTy -RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { +RISCVAsmParser::parseOperandWithModifierOp(std::unique_ptr &Res) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); @@ -1174,10 +1204,21 @@ } const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); - Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); + Res = RISCVOperand::createImm(ModExpr, S, E, isRV64()); return MatchOperand_Success; } +OperandMatchResultTy +RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { + std::unique_ptr Res; + + OperandMatchResultTy Result = parseOperandWithModifierOp(Res); + if (Result == MatchOperand_Success) + Operands.push_back(std::move(Res)); + + return Result; +} + OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); @@ -1257,14 +1298,16 @@ } OperandMatchResultTy -RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { +RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands, bool PushParens) { if (getLexer().isNot(AsmToken::LParen)) { Error(getLoc(), "expected '('"); return MatchOperand_ParseFail; } + SMLoc LParenLoc = getLoc(); getParser().Lex(); // Eat '(' - Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); + if (PushParens) + Operands.push_back(RISCVOperand::createToken("(", LParenLoc, isRV64())); if (parseRegister(Operands) != MatchOperand_Success) { Error(getLoc(), "expected register"); @@ -1276,12 +1319,37 @@ return MatchOperand_ParseFail; } + SMLoc RParenLoc = getLoc(); getParser().Lex(); // Eat ')' - Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); + if (PushParens) + Operands.push_back(RISCVOperand::createToken(")", RParenLoc, isRV64())); return MatchOperand_Success; } +OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { + // Attempt to parse token as a register. Atomic memory operands are special + // and must have parentheses. + if (getLexer().is(AsmToken::LParen)) + if (parseRegister(Operands, true, false) == MatchOperand_Success) + return MatchOperand_Success; + + // Attempt to parse token as an immediate + std::unique_ptr Imm; + if (parseImmediateOp(Imm) == MatchOperand_Success) { + if (!Imm->isImmZero()) { + Error(Imm->getStartLoc(), "optional integer offset must be 0"); + return MatchOperand_ParseFail; + } + // Attempt to parse memory base register, stripping parens + return parseMemOpBaseReg(Operands, false); + } + + // Finally we have exhausted all options and must declare defeat. + Error(getLoc(), "unknown operand"); + return MatchOperand_ParseFail; +} + /// Looks at a token type and creates the relevant operand from this /// information, adding to Operands. If operand was parsed, returns false, else /// true. diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -37,6 +37,8 @@ const MCSubtargetInfo &STI, raw_ostream &O); void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printAtomicMemOp(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); // Autogenerated by tblgen. void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -112,3 +112,15 @@ static_cast(MI->getOperand(OpNo).getImm()); O << RISCVFPRndMode::roundingModeToString(FRMArg); } + +void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + assert(MO.isReg() && "printAtomicMemOp can only print register operands"); + O << "("; + printRegName(O, MO.getReg()); + O << ")"; + return; +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td @@ -11,6 +11,25 @@ // //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored. +// Used for GNU as compatibility, and to allow us to always print inline +// assembly memory operands as 0(${gpr}), matching GCC. +def AtomicMemOpOperand : AsmOperandClass { + let Name = "AtomicMemOpOperand"; + let RenderMethod = "addRegOperands"; + let PredicateMethod = "isReg"; + let ParserMethod = "parseAtomicMemOp"; +} + +def GPRMemAtomic : RegisterOperand { + let ParserMatchClass = AtomicMemOpOperand; + let PrintMethod = "printAtomicMemOp"; +} + //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// @@ -18,8 +37,8 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in class LR_r funct3, string opcodestr> : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, - (outs GPR:$rd), (ins GPR:$rs1), - opcodestr, "$rd, (${rs1})"> { + (outs GPR:$rd), (ins GPRMemAtomic:$rs1), + opcodestr, "$rd, $rs1"> { let rs2 = 0; } @@ -33,8 +52,8 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in class AMO_rr funct5, bit aq, bit rl, bits<3> funct3, string opcodestr> : RVInstRAtomic; + (outs GPR:$rd), (ins GPRMemAtomic:$rs1, GPR:$rs2), + opcodestr, "$rd, $rs2, $rs1">; multiclass AMO_rr_aq_rl funct5, bits<3> funct3, string opcodestr> { def "" : AMO_rr; diff --git a/llvm/test/MC/RISCV/rv32a-invalid.s b/llvm/test/MC/RISCV/rv32a-invalid.s --- a/llvm/test/MC/RISCV/rv32a-invalid.s +++ b/llvm/test/MC/RISCV/rv32a-invalid.s @@ -1,9 +1,10 @@ # RUN: not llvm-mc -triple riscv32 -mattr=+a < %s 2>&1 | FileCheck %s # Final operand must have parentheses -amoswap.w a1, a2, a3 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction -amomin.w a1, a2, 1 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction -lr.w a4, a5 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction +amoswap.w a1, a2, a3 # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomin.w a1, a2, 1 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomin.w a1, a2, 1(a3) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +lr.w a4, a5 # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 # Only .aq, .rl, and .aqrl suffixes are valid amoxor.w.rlqa a2, a3, (a4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic diff --git a/llvm/test/MC/RISCV/rv64a-aliases-valid.s b/llvm/test/MC/RISCV/rv64a-aliases-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64a-aliases-valid.s @@ -0,0 +1,189 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a -riscv-no-aliases \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a -riscv-no-aliases - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a - \ +# RUN: | FileCheck -check-prefix=CHECK-ALIAS %s + +# The below tests for lr.d, sc.d and amo*.d, using `0(reg)` are actually +# implemented using a custom parser, but we test them as if they're aliases. + +# CHECK-INST: lr.d a1, (a0) +# CHECK-ALIAS: lr.d a1, (a0) +lr.d a1, 0(a0) + +# CHECK-INST: lr.d.aq a1, (a0) +# CHECK-ALIAS: lr.d.aq a1, (a0) +lr.d.aq a1, 0(a0) + +# CHECK-INST: lr.d.rl a1, (a0) +# CHECK-ALIAS: lr.d.rl a1, (a0) +lr.d.rl a1, 0(a0) + +# CHECK-INST: lr.d.aqrl a1, (a0) +# CHECK-ALIAS: lr.d.aqrl a1, (a0) +lr.d.aqrl a1, 0(a0) + +# CHECK-INST: sc.d a2, a1, (a0) +# CHECK-ALIAS: sc.d a2, a1, (a0) +sc.d a2, a1, 0(a0) + +# CHECK-INST: sc.d.aq a2, a1, (a0) +# CHECK-ALIAS: sc.d.aq a2, a1, (a0) +sc.d.aq a2, a1, 0(a0) + +# CHECK-INST: sc.d.rl a2, a1, (a0) +# CHECK-ALIAS: sc.d.rl a2, a1, (a0) +sc.d.rl a2, a1, 0(a0) + +# CHECK-INST: sc.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: sc.d.aqrl a2, a1, (a0) +sc.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amoswap.d a2, a1, (a0) +# CHECK-ALIAS: amoswap.d a2, a1, (a0) +amoswap.d a2, a1, 0(a0) + +# CHECK-INST: amoswap.d.aq a2, a1, (a0) +# CHECK-ALIAS: amoswap.d.aq a2, a1, (a0) +amoswap.d.aq a2, a1, 0(a0) + +# CHECK-INST: amoswap.d.rl a2, a1, (a0) +# CHECK-ALIAS: amoswap.d.rl a2, a1, (a0) +amoswap.d.rl a2, a1, 0(a0) + +# CHECK-INST: amoswap.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amoswap.d.aqrl a2, a1, (a0) +amoswap.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amoadd.d a2, a1, (a0) +# CHECK-ALIAS: amoadd.d a2, a1, (a0) +amoadd.d a2, a1, 0(a0) + +# CHECK-INST: amoadd.d.aq a2, a1, (a0) +# CHECK-ALIAS: amoadd.d.aq a2, a1, (a0) +amoadd.d.aq a2, a1, 0(a0) + +# CHECK-INST: amoadd.d.rl a2, a1, (a0) +# CHECK-ALIAS: amoadd.d.rl a2, a1, (a0) +amoadd.d.rl a2, a1, 0(a0) + +# CHECK-INST: amoadd.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amoadd.d.aqrl a2, a1, (a0) +amoadd.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amoxor.d a2, a1, (a0) +# CHECK-ALIAS: amoxor.d a2, a1, (a0) +amoxor.d a2, a1, 0(a0) + +# CHECK-INST: amoxor.d.aq a2, a1, (a0) +# CHECK-ALIAS: amoxor.d.aq a2, a1, (a0) +amoxor.d.aq a2, a1, 0(a0) + +# CHECK-INST: amoxor.d.rl a2, a1, (a0) +# CHECK-ALIAS: amoxor.d.rl a2, a1, (a0) +amoxor.d.rl a2, a1, 0(a0) + +# CHECK-INST: amoxor.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amoxor.d.aqrl a2, a1, (a0) +amoxor.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amoand.d a2, a1, (a0) +# CHECK-ALIAS: amoand.d a2, a1, (a0) +amoand.d a2, a1, 0(a0) + +# CHECK-INST: amoand.d.aq a2, a1, (a0) +# CHECK-ALIAS: amoand.d.aq a2, a1, (a0) +amoand.d.aq a2, a1, 0(a0) + +# CHECK-INST: amoand.d.rl a2, a1, (a0) +# CHECK-ALIAS: amoand.d.rl a2, a1, (a0) +amoand.d.rl a2, a1, 0(a0) + +# CHECK-INST: amoand.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amoand.d.aqrl a2, a1, (a0) +amoand.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amoor.d a2, a1, (a0) +# CHECK-ALIAS: amoor.d a2, a1, (a0) +amoor.d a2, a1, 0(a0) + +# CHECK-INST: amoor.d.aq a2, a1, (a0) +# CHECK-ALIAS: amoor.d.aq a2, a1, (a0) +amoor.d.aq a2, a1, 0(a0) + +# CHECK-INST: amoor.d.rl a2, a1, (a0) +# CHECK-ALIAS: amoor.d.rl a2, a1, (a0) +amoor.d.rl a2, a1, 0(a0) + +# CHECK-INST: amoor.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amoor.d.aqrl a2, a1, (a0) +amoor.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amomin.d a2, a1, (a0) +# CHECK-ALIAS: amomin.d a2, a1, (a0) +amomin.d a2, a1, 0(a0) + +# CHECK-INST: amomin.d.aq a2, a1, (a0) +# CHECK-ALIAS: amomin.d.aq a2, a1, (a0) +amomin.d.aq a2, a1, 0(a0) + +# CHECK-INST: amomin.d.rl a2, a1, (a0) +# CHECK-ALIAS: amomin.d.rl a2, a1, (a0) +amomin.d.rl a2, a1, 0(a0) + +# CHECK-INST: amomin.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amomin.d.aqrl a2, a1, (a0) +amomin.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amomax.d a2, a1, (a0) +# CHECK-ALIAS: amomax.d a2, a1, (a0) +amomax.d a2, a1, 0(a0) + +# CHECK-INST: amomax.d.aq a2, a1, (a0) +# CHECK-ALIAS: amomax.d.aq a2, a1, (a0) +amomax.d.aq a2, a1, 0(a0) + +# CHECK-INST: amomax.d.rl a2, a1, (a0) +# CHECK-ALIAS: amomax.d.rl a2, a1, (a0) +amomax.d.rl a2, a1, 0(a0) + +# CHECK-INST: amomax.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amomax.d.aqrl a2, a1, (a0) +amomax.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amominu.d a2, a1, (a0) +# CHECK-ALIAS: amominu.d a2, a1, (a0) +amominu.d a2, a1, 0(a0) + +# CHECK-INST: amominu.d.aq a2, a1, (a0) +# CHECK-ALIAS: amominu.d.aq a2, a1, (a0) +amominu.d.aq a2, a1, 0(a0) + +# CHECK-INST: amominu.d.rl a2, a1, (a0) +# CHECK-ALIAS: amominu.d.rl a2, a1, (a0) +amominu.d.rl a2, a1, 0(a0) + +# CHECK-INST: amominu.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amominu.d.aqrl a2, a1, (a0) +amominu.d.aqrl a2, a1, 0(a0) + +# CHECK-INST: amomaxu.d a2, a1, (a0) +# CHECK-ALIAS: amomaxu.d a2, a1, (a0) +amomaxu.d a2, a1, 0(a0) + +# CHECK-INST: amomaxu.d.aq a2, a1, (a0) +# CHECK-ALIAS: amomaxu.d.aq a2, a1, (a0) +amomaxu.d.aq a2, a1, 0(a0) + +# CHECK-INST: amomaxu.d.rl a2, a1, (a0) +# CHECK-ALIAS: amomaxu.d.rl a2, a1, (a0) +amomaxu.d.rl a2, a1, 0(a0) + +# CHECK-INST: amomaxu.d.aqrl a2, a1, (a0) +# CHECK-ALIAS: amomaxu.d.aqrl a2, a1, (a0) +amomaxu.d.aqrl a2, a1, 0(a0) diff --git a/llvm/test/MC/RISCV/rv64a-invalid.s b/llvm/test/MC/RISCV/rv64a-invalid.s --- a/llvm/test/MC/RISCV/rv64a-invalid.s +++ b/llvm/test/MC/RISCV/rv64a-invalid.s @@ -1,9 +1,10 @@ # RUN: not llvm-mc -triple riscv64 -mattr=+a < %s 2>&1 | FileCheck %s # Final operand must have parentheses -amoswap.d a1, a2, a3 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction -amomin.d a1, a2, 1 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction -lr.d a4, a5 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction +amoswap.d a1, a2, a3 # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomin.d a1, a2, 1 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomin.d a1, a2, 1(a3) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +lr.d a4, a5 # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 # Only .aq, .rl, and .aqrl suffixes are valid amoxor.d.rlqa a2, a3, (a4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic diff --git a/llvm/test/MC/RISCV/rva-aliases-invalid.s b/llvm/test/MC/RISCV/rva-aliases-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rva-aliases-invalid.s @@ -0,0 +1,94 @@ +# RUN: not llvm-mc %s -triple=riscv32 -mattr=+a 2>&1 | FileCheck %s +# RUN: not llvm-mc %s -triple=riscv64 -mattr=+a 2>&1 | FileCheck %s + +# The below tests for lr(.w), sc(.w) and amo*(.w), using `0(reg)` are actually +# implemented using a custom parser. These tests ensure the custom parser gives +# good error messages. + +lr.w a1, a0 # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 +lr.w a1, foo # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 +lr.w a1, 1(a0) # CHECK: :[[@LINE]]:10: error: optional integer offset must be 0 +lr.w a1, (foo) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0 +lr.w a1, 0(foo) # CHECK: :[[@LINE]]:12: error: expected register +lr.w a1, 0(a0 # CHECK: :[[@LINE]]:17: error: expected ')' +lr.w a1, (a0 # CHECK: :[[@LINE]]:17: error: expected ')' in parentheses expression + +sc.w a2, a1, a0 # CHECK: :[[@LINE]]:14: error: optional integer offset must be 0 +sc.w a2, a1, foo # CHECK: :[[@LINE]]:14: error: optional integer offset must be 0 +sc.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:14: error: optional integer offset must be 0 +sc.w a2, a1, (foo) # CHECK: :[[@LINE]]:15: error: optional integer offset must be 0 +sc.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:16: error: expected register +sc.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:21: error: expected ')' +sc.w a2, a1, (a0 # CHECK: :[[@LINE]]:21: error: expected ')' in parentheses expression + +amoswap.w a2, a1, a0 # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoswap.w a2, a1, foo # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoswap.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoswap.w a2, a1, (foo) # CHECK: :[[@LINE]]:20: error: optional integer offset must be 0 +amoswap.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register +amoswap.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:26: error: expected ')' +amoswap.w a2, a1, (a0 # CHECK: :[[@LINE]]:26: error: expected ')' in parentheses expression + +amoadd.w a2, a1, a0 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoadd.w a2, a1, foo # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoadd.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoadd.w a2, a1, (foo) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoadd.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register +amoadd.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:25: error: expected ')' +amoadd.w a2, a1, (a0 # CHECK: :[[@LINE]]:25: error: expected ')' in parentheses expression + +amoxor.w a2, a1, a0 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoxor.w a2, a1, foo # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoxor.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoxor.w a2, a1, (foo) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoxor.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register +amoxor.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:25: error: expected ')' +amoxor.w a2, a1, (a0 # CHECK: :[[@LINE]]:25: error: expected ')' in parentheses expression + +amoand.w a2, a1, a0 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoand.w a2, a1, foo # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoand.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoand.w a2, a1, (foo) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amoand.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register +amoand.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:25: error: expected ')' +amoand.w a2, a1, (a0 # CHECK: :[[@LINE]]:25: error: expected ')' in parentheses expression + +amoor.w a2, a1, a0 # CHECK: :[[@LINE]]:17: error: optional integer offset must be 0 +amoor.w a2, a1, foo # CHECK: :[[@LINE]]:17: error: optional integer offset must be 0 +amoor.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:17: error: optional integer offset must be 0 +amoor.w a2, a1, (foo) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amoor.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:19: error: expected register +amoor.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:24: error: expected ')' +amoor.w a2, a1, (a0 # CHECK: :[[@LINE]]:24: error: expected ')' in parentheses expression + +amomin.w a2, a1, a0 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomin.w a2, a1, foo # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomin.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomin.w a2, a1, (foo) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomin.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register +amomin.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:25: error: expected ')' +amomin.w a2, a1, (a0 # CHECK: :[[@LINE]]:25: error: expected ')' in parentheses expression + +amomax.w a2, a1, a0 # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomax.w a2, a1, foo # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomax.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amomax.w a2, a1, (foo) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomax.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:20: error: expected register +amomax.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:25: error: expected ')' +amomax.w a2, a1, (a0 # CHECK: :[[@LINE]]:25: error: expected ')' in parentheses expression + +amominu.w a2, a1, a0 # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amominu.w a2, a1, foo # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amominu.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amominu.w a2, a1, (foo) # CHECK: :[[@LINE]]:20: error: optional integer offset must be 0 +amominu.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register +amominu.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:26: error: expected ')' +amominu.w a2, a1, (a0 # CHECK: :[[@LINE]]:26: error: expected ')' in parentheses expression + +amomaxu.w a2, a1, a0 # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomaxu.w a2, a1, foo # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomaxu.w a2, a1, 1(a0) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 +amomaxu.w a2, a1, (foo) # CHECK: :[[@LINE]]:20: error: optional integer offset must be 0 +amomaxu.w a2, a1, 0(foo) # CHECK: :[[@LINE]]:21: error: expected register +amomaxu.w a2, a1, 0(a0 # CHECK: :[[@LINE]]:26: error: expected ')' +amomaxu.w a2, a1, (a0 # CHECK: :[[@LINE]]:26: error: expected ')' in parentheses expression diff --git a/llvm/test/MC/RISCV/rva-aliases-valid.s b/llvm/test/MC/RISCV/rva-aliases-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rva-aliases-valid.s @@ -0,0 +1,297 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+a -riscv-no-aliases \ +# RUN: | FileCheck -check-prefixes=CHECK-S-NOALIAS,CHECK-S-OBJ-NOALIAS %s +# RUN: llvm-mc %s -triple=riscv32 -mattr=+a \ +# RUN: | FileCheck -check-prefixes=CHECK-S,CHECK-S-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a -riscv-no-aliases\ +# RUN: | FileCheck -check-prefixes=CHECK-S-NOALIAS,CHECK-S-OBJ-NOALIAS %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+a \ +# RUN: | FileCheck -check-prefixes=CHECK-S,CHECK-S-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a -riscv-no-aliases - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ-NOALIAS,CHECK-S-OBJ-NOALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-S-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a -riscv-no-aliases - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ-NOALIAS,CHECK-S-OBJ-NOALIAS %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+a < %s \ +# RUN: | llvm-objdump -d -mattr=+a - \ +# RUN: | FileCheck -check-prefixes=CHECK-OBJ,CHECK-S-OBJ %s + +# The following check prefixes are used in this test: +# CHECK-S Match the .s output with aliases enabled +# CHECK-S-NOALIAS Match the .s output with aliases disabled +# CHECK-OBJ Match the objdumped object output with aliases enabled +# CHECK-OBJ-NOALIAS Match the objdumped object output with aliases enabled +# CHECK-S-OBJ Match both the .s and objdumped object output with +# aliases enabled +# CHECK-S-OBJ-NOALIAS Match both the .s and objdumped object output with +# aliases disabled + +# The below tests for lr.w, sc.w and amo*.w, using `0(reg)` are actually +# implemented using a custom parser, but we test them as if they're aliases. + +# CHECK-S: lr.w a1, (a0) +# CHECK-S-NOALIAS: lr.w a1, (a0) +# CHECK-OBJ: lr.w a1, (a0) +# CHECK-OBJ-NOALIAS: lr.w a1, (a0) +lr.w a1, 0(a0) + +# CHECK-S: lr.w.aq a1, (a0) +# CHECK-S-NOALIAS: lr.w.aq a1, (a0) +# CHECK-OBJ: lr.w.aq a1, (a0) +# CHECK-OBJ-NOALIAS: lr.w.aq a1, (a0) +lr.w.aq a1, 0(a0) + +# CHECK-S: lr.w.rl a1, (a0) +# CHECK-S-NOALIAS: lr.w.rl a1, (a0) +# CHECK-OBJ: lr.w.rl a1, (a0) +# CHECK-OBJ-NOALIAS: lr.w.rl a1, (a0) +lr.w.rl a1, 0(a0) + +# CHECK-S: lr.w.aqrl a1, (a0) +# CHECK-S-NOALIAS: lr.w.aqrl a1, (a0) +# CHECK-OBJ: lr.w.aqrl a1, (a0) +# CHECK-OBJ-NOALIAS: lr.w.aqrl a1, (a0) +lr.w.aqrl a1, 0(a0) + +# CHECK-S: sc.w a2, a1, (a0) +# CHECK-S-NOALIAS: sc.w a2, a1, (a0) +# CHECK-OBJ: sc.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: sc.w a2, a1, (a0) +sc.w a2, a1, 0(a0) + +# CHECK-S: sc.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: sc.w.aq a2, a1, (a0) +# CHECK-OBJ: sc.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: sc.w.aq a2, a1, (a0) +sc.w.aq a2, a1, 0(a0) + +# CHECK-S: sc.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: sc.w.rl a2, a1, (a0) +# CHECK-OBJ: sc.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: sc.w.rl a2, a1, (a0) +sc.w.rl a2, a1, 0(a0) + +# CHECK-S: sc.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: sc.w.aqrl a2, a1, (a0) +# CHECK-OBJ: sc.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: sc.w.aqrl a2, a1, (a0) +sc.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amoswap.w a2, a1, (a0) +# CHECK-S-NOALIAS: amoswap.w a2, a1, (a0) +# CHECK-OBJ: amoswap.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoswap.w a2, a1, (a0) +amoswap.w a2, a1, 0(a0) + +# CHECK-S: amoswap.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amoswap.w.aq a2, a1, (a0) +# CHECK-OBJ: amoswap.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoswap.w.aq a2, a1, (a0) +amoswap.w.aq a2, a1, 0(a0) + +# CHECK-S: amoswap.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amoswap.w.rl a2, a1, (a0) +# CHECK-OBJ: amoswap.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoswap.w.rl a2, a1, (a0) +amoswap.w.rl a2, a1, 0(a0) + +# CHECK-S: amoswap.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amoswap.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amoswap.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoswap.w.aqrl a2, a1, (a0) +amoswap.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amoadd.w a2, a1, (a0) +# CHECK-S-NOALIAS: amoadd.w a2, a1, (a0) +# CHECK-OBJ: amoadd.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoadd.w a2, a1, (a0) +amoadd.w a2, a1, 0(a0) + +# CHECK-S: amoadd.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amoadd.w.aq a2, a1, (a0) +# CHECK-OBJ: amoadd.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoadd.w.aq a2, a1, (a0) +amoadd.w.aq a2, a1, 0(a0) + +# CHECK-S: amoadd.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amoadd.w.rl a2, a1, (a0) +# CHECK-OBJ: amoadd.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoadd.w.rl a2, a1, (a0) +amoadd.w.rl a2, a1, 0(a0) + +# CHECK-S: amoadd.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amoadd.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amoadd.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoadd.w.aqrl a2, a1, (a0) +amoadd.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amoxor.w a2, a1, (a0) +# CHECK-S-NOALIAS: amoxor.w a2, a1, (a0) +# CHECK-OBJ: amoxor.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoxor.w a2, a1, (a0) +amoxor.w a2, a1, 0(a0) + +# CHECK-S: amoxor.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amoxor.w.aq a2, a1, (a0) +# CHECK-OBJ: amoxor.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoxor.w.aq a2, a1, (a0) +amoxor.w.aq a2, a1, 0(a0) + +# CHECK-S: amoxor.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amoxor.w.rl a2, a1, (a0) +# CHECK-OBJ: amoxor.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoxor.w.rl a2, a1, (a0) +amoxor.w.rl a2, a1, 0(a0) + +# CHECK-S: amoxor.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amoxor.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amoxor.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoxor.w.aqrl a2, a1, (a0) +amoxor.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amoand.w a2, a1, (a0) +# CHECK-S-NOALIAS: amoand.w a2, a1, (a0) +# CHECK-OBJ: amoand.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoand.w a2, a1, (a0) +amoand.w a2, a1, 0(a0) + +# CHECK-S: amoand.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amoand.w.aq a2, a1, (a0) +# CHECK-OBJ: amoand.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoand.w.aq a2, a1, (a0) +amoand.w.aq a2, a1, 0(a0) + +# CHECK-S: amoand.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amoand.w.rl a2, a1, (a0) +# CHECK-OBJ: amoand.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoand.w.rl a2, a1, (a0) +amoand.w.rl a2, a1, 0(a0) + +# CHECK-S: amoand.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amoand.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amoand.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoand.w.aqrl a2, a1, (a0) +amoand.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amoor.w a2, a1, (a0) +# CHECK-S-NOALIAS: amoor.w a2, a1, (a0) +# CHECK-OBJ: amoor.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoor.w a2, a1, (a0) +amoor.w a2, a1, 0(a0) + +# CHECK-S: amoor.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amoor.w.aq a2, a1, (a0) +# CHECK-OBJ: amoor.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoor.w.aq a2, a1, (a0) +amoor.w.aq a2, a1, 0(a0) + +# CHECK-S: amoor.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amoor.w.rl a2, a1, (a0) +# CHECK-OBJ: amoor.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoor.w.rl a2, a1, (a0) +amoor.w.rl a2, a1, 0(a0) + +# CHECK-S: amoor.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amoor.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amoor.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amoor.w.aqrl a2, a1, (a0) +amoor.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amomin.w a2, a1, (a0) +# CHECK-S-NOALIAS: amomin.w a2, a1, (a0) +# CHECK-OBJ: amomin.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomin.w a2, a1, (a0) +amomin.w a2, a1, 0(a0) + +# CHECK-S: amomin.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amomin.w.aq a2, a1, (a0) +# CHECK-OBJ: amomin.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomin.w.aq a2, a1, (a0) +amomin.w.aq a2, a1, 0(a0) + +# CHECK-S: amomin.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amomin.w.rl a2, a1, (a0) +# CHECK-OBJ: amomin.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomin.w.rl a2, a1, (a0) +amomin.w.rl a2, a1, 0(a0) + +# CHECK-S: amomin.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amomin.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amomin.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomin.w.aqrl a2, a1, (a0) +amomin.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amomax.w a2, a1, (a0) +# CHECK-S-NOALIAS: amomax.w a2, a1, (a0) +# CHECK-OBJ: amomax.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomax.w a2, a1, (a0) +amomax.w a2, a1, 0(a0) + +# CHECK-S: amomax.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amomax.w.aq a2, a1, (a0) +# CHECK-OBJ: amomax.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomax.w.aq a2, a1, (a0) +amomax.w.aq a2, a1, 0(a0) + +# CHECK-S: amomax.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amomax.w.rl a2, a1, (a0) +# CHECK-OBJ: amomax.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomax.w.rl a2, a1, (a0) +amomax.w.rl a2, a1, 0(a0) + +# CHECK-S: amomax.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amomax.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amomax.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomax.w.aqrl a2, a1, (a0) +amomax.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amominu.w a2, a1, (a0) +# CHECK-S-NOALIAS: amominu.w a2, a1, (a0) +# CHECK-OBJ: amominu.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amominu.w a2, a1, (a0) +amominu.w a2, a1, 0(a0) + +# CHECK-S: amominu.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amominu.w.aq a2, a1, (a0) +# CHECK-OBJ: amominu.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amominu.w.aq a2, a1, (a0) +amominu.w.aq a2, a1, 0(a0) + +# CHECK-S: amominu.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amominu.w.rl a2, a1, (a0) +# CHECK-OBJ: amominu.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amominu.w.rl a2, a1, (a0) +amominu.w.rl a2, a1, 0(a0) + +# CHECK-S: amominu.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amominu.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amominu.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amominu.w.aqrl a2, a1, (a0) +amominu.w.aqrl a2, a1, 0(a0) + +# CHECK-S: amomaxu.w a2, a1, (a0) +# CHECK-S-NOALIAS: amomaxu.w a2, a1, (a0) +# CHECK-OBJ: amomaxu.w a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomaxu.w a2, a1, (a0) +amomaxu.w a2, a1, 0(a0) + +# CHECK-S: amomaxu.w.aq a2, a1, (a0) +# CHECK-S-NOALIAS: amomaxu.w.aq a2, a1, (a0) +# CHECK-OBJ: amomaxu.w.aq a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomaxu.w.aq a2, a1, (a0) +amomaxu.w.aq a2, a1, 0(a0) + +# CHECK-S: amomaxu.w.rl a2, a1, (a0) +# CHECK-S-NOALIAS: amomaxu.w.rl a2, a1, (a0) +# CHECK-OBJ: amomaxu.w.rl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomaxu.w.rl a2, a1, (a0) +amomaxu.w.rl a2, a1, 0(a0) + +# CHECK-S: amomaxu.w.aqrl a2, a1, (a0) +# CHECK-S-NOALIAS: amomaxu.w.aqrl a2, a1, (a0) +# CHECK-OBJ: amomaxu.w.aqrl a2, a1, (a0) +# CHECK-OBJ-NOALIAS: amomaxu.w.aqrl a2, a1, (a0) +amomaxu.w.aqrl a2, a1, 0(a0)