164 changes: 17 additions & 147 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
OperandMatchResultTy tryParseMatrixTileList(OperandVector &Operands);
OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands);
OperandMatchResultTy tryParseGPR64x8(OperandVector &Operands);
OperandMatchResultTy tryParseImmRange(OperandVector &Operands);

public:
enum AArch64MatchResultTy {
Expand Down Expand Up @@ -304,8 +303,8 @@ class AArch64AsmParser : public MCTargetAsmParser {
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
}

bool areEqualRegs(const MCParsedAsmOperand &Op1,
const MCParsedAsmOperand &Op2) const override;
bool regsEqual(const MCParsedAsmOperand &Op1,
const MCParsedAsmOperand &Op2) const override;
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override;
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Expand All @@ -328,7 +327,6 @@ class AArch64Operand : public MCParsedAsmOperand {
enum KindTy {
k_Immediate,
k_ShiftedImm,
k_ImmRange,
k_CondCode,
k_Register,
k_MatrixRegister,
Expand Down Expand Up @@ -419,11 +417,6 @@ class AArch64Operand : public MCParsedAsmOperand {
unsigned ShiftAmount;
};

struct ImmRangeOp {
unsigned First;
unsigned Last;
};

struct CondCodeOp {
AArch64CC::CondCode Code;
};
Expand Down Expand Up @@ -485,7 +478,6 @@ class AArch64Operand : public MCParsedAsmOperand {
struct VectorIndexOp VectorIndex;
struct ImmOp Imm;
struct ShiftedImmOp ShiftedImm;
struct ImmRangeOp ImmRange;
struct CondCodeOp CondCode;
struct FPImmOp FPImm;
struct BarrierOp Barrier;
Expand Down Expand Up @@ -519,9 +511,6 @@ class AArch64Operand : public MCParsedAsmOperand {
case k_ShiftedImm:
ShiftedImm = o.ShiftedImm;
break;
case k_ImmRange:
ImmRange = o.ImmRange;
break;
case k_CondCode:
CondCode = o.CondCode;
break;
Expand Down Expand Up @@ -600,16 +589,6 @@ class AArch64Operand : public MCParsedAsmOperand {
return ShiftedImm.ShiftAmount;
}

unsigned getFirstImmVal() const {
assert(Kind == k_ImmRange && "Invalid access!");
return ImmRange.First;
}

unsigned getLastImmVal() const {
assert(Kind == k_ImmRange && "Invalid access!");
return ImmRange.Last;
}

AArch64CC::CondCode getCondCode() const {
assert(Kind == k_CondCode && "Invalid access!");
return CondCode.Code;
Expand Down Expand Up @@ -773,30 +752,18 @@ class AArch64Operand : public MCParsedAsmOperand {
return isImmScaled<Bits, Scale>(true);
}

template <int Bits, int Scale, int Offset = 0, bool IsRange = false>
DiagnosticPredicate isUImmScaled() const {
if (IsRange && isImmRange() &&
(getLastImmVal() != getFirstImmVal() + Offset))
return DiagnosticPredicateTy::NoMatch;

return isImmScaled<Bits, Scale, IsRange>(false);
template <int Bits, int Scale> DiagnosticPredicate isUImmScaled() const {
return isImmScaled<Bits, Scale>(false);
}

template <int Bits, int Scale, bool IsRange = false>
template <int Bits, int Scale>
DiagnosticPredicate isImmScaled(bool Signed) const {
if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
(isImmRange() && !IsRange))
if (!isImm())
return DiagnosticPredicateTy::NoMatch;

int64_t Val;
if (isImmRange())
Val = getFirstImmVal();
else {
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return DiagnosticPredicateTy::NoMatch;
Val = MCE->getValue();
}
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return DiagnosticPredicateTy::NoMatch;

int64_t MinVal, MaxVal;
if (Signed) {
Expand All @@ -808,6 +775,7 @@ class AArch64Operand : public MCParsedAsmOperand {
MaxVal = ((int64_t(1) << Bits) - 1) * Scale;
}

int64_t Val = MCE->getValue();
if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
return DiagnosticPredicateTy::Match;

Expand Down Expand Up @@ -907,8 +875,6 @@ class AArch64Operand : public MCParsedAsmOperand {

bool isShiftedImm() const { return Kind == k_ShiftedImm; }

bool isImmRange() const { return Kind == k_ImmRange; }

/// Returns the immediate value as a pair of (imm, shift) if the immediate is
/// a shifted immediate by value 'Shift' or '0', or if it is an unshifted
/// immediate that can be shifted by 'Shift'.
Expand Down Expand Up @@ -1177,8 +1143,6 @@ class AArch64Operand : public MCParsedAsmOperand {
return Kind == k_Register;
}

bool isVectorList() const { return Kind == k_VectorList; }

bool isScalarReg() const {
return Kind == k_Register && Reg.Kind == RegKind::Scalar;
}
Expand Down Expand Up @@ -1804,12 +1768,6 @@ class AArch64Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
}

template <int Scale>
void addImmScaledRangeOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createImm(getFirstImmVal() / Scale));
}

template <typename T>
void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Expand Down Expand Up @@ -2151,17 +2109,6 @@ class AArch64Operand : public MCParsedAsmOperand {
return Op;
}

static std::unique_ptr<AArch64Operand> CreateImmRange(unsigned First,
unsigned Last, SMLoc S,
SMLoc E,
MCContext &Ctx) {
auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
Op->ImmRange.First = First;
Op->ImmRange.Last = Last;
Op->EndLoc = E;
return Op;
}

static std::unique_ptr<AArch64Operand>
CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
Expand Down Expand Up @@ -2324,12 +2271,6 @@ void AArch64Operand::print(raw_ostream &OS) const {
OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
break;
}
case k_ImmRange: {
OS << "<immrange ";
OS << getFirstImmVal();
OS << ":" << getLastImmVal() << ">";
break;
}
case k_CondCode:
OS << "<condcode " << getCondCode() << ">";
break;
Expand Down Expand Up @@ -3056,10 +2997,6 @@ AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) {
// Operand should start from # or should be integer, emit error otherwise.
return MatchOperand_NoMatch;

if (getTok().is(AsmToken::Integer) &&
getLexer().peekTok().is(AsmToken::Colon))
return tryParseImmRange(Operands);

const MCExpr *Imm = nullptr;
if (parseSymbolicImmVal(Imm))
return MatchOperand_ParseFail;
Expand Down Expand Up @@ -4593,21 +4530,13 @@ bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
return false;
}

bool AArch64AsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
const MCParsedAsmOperand &Op2) const {
bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
const MCParsedAsmOperand &Op2) const {
auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
auto &AOp2 = static_cast<const AArch64Operand&>(Op2);

if (AOp1.isVectorList() && AOp2.isVectorList())
return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
AOp1.getVectorListStart() == AOp2.getVectorListStart();

if (!AOp1.isReg() || !AOp2.isReg())
return false;

if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
return MCTargetAsmParser::areEqualRegs(Op1, Op2);
return MCTargetAsmParser::regsEqual(Op1, Op2);

assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
"Testing equality of non-scalar registers not supported");
Expand Down Expand Up @@ -5248,12 +5177,10 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
OperandVector &Operands) {
switch (ErrCode) {
case Match_InvalidTiedOperand: {
auto &Op = static_cast<const AArch64Operand &>(*Operands[ErrorInfo]);
if (Op.isVectorList())
return Error(Loc, "operand must match destination register list");

assert(Op.isReg() && "Unexpected operand type");
switch (Op.getRegEqualityTy()) {
RegConstraintEqualityTy EqTy =
static_cast<const AArch64Operand &>(*Operands[ErrorInfo])
.getRegEqualityTy();
switch (EqTy) {
case RegConstraintEqualityTy::EqualsSubReg:
return Error(Loc, "operand must be 64-bit form of destination register");
case RegConstraintEqualityTy::EqualsSuperReg:
Expand Down Expand Up @@ -5412,15 +5339,6 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "immediate must be an integer in range [1, 32].");
case Match_InvalidImm1_64:
return Error(Loc, "immediate must be an integer in range [1, 64].");
case Match_InvalidMemoryIndexedRange2UImm2:
case Match_InvalidMemoryIndexedRange2UImm3:
return Error(
Loc,
"vector select offset must be an immediate range of the form "
"<immf>:<imml>, "
"where the first immediate is a multiple of 2 in the range [0, 6] or "
"[0, 14] "
"depending on the instruction, and the second immediate is immf + 1.");
case Match_InvalidSVEAddSubImm8:
return Error(Loc, "immediate must be an integer in range [0, 255]"
" with a shift amount of 0");
Expand Down Expand Up @@ -5553,9 +5471,6 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h");
case Match_InvalidZPR_3b32:
return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s");
case Match_InvalidZPR_4b8:
return Error(Loc,
"Invalid restricted vector register, expected z0.b..z15.b");
case Match_InvalidZPR_4b16:
return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h");
case Match_InvalidZPR_4b32:
Expand Down Expand Up @@ -5611,15 +5526,11 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "operand must be a register in range [w12, w15]");
case Match_InvalidMatrixIndexGPR32_8_11:
return Error(Loc, "operand must be a register in range [w8, w11]");
case Match_InvalidSVEVectorListMul2x8:
case Match_InvalidSVEVectorListMul2x16:
case Match_InvalidSVEVectorListMul2x32:
case Match_InvalidSVEVectorListMul2x64:
return Error(Loc, "Invalid vector list, expected list with 2 consecutive "
"SVE vectors, where the first vector is a multiple of 2 "
"and with matching element types");
case Match_InvalidSVEVectorListMul4x8:
case Match_InvalidSVEVectorListMul4x16:
case Match_InvalidSVEVectorListMul4x32:
case Match_InvalidSVEVectorListMul4x64:
return Error(Loc, "Invalid vector list, expected list with 4 consecutive "
Expand Down Expand Up @@ -6066,8 +5977,6 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidImm1_16:
case Match_InvalidImm1_32:
case Match_InvalidImm1_64:
case Match_InvalidMemoryIndexedRange2UImm2:
case Match_InvalidMemoryIndexedRange2UImm3:
case Match_InvalidSVEAddSubImm8:
case Match_InvalidSVEAddSubImm16:
case Match_InvalidSVEAddSubImm32:
Expand Down Expand Up @@ -6133,7 +6042,6 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidZPR_3b8:
case Match_InvalidZPR_3b16:
case Match_InvalidZPR_3b32:
case Match_InvalidZPR_4b8:
case Match_InvalidZPR_4b16:
case Match_InvalidZPR_4b32:
case Match_InvalidZPR_4b64:
Expand Down Expand Up @@ -6165,12 +6073,8 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSVCR:
case Match_InvalidMatrixIndexGPR32_12_15:
case Match_InvalidMatrixIndexGPR32_8_11:
case Match_InvalidSVEVectorListMul2x8:
case Match_InvalidSVEVectorListMul2x16:
case Match_InvalidSVEVectorListMul2x32:
case Match_InvalidSVEVectorListMul2x64:
case Match_InvalidSVEVectorListMul4x8:
case Match_InvalidSVEVectorListMul4x16:
case Match_InvalidSVEVectorListMul4x32:
case Match_InvalidSVEVectorListMul4x64:
case Match_MSR:
Expand Down Expand Up @@ -7362,37 +7266,3 @@ AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) {
AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
return MatchOperand_Success;
}

OperandMatchResultTy
AArch64AsmParser::tryParseImmRange(OperandVector &Operands) {
SMLoc S = getLoc();

if (getTok().isNot(AsmToken::Integer))
return MatchOperand_NoMatch;

if (getLexer().peekTok().isNot(AsmToken::Colon))
return MatchOperand_NoMatch;

const MCExpr *ImmF;
if (getParser().parseExpression(ImmF))
return MatchOperand_NoMatch;

if (getTok().isNot(AsmToken::Colon))
return MatchOperand_NoMatch;

Lex(); // Eat ':'
if (getTok().isNot(AsmToken::Integer))
return MatchOperand_NoMatch;

SMLoc E = getTok().getLoc();
const MCExpr *ImmL;
if (getParser().parseExpression(ImmL))
return MatchOperand_NoMatch;

unsigned ImmFVal = dyn_cast<MCConstantExpr>(ImmF)->getValue();
unsigned ImmLVal = dyn_cast<MCConstantExpr>(ImmL)->getValue();

Operands.push_back(
AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
return MatchOperand_Success;
}
9 changes: 0 additions & 9 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1223,15 +1223,6 @@ void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum,
<< formatImm(Scale * MI->getOperand(OpNum).getImm()) << markup(">");
}

template <int Scale, int Offset>
void AArch64InstPrinter::printImmRangeScale(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned FirstImm = Scale * MI->getOperand(OpNum).getImm();
O << formatImm(FirstImm);
O << ":" << formatImm(FirstImm + Offset);
}

void AArch64InstPrinter::printUImm12Offset(const MCInst *MI, unsigned OpNum,
unsigned Scale, raw_ostream &O) {
const MCOperand MO = MI->getOperand(OpNum);
Expand Down
4 changes: 0 additions & 4 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,6 @@ class AArch64InstPrinter : public MCInstPrinter {
void printImmScale(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);

template <int Scale, int Offset>
void printImmRangeScale(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);

template <bool IsSVEPrefetch = false>
void printPrefetchOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
Expand Down
287 changes: 0 additions & 287 deletions llvm/lib/Target/AArch64/SMEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1337,290 +1337,3 @@ multiclass sme2_mla_add_sub_array_vg4_multi_D<string mnemonic, bits<2> op>{
def : InstAlias<mnemonic # "\t$ZAd[$Rv, $imm3], $Zn, $Zm",
(!cast<Instruction>(NAME) MatrixOp64:$ZAd, MatrixIndexGPR32Op8_11:$Rv, sme_elm_idx0_7:$imm3, ZZZZ_d_mul_r:$Zn, ZZZZ_d_mul_r:$Zm), 0>;
}

//===----------------------------------------------------------------------===//
// SME2 Multi-vector - Multiple and Single SVE Destructive
// Two and Four registers

class sme2_sqdmulh_add_vector_vg2_single<bits<2> sz, bits<6> op,
RegisterOperand vector_ty,
ZPRRegOp zpr_ty, string mnemonic>
: I<(outs vector_ty:$Zdn), (ins vector_ty:$_Zdn, zpr_ty:$Zm),
mnemonic, "\t$Zdn, $_Zdn, $Zm",
"", []>, Sched<[]> {
bits<4> Zm;
bits<4> Zdn;
let Inst{31-24} = 0b11000001;
let Inst{23-22} = sz;
let Inst{21-20} = 0b10;
let Inst{19-16} = Zm;
let Inst{15-11} = 0b10100;
let Inst{10-5} = op;
let Inst{4-1} = Zdn;
let Inst{0} = 0b0;
let Constraints = "$Zdn = $_Zdn";
}

multiclass sme2_sqdmulh_add_vector_vg2_single<string mnemonic, bits<6> op> {
def _B : sme2_sqdmulh_add_vector_vg2_single<0b00, op, ZZ_b_mul_r, ZPR4b8, mnemonic>;
def _H : sme2_sqdmulh_add_vector_vg2_single<0b01, op, ZZ_h_mul_r, ZPR4b16, mnemonic>;
def _S : sme2_sqdmulh_add_vector_vg2_single<0b10, op, ZZ_s_mul_r, ZPR4b32, mnemonic>;
def _D : sme2_sqdmulh_add_vector_vg2_single<0b11, op, ZZ_d_mul_r, ZPR4b64, mnemonic>;
}

class sme2_sqdmulh_add_vector_vg4_single<bits<2> sz, bits<6> op,
RegisterOperand vector_ty,
ZPRRegOp zpr_ty, string mnemonic>
: I<(outs vector_ty:$Zdn), (ins vector_ty:$_Zdn, zpr_ty:$Zm),
mnemonic, "\t$Zdn, $_Zdn, $Zm",
"", []>, Sched<[]> {
bits<4> Zm;
bits<3> Zdn;
let Inst{31-24} = 0b11000001;
let Inst{23-22} = sz;
let Inst{21-20} = 0b10;
let Inst{19-16} = Zm;
let Inst{15-11} = 0b10101;
let Inst{10-5} = op;
let Inst{4-2} = Zdn;
let Inst{1-0} = 0b00;
let Constraints = "$Zdn = $_Zdn";
}

multiclass sme2_sqdmulh_add_vector_vg4_single<string mnemonic, bits<6> op> {
def _B : sme2_sqdmulh_add_vector_vg4_single<0b00, op, ZZZZ_b_mul_r, ZPR4b8, mnemonic>;
def _H : sme2_sqdmulh_add_vector_vg4_single<0b01, op, ZZZZ_h_mul_r, ZPR4b16, mnemonic>;
def _S : sme2_sqdmulh_add_vector_vg4_single<0b10, op, ZZZZ_s_mul_r, ZPR4b32, mnemonic>;
def _D : sme2_sqdmulh_add_vector_vg4_single<0b11, op, ZZZZ_d_mul_r, ZPR4b64, mnemonic>;
}

//===----------------------------------------------------------------------===//
// SME2 Multi-vector - Index/Single/Multi Array Vectors FMA sources

class sme2_mla_long_array_index_base<bits<2> op0, bits<2> op, Operand index_ty,
RegisterOperand multi_vector_ty,
string mnemonic, string vg_acronym="">
: I<(outs MatrixOp32:$ZAda),
(ins MatrixOp32:$_ZAda, MatrixIndexGPR32Op8_11:$Rv, index_ty:$imm, multi_vector_ty:$Zn, ZPR4b16:$Zm, VectorIndexH:$i3),
mnemonic, "\t$ZAda[$Rv, $imm" # !if(!eq(vg_acronym, ""), "", ", " # vg_acronym) # "], $Zn, $Zm$i3",
"", []>, Sched<[]> {
bits<4> Zm;
bits<2> Rv;
let Inst{31-24} = 0b11000001;
let Inst{23-22} = op0;
let Inst{21} = 0b0;
let Inst{20} = !if(!eq(vg_acronym, ""), 0, 1);
let Inst{19-16} = Zm;
let Inst{14-13} = Rv;
let Inst{12} = 0b1;
let Inst{4-3} = op;

let Constraints = "$ZAda = $_ZAda";
}

multiclass sme2_mla_long_array_index<string mnemonic, bits<2> op0, bits<2> op> {
def _S : sme2_mla_long_array_index_base<op0, op, uimm3s2range, ZPR16,
mnemonic> {
bits<3> i3;
bits<5> Zn;
bits<3> imm;
let Inst{15} = i3{2};
let Inst{11-10} = i3{1-0};
let Inst{9-5} = Zn;
let Inst{2-0} = imm;
}
}

class sme2_mla_long_array_vg2_index<string mnemonic, bits<2> op0, bits<2> op>
: sme2_mla_long_array_index_base<op0, op, uimm2s2range, ZZ_h_mul_r,
mnemonic, "vgx2"> {
bits<3> i3;
bits<4> Zn;
bits<2> imm;
let Inst{15} = 0b0;
let Inst{11-10} = i3{2-1};
let Inst{9-6} = Zn;
let Inst{5} = 0b0;
let Inst{2} = i3{0};
let Inst{1-0} = imm;
}

multiclass sme2_fp_mla_long_array_vg2_index<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg2_index<mnemonic, 0b10, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm$i3",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZ_h_mul_r:$Zn, ZPR4b16:$Zm, VectorIndexH:$i3), 0>;
}

multiclass sme2_int_mla_long_array_vg2_index<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg2_index<mnemonic, 0b11, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm$i3",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZ_h_mul_r:$Zn, ZPR4b16:$Zm, VectorIndexH:$i3), 0>;
}

class sme2_mla_long_array_vg4_index<string mnemonic, bits<2> op0, bits<2> op>
: sme2_mla_long_array_index_base<op0, op, uimm2s2range, ZZZZ_h_mul_r,
mnemonic, "vgx4"> {
bits<3> i3;
bits<3> Zn;
bits<2> imm;
let Inst{15} = 0b1;
let Inst{11-10} = i3{2-1};
let Inst{9-7} = Zn;
let Inst{6-5} = 0b00;
let Inst{2} = i3{0};
let Inst{1-0} = imm;
}

multiclass sme2_fp_mla_long_array_vg4_index<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg4_index<mnemonic, 0b10, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm$i3",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZZZ_h_mul_r:$Zn, ZPR4b16:$Zm, VectorIndexH:$i3), 0>;
}

multiclass sme2_int_mla_long_array_vg4_index<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg4_index<mnemonic, 0b11, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm$i3",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZZZ_h_mul_r:$Zn, ZPR4b16:$Zm, VectorIndexH:$i3), 0>;
}

class sme2_mla_long_array<bits<2>op0, bits<2> op, Operand index_ty,
RegisterOperand first_vector_ty,
RegisterOperand second_vector_ty,
string mnemonic, string vg_acronym="">
: I<(outs MatrixOp32:$ZAda),
(ins MatrixOp32:$_ZAda, MatrixIndexGPR32Op8_11:$Rv,
index_ty:$imm, first_vector_ty:$Zn, second_vector_ty:$Zm),
mnemonic,"\t$ZAda[$Rv, $imm" # !if(!eq(vg_acronym, ""), "", ", " # vg_acronym) # "], $Zn, $Zm",
"", []> , Sched<[]> {
bits<2> Rv;
let Inst{31-24} = 0b11000001;
let Inst{23-22} = op0;
let Inst{21} = 0b1;
let Inst{15} = 0b0;
let Inst{14-13} = Rv;
let Inst{12-11} = 0b01;
let Inst{10} = !if(!eq(vg_acronym, ""), 1, 0);
let Inst{4-3} = op;

let Constraints = "$ZAda = $_ZAda";
}

multiclass sme2_mla_long_array_single<string mnemonic, bits<2> op0, bits<2> op> {
def _S : sme2_mla_long_array<op0, op, uimm3s2range, ZPR16, ZPR4b16,
mnemonic> {
bits<4> Zm;
bits<5> Zn;
bits<3> imm;
let Inst{20} = 0b0;
let Inst{19-16} = Zm;
let Inst{9-5} = Zn;
let Inst{2-0} = imm;
}
}

class sme2_mla_long_array_vg24_single<bits<2> op0, bit vg4, bits<2> op,
RegisterOperand first_vector_ty,
string mnemonic, string vg_acronym>
: sme2_mla_long_array<op0, op, uimm2s2range, first_vector_ty, ZPR4b16,
mnemonic, vg_acronym> {
bits<4> Zm;
bits<5> Zn;
bits<2> imm;
let Inst{20} = vg4;
let Inst{19-16} = Zm;
let Inst{9-5} = Zn;
let Inst{2} = 0b0;
let Inst{1-0} = imm;
}

multiclass sme2_fp_mla_long_array_vg2_single<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg24_single<0b00, 0b0, op, ZZ_h, mnemonic,
"vgx2">;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZ_h:$Zn, ZPR4b16:$Zm), 0>;
}

multiclass sme2_int_mla_long_array_vg2_single<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg24_single<0b01, 0b0, op, ZZ_h, mnemonic,
"vgx2">;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZ_h:$Zn, ZPR4b16:$Zm), 0>;
}

multiclass sme2_fp_mla_long_array_vg4_single<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg24_single<0b00, 0b1, op, ZZZZ_h, mnemonic,
"vgx4">;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZZZ_h:$Zn, ZPR4b16:$Zm), 0>;
}

multiclass sme2_int_mla_long_array_vg4_single<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg24_single<0b01, 0b1, op, ZZZZ_h, mnemonic,
"vgx4">;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZZZ_h:$Zn, ZPR4b16:$Zm), 0>;
}
class sme2_mla_long_array_vg2_multi<string mnemonic, bits<2> op0, bits<2> op>
: sme2_mla_long_array<op0, op, uimm2s2range, ZZ_h_mul_r, ZZ_h_mul_r, mnemonic,
"vgx2"> {
bits<4> Zm;
bits<4> Zn;
bits<2> imm;
let Inst{20-17} = Zm;
let Inst{16} = 0b0;
let Inst{9-6} = Zn;
let Inst{5} = 0b0;
let Inst{2} = 0b0;
let Inst{1-0} = imm;
}

multiclass sme2_fp_mla_long_array_vg2_multi<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg2_multi<mnemonic, 0b10, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZ_h_mul_r:$Zn, ZZ_h_mul_r:$Zm), 0>;
}

multiclass sme2_int_mla_long_array_vg2_multi<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg2_multi<mnemonic, 0b11, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm2], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm2, ZZ_h_mul_r:$Zn, ZZ_h_mul_r:$Zm), 0>;
}

class sme2_mla_long_array_vg4_multi<string mnemonic, bits<2> op0, bits<2> op>
: sme2_mla_long_array<op0, op, uimm2s2range, ZZZZ_h_mul_r, ZZZZ_h_mul_r, mnemonic,
"vgx4"> {
bits<3> Zm;
bits<3> Zn;
bits<2> imm;
let Inst{20-18} = Zm;
let Inst{17} = 0b0;
let Inst{16} = 0b1;
let Inst{9-7} = Zn;
let Inst{6-5} = 0b00;
let Inst{2} = 0b0;
let Inst{1-0} = imm;
}

multiclass sme2_fp_mla_long_array_vg4_multi<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg4_multi<mnemonic, 0b10, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm, ZZZZ_h_mul_r:$Zn, ZZZZ_h_mul_r:$Zm), 0>;
}

multiclass sme2_int_mla_long_array_vg4_multi<string mnemonic, bits<2> op> {
def _S : sme2_mla_long_array_vg4_multi<mnemonic, 0b11, op>;

def : InstAlias<mnemonic # "\t$ZAda[$Rv, $imm2], $Zn, $Zm",
(!cast<Instruction>(NAME #_S) MatrixOp32:$ZAda, MatrixIndexGPR32Op8_11:$Rv, uimm2s2range:$imm2, ZZZZ_h_mul_r:$Zn, ZZZZ_h_mul_r:$Zm), 0>;
}
31 changes: 2 additions & 29 deletions llvm/test/MC/AArch64/SME2/add-diagnostics.s
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ add za.s[w7, 0], {z0.s - z1.s}, {z2.s - z3.s}
// CHECK-NEXT: add za.s[w7, 0], {z0.s - z1.s}, {z2.s - z3.s}
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:$


// --------------------------------------------------------------------------//
// Invalid Matrix Operand

Expand Down Expand Up @@ -80,6 +81,7 @@ add za.d[w11, 7, vgx4], {z12.d-z15.d}, {z9.d-z12.d}
// CHECK-NEXT: add za.d[w11, 7, vgx4], {z12.d-z15.d}, {z9.d-z12.d}
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


add za.s[w10, 3], {z10.b-z11.b}, {z20.b-z21.b}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: add za.s[w10, 3], {z10.b-z11.b}, {z20.b-z21.b}
Expand All @@ -89,32 +91,3 @@ add za.d[w11, 7], {z28.h - z31.h}, {z28.h - z31.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: add za.d[w11, 7], {z28.h - z31.h}, {z28.h - z31.h}
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// --------------------------------------------------------------------------//
// The tied operands must match, even for vector groups.

add {z0.s-z1.s}, {z2.s-z3.s}, z15.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
// CHECK-NEXT: add {z0.s-z1.s}, {z2.s-z3.s}, z15.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

add {z0.s,z1.s}, {z2.s,z3.s}, z15.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
// CHECK-NEXT: add {z0.s,z1.s}, {z2.s,z3.s}, z15.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

add {z0.s,z1.s}, {z0.s,z2.s}, z15.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: registers must be sequential
// CHECK-NEXT: add {z0.s,z1.s}, {z0.s,z2.s}, z15.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

add {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: add {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

add {z0.s,z1.s}, {z0.d,z1.d}, z15.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: add {z0.s,z1.s}, {z0.d,z1.d}, z15.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

357 changes: 2 additions & 355 deletions llvm/test/MC/AArch64/SME2/add.s

Large diffs are not rendered by default.

79 changes: 0 additions & 79 deletions llvm/test/MC/AArch64/SME2/bfmlal-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/bfmlal.s

This file was deleted.

79 changes: 0 additions & 79 deletions llvm/test/MC/AArch64/SME2/bfmlsl-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/bfmlsl.s

This file was deleted.

74 changes: 0 additions & 74 deletions llvm/test/MC/AArch64/SME2/fmlal-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/fmlal.s

This file was deleted.

74 changes: 0 additions & 74 deletions llvm/test/MC/AArch64/SME2/fmlsl-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/fmlsl.s

This file was deleted.

74 changes: 0 additions & 74 deletions llvm/test/MC/AArch64/SME2/smlal-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/smlal.s

This file was deleted.

74 changes: 0 additions & 74 deletions llvm/test/MC/AArch64/SME2/smlsl-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/smlsl.s

This file was deleted.

79 changes: 0 additions & 79 deletions llvm/test/MC/AArch64/SME2/sqdmulh-diagnostics.s

This file was deleted.

212 changes: 0 additions & 212 deletions llvm/test/MC/AArch64/SME2/sqdmulh.s

This file was deleted.

74 changes: 0 additions & 74 deletions llvm/test/MC/AArch64/SME2/umlal-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/umlal.s

This file was deleted.

69 changes: 0 additions & 69 deletions llvm/test/MC/AArch64/SME2/umlsl-diagnostics.s

This file was deleted.

1,029 changes: 0 additions & 1,029 deletions llvm/test/MC/AArch64/SME2/umlsl.s

This file was deleted.

8 changes: 5 additions & 3 deletions llvm/utils/TableGen/AsmMatcherEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3029,9 +3029,11 @@ static void emitAsmTiedOperandConstraints(CodeGenTarget &Target,
OS << " if (OpndNum1 != OpndNum2) {\n";
OS << " auto &SrcOp1 = Operands[OpndNum1];\n";
OS << " auto &SrcOp2 = Operands[OpndNum2];\n";
OS << " if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {\n";
OS << " ErrorInfo = OpndNum2;\n";
OS << " return false;\n";
OS << " if (SrcOp1->isReg() && SrcOp2->isReg()) {\n";
OS << " if (!AsmParser.regsEqual(*SrcOp1, *SrcOp2)) {\n";
OS << " ErrorInfo = OpndNum2;\n";
OS << " return false;\n";
OS << " }\n";
OS << " }\n";
OS << " }\n";
OS << " break;\n";
Expand Down