[AArch64] Adding "armv8.8-a" memcpy/memset support.

This family of instructions includes CPYF (copy forward), CPYB (copy
backward), SET (memset) and SETG (memset + initialise MTE tags), with
some sub-variants to indicate whether address translation is done in a
privileged or unprivileged way. For the copy instructions, you can
separately specify the read and write translations (so that kernels
can safely use these instructions in syscall handlers, to memcpy
between the calling process's user-space memory map and the kernel's
own privileged one).

The unusual thing about these instructions is that they write back to
multiple registers, because they perform an implementation-defined
amount of copying each time they run, and write back to _all_ the
address and size registers to indicate how much remains to be done
(and the code is expected to loop on them until the size register
becomes zero). But this is no problem in LLVM - you just define each
instruction to have multiple outputs, multiple inputs, and a set of
constraints tying their register numbers together appropriately.

This commit introduces a special subtarget feature called MOPS (after
the name the spec gives to the CPU id field), which is a dependency of
the top-level 8.8-A feature, and uses that to enable most of the new
instructions. The SETMG instructions also depend on MTE (and the test
checks that).

Differential Revision: https://reviews.llvm.org/D116157
This commit is contained in:
Simon Tatham 2021-02-11 11:41:20 +00:00 committed by Tomas Matheson
parent b30a18f445
commit e35a3f188f
15 changed files with 1467 additions and 9 deletions

View File

@ -419,6 +419,9 @@ def FeatureLS64 : SubtargetFeature<"ls64", "HasLS64",
def FeatureHBC : SubtargetFeature<"hbc", "HasHBC",
"true", "Enable Armv8.8-A Hinted Conditional Branches Extension">;
def FeatureMOPS : SubtargetFeature<"mops", "HasMOPS",
"true", "Enable Armv8.8-A memcpy and memset acceleration instructions">;
def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE",
"true", "Enable Branch Record Buffer Extension">;
@ -502,7 +505,7 @@ def HasV8_7aOps : SubtargetFeature<
def HasV8_8aOps : SubtargetFeature<
"v8.8a", "HasV8_8aOps", "true", "Support ARM v8.8a instructions",
[HasV8_7aOps, FeatureHBC]>;
[HasV8_7aOps, FeatureHBC, FeatureMOPS]>;
def HasV9_0aOps : SubtargetFeature<
"v9a", "HasV9_0aOps", "true", "Support ARM v9a instructions",

View File

@ -11430,6 +11430,123 @@ class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>
let Inst{20-16} = Rs;
}
class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1,
bits<2> op2, string asm>
: I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),
(ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn),
asm, "\t[$Rd]!, [$Rs]!, $Rn!",
"$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>,
Sched<[]> {
bits<5> Rd;
bits<5> Rs;
bits<5> Rn;
let Inst{31-27} = 0b00011;
let Inst{26} = isMove;
let Inst{25-24} = 0b01;
let Inst{23-22} = opcode;
let Inst{21} = 0b0;
let Inst{20-16} = Rs;
let Inst{15-14} = op2;
let Inst{13-12} = op1;
let Inst{11-10} = 0b01;
let Inst{9-5} = Rn;
let Inst{4-0} = Rd;
let DecoderMethod = "DecodeCPYMemOpInstruction";
let mayLoad = 1;
let mayStore = 1;
}
class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
: MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>;
class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>
: MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>;
class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2,
string asm>
: I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb),
(ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),
asm, "\t[$Rd]!, $Rn!, $Rm",
"$Rd = $Rd_wb,$Rn = $Rn_wb", []>,
Sched<[]> {
bits<5> Rd;
bits<5> Rn;
bits<5> Rm;
let Inst{31-27} = 0b00011;
let Inst{26} = isTagging;
let Inst{25-21} = 0b01110;
let Inst{20-16} = Rm;
let Inst{15-14} = opcode;
let Inst{13} = op2;
let Inst{12} = op1;
let Inst{11-10} = 0b01;
let Inst{9-5} = Rn;
let Inst{4-0} = Rd;
let DecoderMethod = "DecodeSETMemOpInstruction";
let mayLoad = 0;
let mayStore = 1;
}
class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm>
: MOPSMemorySetBase<0, opcode, op1, op2, asm>;
class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm>
: MOPSMemorySetBase<1, opcode, op1, op2, asm>;
multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> {
def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>;
def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">;
def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">;
def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">;
def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">;
def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">;
def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">;
def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">;
def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">;
def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">;
def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">;
def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">;
def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">;
def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">;
def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">;
def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">;
}
multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> {
def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>;
def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">;
def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">;
def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">;
def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">;
def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">;
def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">;
def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">;
def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">;
def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">;
def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">;
def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">;
def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">;
def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">;
def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">;
def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">;
}
multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> {
def "" : MOPSMemorySet<opcode, 0, 0, asm>;
def T : MOPSMemorySet<opcode, 1, 0, asm # "t">;
def N : MOPSMemorySet<opcode, 0, 1, asm # "n">;
def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">;
}
multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> {
def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>;
def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">;
def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">;
def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">;
}
//----------------------------------------------------------------------------
// Allow the size specifier tokens to be upper case, not just lower.
def : TokenAlias<".4B", ".4b">; // Add dot product

View File

@ -200,8 +200,10 @@ def HasBRBE : Predicate<"Subtarget->hasBRBE()">,
AssemblerPredicate<(all_of FeatureBRBE), "brbe">;
def HasSPE_EEF : Predicate<"Subtarget->hasSPE_EEF()">,
AssemblerPredicate<(all_of FeatureSPE_EEF), "spe-eef">;
def HasHBC : Predicate<"Subtarget->hasHBC()">,
def HasHBC : Predicate<"Subtarget->hasHBC()">,
AssemblerPredicate<(all_of FeatureHBC), "hbc">;
def HasMOPS : Predicate<"Subtarget->hasMOPS()">,
AssemblerPredicate<(all_of FeatureMOPS), "mops">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
@ -8315,6 +8317,26 @@ let Predicates = [HasLS64] in {
def : ST64BPattern<int_aarch64_st64bv0, ST64BV0>;
}
let Predicates = [HasMOPS] in {
defm CPYFP : MOPSMemoryCopyInsns<0b00, "cpyfp">;
defm CPYFM : MOPSMemoryCopyInsns<0b01, "cpyfm">;
defm CPYFE : MOPSMemoryCopyInsns<0b10, "cpyfe">;
defm CPYP : MOPSMemoryMoveInsns<0b00, "cpyp">;
defm CPYM : MOPSMemoryMoveInsns<0b01, "cpym">;
defm CPYE : MOPSMemoryMoveInsns<0b10, "cpye">;
defm SETP : MOPSMemorySetInsns<0b00, "setp">;
defm SETM : MOPSMemorySetInsns<0b01, "setm">;
defm SETE : MOPSMemorySetInsns<0b10, "sete">;
}
let Predicates = [HasMOPS, HasMTE] in {
defm SETGP : MOPSMemorySetTaggingInsns<0b00, "setgp">;
defm SETGM : MOPSMemorySetTaggingInsns<0b01, "setgm">;
// Can't use SETGE because it's a reserved name in TargetSelectionDAG.td
defm MOPSSETGE : MOPSMemorySetTaggingInsns<0b10, "setge">;
}
let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1 in
def StoreSwiftAsyncContext
: Pseudo<(outs), (ins GPR64:$ctx, GPR64sp:$base, simm9:$offset),

View File

@ -526,7 +526,7 @@ def : InstRW<[A57Write_5cyc_2V], (instregex "^FRINT[AIMNPXZ](v4f32|v2f64)")>;
def : InstRW<[A57Write_3cyc_2V], (instregex "^(BIF|BIT|BSL|BSP)v16i8")>;
// ASIMD duplicate, gen reg, D-form and Q-form
def : InstRW<[A57Write_8cyc_1L_1V], (instregex "^CPY")>;
def : InstRW<[A57Write_8cyc_1L_1V], (instregex "^CPY[^PMEF]")>;
def : InstRW<[A57Write_8cyc_1L_1V], (instregex "^DUPv.+gpr")>;
// ASIMD move, saturating

View File

@ -1891,7 +1891,7 @@ def : InstRW<[A64FXWrite_4Cyc_GI0],
// ASIMD duplicate, gen reg
// ASIMD duplicate, element
def : InstRW<[A64FXWrite_DUPGENERAL], (instregex "^DUPv")>;
def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^CPY")>;
def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^CPY[^PMEF]")>;
def : InstRW<[A64FXWrite_6Cyc_GI0], (instregex "^DUPv.+gpr")>;
// ASIMD extract

View File

@ -669,7 +669,7 @@ def : InstRW<[M3WriteNEONB], (instregex "^DUPv.+gpr")>;
def : InstRW<[M3WriteNSHF1], (instregex "^DUPv.+lane")>;
def : InstRW<[M3WriteNSHF1], (instregex "^EXTv")>;
def : InstRW<[M3WriteNSHF1], (instregex "^[SU]?Q?XTU?Nv")>;
def : InstRW<[M3WriteNSHF1], (instregex "^CPY")>;
def : InstRW<[M3WriteNSHF1], (instregex "^CPY[^PMEF]")>;
def : InstRW<[M3WriteNSHF1], (instregex "^INSv.+lane")>;
def : InstRW<[M3WriteMOVI], (instregex "^MOVI")>;
def : InstRW<[M3WriteNALU1], (instregex "^FMOVv")>;

View File

@ -810,7 +810,7 @@ def : InstRW<[M4WriteNALU1], (instregex "^RBITv")>;
def : InstRW<[M4WriteNALU1], (instregex "^(BIF|BIT|BSL|BSP)v")>;
def : InstRW<[M4WriteNALU1], (instregex "^CL[STZ]v")>;
def : InstRW<[M4WriteNEONB], (instregex "^DUPv.+gpr")>;
def : InstRW<[M4WriteNSHF1], (instregex "^CPY")>;
def : InstRW<[M4WriteNSHF1], (instregex "^CPY[^PMEF]")>;
def : InstRW<[M4WriteNSHF1], (instregex "^DUPv.+lane")>;
def : InstRW<[M4WriteNSHF1], (instregex "^EXTv")>;
def : InstRW<[M4WriteNSHT4A], (instregex "^XTNv")>;

View File

@ -848,7 +848,7 @@ def : InstRW<[M5WriteNALU2], (instregex "^RBITv")>;
def : InstRW<[M5WriteNALU2], (instregex "^(BIF|BIT|BSL|BSP)v")>;
def : InstRW<[M5WriteNALU2], (instregex "^CL[STZ]v")>;
def : InstRW<[M5WriteNEONB], (instregex "^DUPv.+gpr")>;
def : InstRW<[M5WriteNSHF2], (instregex "^CPY")>;
def : InstRW<[M5WriteNSHF2], (instregex "^CPY[^PMEF]")>;
def : InstRW<[M5WriteNSHF2], (instregex "^DUPv.+lane")>;
def : InstRW<[M5WriteNSHF2], (instregex "^EXTv")>;
def : InstRW<[M5WriteNSHT4A], (instregex "^XTNv")>;

View File

@ -1499,7 +1499,7 @@ def : InstRW<[THX2T99Write_5Cyc_F01],
// ASIMD duplicate, gen reg
// ASIMD duplicate, element
def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^DUPv")>;
def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^CPY")>;
def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^CPY[^PMEF]")>;
def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^DUPv.+gpr")>;
// ASIMD extract

View File

@ -1608,7 +1608,7 @@ def : InstRW<[THX3T110Write_3_4Cyc_F23_F0123],
// ASIMD duplicate, gen reg
// ASIMD duplicate, element
def : InstRW<[THX3T110Write_5Cyc_F0123], (instregex "^DUPv")>;
def : InstRW<[THX3T110Write_5Cyc_F0123], (instregex "^CPY")>;
def : InstRW<[THX3T110Write_5Cyc_F0123], (instregex "^CPY[^PMEF]")>;
def : InstRW<[THX3T110Write_5Cyc_F0123], (instregex "^DUPv.+gpr")>;
// ASIMD extract

View File

@ -192,6 +192,7 @@ protected:
// Armv8.8-A Extensions
bool HasHBC = false;
bool HasMOPS = false;
// Arm SVE2 extensions
bool HasSVE2 = false;
@ -584,6 +585,7 @@ public:
bool hasEL2VMSA() const { return HasEL2VMSA; }
bool hasEL3() const { return HasEL3; }
bool hasHBC() const { return HasHBC; }
bool hasMOPS() const { return HasMOPS; }
bool fixCortexA53_835769() const { return FixCortexA53_835769; }

View File

@ -4866,6 +4866,177 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
}
}
// Check v8.8-A memops instructions.
switch (Inst.getOpcode()) {
case AArch64::CPYFP:
case AArch64::CPYFPWN:
case AArch64::CPYFPRN:
case AArch64::CPYFPN:
case AArch64::CPYFPWT:
case AArch64::CPYFPWTWN:
case AArch64::CPYFPWTRN:
case AArch64::CPYFPWTN:
case AArch64::CPYFPRT:
case AArch64::CPYFPRTWN:
case AArch64::CPYFPRTRN:
case AArch64::CPYFPRTN:
case AArch64::CPYFPT:
case AArch64::CPYFPTWN:
case AArch64::CPYFPTRN:
case AArch64::CPYFPTN:
case AArch64::CPYFM:
case AArch64::CPYFMWN:
case AArch64::CPYFMRN:
case AArch64::CPYFMN:
case AArch64::CPYFMWT:
case AArch64::CPYFMWTWN:
case AArch64::CPYFMWTRN:
case AArch64::CPYFMWTN:
case AArch64::CPYFMRT:
case AArch64::CPYFMRTWN:
case AArch64::CPYFMRTRN:
case AArch64::CPYFMRTN:
case AArch64::CPYFMT:
case AArch64::CPYFMTWN:
case AArch64::CPYFMTRN:
case AArch64::CPYFMTN:
case AArch64::CPYFE:
case AArch64::CPYFEWN:
case AArch64::CPYFERN:
case AArch64::CPYFEN:
case AArch64::CPYFEWT:
case AArch64::CPYFEWTWN:
case AArch64::CPYFEWTRN:
case AArch64::CPYFEWTN:
case AArch64::CPYFERT:
case AArch64::CPYFERTWN:
case AArch64::CPYFERTRN:
case AArch64::CPYFERTN:
case AArch64::CPYFET:
case AArch64::CPYFETWN:
case AArch64::CPYFETRN:
case AArch64::CPYFETN:
case AArch64::CPYP:
case AArch64::CPYPWN:
case AArch64::CPYPRN:
case AArch64::CPYPN:
case AArch64::CPYPWT:
case AArch64::CPYPWTWN:
case AArch64::CPYPWTRN:
case AArch64::CPYPWTN:
case AArch64::CPYPRT:
case AArch64::CPYPRTWN:
case AArch64::CPYPRTRN:
case AArch64::CPYPRTN:
case AArch64::CPYPT:
case AArch64::CPYPTWN:
case AArch64::CPYPTRN:
case AArch64::CPYPTN:
case AArch64::CPYM:
case AArch64::CPYMWN:
case AArch64::CPYMRN:
case AArch64::CPYMN:
case AArch64::CPYMWT:
case AArch64::CPYMWTWN:
case AArch64::CPYMWTRN:
case AArch64::CPYMWTN:
case AArch64::CPYMRT:
case AArch64::CPYMRTWN:
case AArch64::CPYMRTRN:
case AArch64::CPYMRTN:
case AArch64::CPYMT:
case AArch64::CPYMTWN:
case AArch64::CPYMTRN:
case AArch64::CPYMTN:
case AArch64::CPYE:
case AArch64::CPYEWN:
case AArch64::CPYERN:
case AArch64::CPYEN:
case AArch64::CPYEWT:
case AArch64::CPYEWTWN:
case AArch64::CPYEWTRN:
case AArch64::CPYEWTN:
case AArch64::CPYERT:
case AArch64::CPYERTWN:
case AArch64::CPYERTRN:
case AArch64::CPYERTN:
case AArch64::CPYET:
case AArch64::CPYETWN:
case AArch64::CPYETRN:
case AArch64::CPYETN: {
unsigned Xd_wb = Inst.getOperand(0).getReg();
unsigned Xs_wb = Inst.getOperand(1).getReg();
unsigned Xn_wb = Inst.getOperand(2).getReg();
unsigned Xd = Inst.getOperand(3).getReg();
unsigned Xs = Inst.getOperand(4).getReg();
unsigned Xn = Inst.getOperand(5).getReg();
if (Xd_wb != Xd)
return Error(Loc[0],
"invalid CPY instruction, Xd_wb and Xd do not match");
if (Xs_wb != Xs)
return Error(Loc[0],
"invalid CPY instruction, Xs_wb and Xs do not match");
if (Xn_wb != Xn)
return Error(Loc[0],
"invalid CPY instruction, Xn_wb and Xn do not match");
if (Xd == Xs)
return Error(Loc[0], "invalid CPY instruction, destination and source"
" registers are the same");
if (Xd == Xn)
return Error(Loc[0], "invalid CPY instruction, destination and size"
" registers are the same");
if (Xs == Xn)
return Error(Loc[0], "invalid CPY instruction, source and size"
" registers are the same");
break;
}
case AArch64::SETP:
case AArch64::SETPT:
case AArch64::SETPN:
case AArch64::SETPTN:
case AArch64::SETM:
case AArch64::SETMT:
case AArch64::SETMN:
case AArch64::SETMTN:
case AArch64::SETE:
case AArch64::SETET:
case AArch64::SETEN:
case AArch64::SETETN:
case AArch64::SETGP:
case AArch64::SETGPT:
case AArch64::SETGPN:
case AArch64::SETGPTN:
case AArch64::SETGM:
case AArch64::SETGMT:
case AArch64::SETGMN:
case AArch64::SETGMTN:
case AArch64::MOPSSETGE:
case AArch64::MOPSSETGET:
case AArch64::MOPSSETGEN:
case AArch64::MOPSSETGETN: {
unsigned Xd_wb = Inst.getOperand(0).getReg();
unsigned Xn_wb = Inst.getOperand(1).getReg();
unsigned Xd = Inst.getOperand(2).getReg();
unsigned Xn = Inst.getOperand(3).getReg();
unsigned Xm = Inst.getOperand(4).getReg();
if (Xd_wb != Xd)
return Error(Loc[0],
"invalid SET instruction, Xd_wb and Xd do not match");
if (Xn_wb != Xn)
return Error(Loc[0],
"invalid SET instruction, Xn_wb and Xn do not match");
if (Xd == Xn)
return Error(Loc[0], "invalid SET instruction, destination and size"
" registers are the same");
if (Xd == Xm)
return Error(Loc[0], "invalid SET instruction, destination and source"
" registers are the same");
if (Xn == Xm)
return Error(Loc[0], "invalid SET instruction, source and size"
" registers are the same");
break;
}
}
// Now check immediate ranges. Separate from the above as there is overlap
// in the instructions being checked and this keeps the nested conditionals

View File

@ -238,6 +238,12 @@ static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder);
static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder);
static bool Check(DecodeStatus &Out, DecodeStatus In) {
switch (In) {
@ -1842,3 +1848,52 @@ static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
}
return Fail;
}
static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
unsigned Rd = fieldFromInstruction(insn, 0, 5);
unsigned Rs = fieldFromInstruction(insn, 16, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
// None of the registers may alias: if they do, then the instruction is not
// merely unpredictable but actually entirely unallocated.
if (Rd == Rs || Rs == Rn || Rd == Rn)
return MCDisassembler::Fail;
// All three register operands are written back, so they all appear
// twice in the operand list, once as outputs and once as inputs.
if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
!DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
!DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
!DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
!DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder))
return MCDisassembler::Fail;
return MCDisassembler::Success;
}
static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
uint64_t Addr,
const void *Decoder) {
unsigned Rd = fieldFromInstruction(insn, 0, 5);
unsigned Rm = fieldFromInstruction(insn, 16, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
// None of the registers may alias: if they do, then the instruction is not
// merely unpredictable but actually entirely unallocated.
if (Rd == Rm || Rm == Rn || Rd == Rn)
return MCDisassembler::Fail;
// Rd and Rn (not Rm) register operands are written back, so they appear
// twice in the operand list, once as outputs and once as inputs.
if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
!DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
!DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
!DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder))
return MCDisassembler::Fail;
return MCDisassembler::Success;
}

View File

@ -0,0 +1,654 @@
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+mops,+mte < %s 2> %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MTE
// RUN: FileCheck --check-prefix=CHECK-ERROR %s < %t
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.8a,+mte < %s 2> %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MTE
// RUN: FileCheck --check-prefix=CHECK-ERROR %s < %t
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+mops < %s 2> %t | FileCheck %s --check-prefix=CHECK
// RUN: FileCheck --check-prefix=CHECK-NO-MTE-ERR %s < %t
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.8a < %s 2> %t | FileCheck %s --check-prefix=CHECK
// RUN: FileCheck --check-prefix=CHECK-NO-MTE-ERR %s < %t
// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-NO-MOPS-ERR --check-prefix=CHECK-NO-MOPSMTE-ERR %s < %t
// CHECK: [0x40,0x04,0x01,0x19]
// CHECK-NEXT: [0x40,0x44,0x01,0x19]
// CHECK-NEXT: [0x40,0x84,0x01,0x19]
// CHECK-NEXT: [0x40,0xc4,0x01,0x19]
// CHECK-NEXT: [0x40,0x14,0x01,0x19]
// CHECK-NEXT: [0x40,0x54,0x01,0x19]
// CHECK-NEXT: [0x40,0x94,0x01,0x19]
// CHECK-NEXT: [0x40,0xd4,0x01,0x19]
// CHECK-NEXT: [0x40,0x24,0x01,0x19]
// CHECK-NEXT: [0x40,0x64,0x01,0x19]
// CHECK-NEXT: [0x40,0xa4,0x01,0x19]
// CHECK-NEXT: [0x40,0xe4,0x01,0x19]
// CHECK-NEXT: [0x40,0x34,0x01,0x19]
// CHECK-NEXT: [0x40,0x74,0x01,0x19]
// CHECK-NEXT: [0x40,0xb4,0x01,0x19]
// CHECK-NEXT: [0x40,0xf4,0x01,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpyfp [x0]!, [x1]!, x2!
cpyfpwn [x0]!, [x1]!, x2!
cpyfprn [x0]!, [x1]!, x2!
cpyfpn [x0]!, [x1]!, x2!
cpyfpwt [x0]!, [x1]!, x2!
cpyfpwtwn [x0]!, [x1]!, x2!
cpyfpwtrn [x0]!, [x1]!, x2!
cpyfpwtn [x0]!, [x1]!, x2!
cpyfprt [x0]!, [x1]!, x2!
cpyfprtwn [x0]!, [x1]!, x2!
cpyfprtrn [x0]!, [x1]!, x2!
cpyfprtn [x0]!, [x1]!, x2!
cpyfpt [x0]!, [x1]!, x2!
cpyfptwn [x0]!, [x1]!, x2!
cpyfptrn [x0]!, [x1]!, x2!
cpyfptn [x0]!, [x1]!, x2!
// CHECK: [0x40,0x04,0x41,0x19]
// CHECK-NEXT: [0x40,0x44,0x41,0x19]
// CHECK-NEXT: [0x40,0x84,0x41,0x19]
// CHECK-NEXT: [0x40,0xc4,0x41,0x19]
// CHECK-NEXT: [0x40,0x14,0x41,0x19]
// CHECK-NEXT: [0x40,0x54,0x41,0x19]
// CHECK-NEXT: [0x40,0x94,0x41,0x19]
// CHECK-NEXT: [0x40,0xd4,0x41,0x19]
// CHECK-NEXT: [0x40,0x24,0x41,0x19]
// CHECK-NEXT: [0x40,0x64,0x41,0x19]
// CHECK-NEXT: [0x40,0xa4,0x41,0x19]
// CHECK-NEXT: [0x40,0xe4,0x41,0x19]
// CHECK-NEXT: [0x40,0x34,0x41,0x19]
// CHECK-NEXT: [0x40,0x74,0x41,0x19]
// CHECK-NEXT: [0x40,0xb4,0x41,0x19]
// CHECK-NEXT: [0x40,0xf4,0x41,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpyfm [x0]!, [x1]!, x2!
cpyfmwn [x0]!, [x1]!, x2!
cpyfmrn [x0]!, [x1]!, x2!
cpyfmn [x0]!, [x1]!, x2!
cpyfmwt [x0]!, [x1]!, x2!
cpyfmwtwn [x0]!, [x1]!, x2!
cpyfmwtrn [x0]!, [x1]!, x2!
cpyfmwtn [x0]!, [x1]!, x2!
cpyfmrt [x0]!, [x1]!, x2!
cpyfmrtwn [x0]!, [x1]!, x2!
cpyfmrtrn [x0]!, [x1]!, x2!
cpyfmrtn [x0]!, [x1]!, x2!
cpyfmt [x0]!, [x1]!, x2!
cpyfmtwn [x0]!, [x1]!, x2!
cpyfmtrn [x0]!, [x1]!, x2!
cpyfmtn [x0]!, [x1]!, x2!
// CHECK: [0x40,0x04,0x81,0x19]
// CHECK-NEXT: [0x40,0x44,0x81,0x19]
// CHECK-NEXT: [0x40,0x84,0x81,0x19]
// CHECK-NEXT: [0x40,0xc4,0x81,0x19]
// CHECK-NEXT: [0x40,0x14,0x81,0x19]
// CHECK-NEXT: [0x40,0x54,0x81,0x19]
// CHECK-NEXT: [0x40,0x94,0x81,0x19]
// CHECK-NEXT: [0x40,0xd4,0x81,0x19]
// CHECK-NEXT: [0x40,0x24,0x81,0x19]
// CHECK-NEXT: [0x40,0x64,0x81,0x19]
// CHECK-NEXT: [0x40,0xa4,0x81,0x19]
// CHECK-NEXT: [0x40,0xe4,0x81,0x19]
// CHECK-NEXT: [0x40,0x34,0x81,0x19]
// CHECK-NEXT: [0x40,0x74,0x81,0x19]
// CHECK-NEXT: [0x40,0xb4,0x81,0x19]
// CHECK-NEXT: [0x40,0xf4,0x81,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpyfe [x0]!, [x1]!, x2!
cpyfewn [x0]!, [x1]!, x2!
cpyfern [x0]!, [x1]!, x2!
cpyfen [x0]!, [x1]!, x2!
cpyfewt [x0]!, [x1]!, x2!
cpyfewtwn [x0]!, [x1]!, x2!
cpyfewtrn [x0]!, [x1]!, x2!
cpyfewtn [x0]!, [x1]!, x2!
cpyfert [x0]!, [x1]!, x2!
cpyfertwn [x0]!, [x1]!, x2!
cpyfertrn [x0]!, [x1]!, x2!
cpyfertn [x0]!, [x1]!, x2!
cpyfet [x0]!, [x1]!, x2!
cpyfetwn [x0]!, [x1]!, x2!
cpyfetrn [x0]!, [x1]!, x2!
cpyfetn [x0]!, [x1]!, x2!
// CHECK: [0x40,0x04,0x01,0x1d]
// CHECK-NEXT: [0x40,0x44,0x01,0x1d]
// CHECK-NEXT: [0x40,0x84,0x01,0x1d]
// CHECK-NEXT: [0x40,0xc4,0x01,0x1d]
// CHECK-NEXT: [0x40,0x14,0x01,0x1d]
// CHECK-NEXT: [0x40,0x54,0x01,0x1d]
// CHECK-NEXT: [0x40,0x94,0x01,0x1d]
// CHECK-NEXT: [0x40,0xd4,0x01,0x1d]
// CHECK-NEXT: [0x40,0x24,0x01,0x1d]
// CHECK-NEXT: [0x40,0x64,0x01,0x1d]
// CHECK-NEXT: [0x40,0xa4,0x01,0x1d]
// CHECK-NEXT: [0x40,0xe4,0x01,0x1d]
// CHECK-NEXT: [0x40,0x34,0x01,0x1d]
// CHECK-NEXT: [0x40,0x74,0x01,0x1d]
// CHECK-NEXT: [0x40,0xb4,0x01,0x1d]
// CHECK-NEXT: [0x40,0xf4,0x01,0x1d]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpyp [x0]!, [x1]!, x2!
cpypwn [x0]!, [x1]!, x2!
cpyprn [x0]!, [x1]!, x2!
cpypn [x0]!, [x1]!, x2!
cpypwt [x0]!, [x1]!, x2!
cpypwtwn [x0]!, [x1]!, x2!
cpypwtrn [x0]!, [x1]!, x2!
cpypwtn [x0]!, [x1]!, x2!
cpyprt [x0]!, [x1]!, x2!
cpyprtwn [x0]!, [x1]!, x2!
cpyprtrn [x0]!, [x1]!, x2!
cpyprtn [x0]!, [x1]!, x2!
cpypt [x0]!, [x1]!, x2!
cpyptwn [x0]!, [x1]!, x2!
cpyptrn [x0]!, [x1]!, x2!
cpyptn [x0]!, [x1]!, x2!
// CHECK: [0x40,0x04,0x41,0x1d]
// CHECK-NEXT: [0x40,0x44,0x41,0x1d]
// CHECK-NEXT: [0x40,0x84,0x41,0x1d]
// CHECK-NEXT: [0x40,0xc4,0x41,0x1d]
// CHECK-NEXT: [0x40,0x14,0x41,0x1d]
// CHECK-NEXT: [0x40,0x54,0x41,0x1d]
// CHECK-NEXT: [0x40,0x94,0x41,0x1d]
// CHECK-NEXT: [0x40,0xd4,0x41,0x1d]
// CHECK-NEXT: [0x40,0x24,0x41,0x1d]
// CHECK-NEXT: [0x40,0x64,0x41,0x1d]
// CHECK-NEXT: [0x40,0xa4,0x41,0x1d]
// CHECK-NEXT: [0x40,0xe4,0x41,0x1d]
// CHECK-NEXT: [0x40,0x34,0x41,0x1d]
// CHECK-NEXT: [0x40,0x74,0x41,0x1d]
// CHECK-NEXT: [0x40,0xb4,0x41,0x1d]
// CHECK-NEXT: [0x40,0xf4,0x41,0x1d]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpym [x0]!, [x1]!, x2!
cpymwn [x0]!, [x1]!, x2!
cpymrn [x0]!, [x1]!, x2!
cpymn [x0]!, [x1]!, x2!
cpymwt [x0]!, [x1]!, x2!
cpymwtwn [x0]!, [x1]!, x2!
cpymwtrn [x0]!, [x1]!, x2!
cpymwtn [x0]!, [x1]!, x2!
cpymrt [x0]!, [x1]!, x2!
cpymrtwn [x0]!, [x1]!, x2!
cpymrtrn [x0]!, [x1]!, x2!
cpymrtn [x0]!, [x1]!, x2!
cpymt [x0]!, [x1]!, x2!
cpymtwn [x0]!, [x1]!, x2!
cpymtrn [x0]!, [x1]!, x2!
cpymtn [x0]!, [x1]!, x2!
// CHECK: [0x40,0x04,0x81,0x1d]
// CHECK-NEXT: [0x40,0x44,0x81,0x1d]
// CHECK-NEXT: [0x40,0x84,0x81,0x1d]
// CHECK-NEXT: [0x40,0xc4,0x81,0x1d]
// CHECK-NEXT: [0x40,0x14,0x81,0x1d]
// CHECK-NEXT: [0x40,0x54,0x81,0x1d]
// CHECK-NEXT: [0x40,0x94,0x81,0x1d]
// CHECK-NEXT: [0x40,0xd4,0x81,0x1d]
// CHECK-NEXT: [0x40,0x24,0x81,0x1d]
// CHECK-NEXT: [0x40,0x64,0x81,0x1d]
// CHECK-NEXT: [0x40,0xa4,0x81,0x1d]
// CHECK-NEXT: [0x40,0xe4,0x81,0x1d]
// CHECK-NEXT: [0x40,0x34,0x81,0x1d]
// CHECK-NEXT: [0x40,0x74,0x81,0x1d]
// CHECK-NEXT: [0x40,0xb4,0x81,0x1d]
// CHECK-NEXT: [0x40,0xf4,0x81,0x1d]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
cpye [x0]!, [x1]!, x2!
cpyewn [x0]!, [x1]!, x2!
cpyern [x0]!, [x1]!, x2!
cpyen [x0]!, [x1]!, x2!
cpyewt [x0]!, [x1]!, x2!
cpyewtwn [x0]!, [x1]!, x2!
cpyewtrn [x0]!, [x1]!, x2!
cpyewtn [x0]!, [x1]!, x2!
cpyert [x0]!, [x1]!, x2!
cpyertwn [x0]!, [x1]!, x2!
cpyertrn [x0]!, [x1]!, x2!
cpyertn [x0]!, [x1]!, x2!
cpyet [x0]!, [x1]!, x2!
cpyetwn [x0]!, [x1]!, x2!
cpyetrn [x0]!, [x1]!, x2!
cpyetn [x0]!, [x1]!, x2!
// CHECK: [0x20,0x04,0xc2,0x19]
// CHECK-NEXT: [0x20,0x14,0xc2,0x19]
// CHECK-NEXT: [0x20,0x24,0xc2,0x19]
// CHECK-NEXT: [0x20,0x34,0xc2,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
setp [x0]!, x1!, x2
setpt [x0]!, x1!, x2
setpn [x0]!, x1!, x2
setptn [x0]!, x1!, x2
// CHECK: [0x20,0x44,0xc2,0x19]
// CHECK: [0x20,0x54,0xc2,0x19]
// CHECK: [0x20,0x64,0xc2,0x19]
// CHECK: [0x20,0x74,0xc2,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
setm [x0]!, x1!, x2
setmt [x0]!, x1!, x2
setmn [x0]!, x1!, x2
setmtn [x0]!, x1!, x2
// CHECK: [0x20,0x84,0xc2,0x19]
// CHECK: [0x20,0x94,0xc2,0x19]
// CHECK: [0x20,0xa4,0xc2,0x19]
// CHECK: [0x20,0xb4,0xc2,0x19]
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
// CHECK-NO-MOPS-ERR: error: instruction requires: mops
sete [x0]!, x1!, x2
setet [x0]!, x1!, x2
seten [x0]!, x1!, x2
setetn [x0]!, x1!, x2
// CHECK-MTE: [0x20,0x04,0xc2,0x1d]
// CHECK-MTE: [0x20,0x14,0xc2,0x1d]
// CHECK-MTE: [0x20,0x24,0xc2,0x1d]
// CHECK-MTE: [0x20,0x34,0xc2,0x1d]
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
setgp [x0]!, x1!, x2
setgpt [x0]!, x1!, x2
setgpn [x0]!, x1!, x2
setgptn [x0]!, x1!, x2
// CHECK-MTE: [0x20,0x44,0xc2,0x1d]
// CHECK-MTE: [0x20,0x54,0xc2,0x1d]
// CHECK-MTE: [0x20,0x64,0xc2,0x1d]
// CHECK-MTE: [0x20,0x74,0xc2,0x1d]
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
setgm [x0]!, x1!, x2
setgmt [x0]!, x1!, x2
setgmn [x0]!, x1!, x2
setgmtn [x0]!, x1!, x2
// CHECK-MTE: [0x20,0x84,0xc2,0x1d]
// CHECK-MTE: [0x20,0x94,0xc2,0x1d]
// CHECK-MTE: [0x20,0xa4,0xc2,0x1d]
// CHECK-MTE: [0x20,0xb4,0xc2,0x1d]
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MTE-ERR: error: instruction requires: mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
// CHECK-NO-MOPSMTE-ERR: error: instruction requires: mops mte
setge [x0]!, x1!, x2
setget [x0]!, x1!, x2
setgen [x0]!, x1!, x2
setgetn [x0]!, x1!, x2
// All operand must be different from each other
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpyfp [x0]!, [x0]!, x1!
cpyfp [x0]!, [x1]!, x0!
cpyfp [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpyfm [x0]!, [x0]!, x1!
cpyfm [x0]!, [x1]!, x0!
cpyfm [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpyfe [x0]!, [x0]!, x1!
cpyfe [x0]!, [x1]!, x0!
cpyfe [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpyp [x0]!, [x0]!, x1!
cpyp [x0]!, [x1]!, x0!
cpyp [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpym [x0]!, [x0]!, x1!
cpym [x0]!, [x1]!, x0!
cpym [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid CPY instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid CPY instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid CPY instruction, source and size registers are the same
cpye [x0]!, [x0]!, x1!
cpye [x0]!, [x1]!, x0!
cpye [x1]!, [x0]!, x0!
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
setp [x0]!, x0!, x1
setp [x0]!, x1!, x0
setp [x1]!, x0!, x0
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
setm [x0]!, x0!, x1
setm [x0]!, x1!, x0
setm [x1]!, x0!, x0
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
sete [x0]!, x0!, x1
sete [x0]!, x1!, x0
sete [x1]!, x0!, x0
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
setgp [x0]!, x0!, x1
setgp [x0]!, x1!, x0
setgp [x1]!, x0!, x0
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
setgm [x0]!, x0!, x1
setgm [x0]!, x1!, x0
setgm [x1]!, x0!, x0
// CHECK-ERROR: error: invalid SET instruction, destination and size registers are the same
// CHECK-ERROR: error: invalid SET instruction, destination and source registers are the same
// CHECK-ERROR: error: invalid SET instruction, source and size registers are the same
setge [x0]!, x0!, x1
setge [x0]!, x1!, x0
setge [x1]!, x0!, x0
// SP cannot be used as argument at any position
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpyfp [sp]!, [x1]!, x2!
cpyfp [x0]!, [sp]!, x2!
cpyfp [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpyfm [sp]!, [x1]!, x2!
cpyfm [x0]!, [sp]!, x2!
cpyfm [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpyfe [sp]!, [x1]!, x2!
cpyfe [x0]!, [sp]!, x2!
cpyfe [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpyp [sp]!, [x2]!, x2!
cpyp [x0]!, [sp]!, x2!
cpyp [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpym [sp]!, [x2]!, x2!
cpym [x0]!, [sp]!, x2!
cpym [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
cpye [sp]!, [x2]!, x2!
cpye [x0]!, [sp]!, x2!
cpye [x0]!, [x1]!, sp!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
setp [sp]!, x1!, x2
setp [x0]!, sp!, x2
setp [x0]!, x1!, sp
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
setm [sp]!, x1!, x2
setm [x0]!, sp!, x2
setm [x0]!, x1!, sp
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
sete [sp]!, x1!, x2
sete [x0]!, sp!, x2
sete [x0]!, x1!, sp
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
setgp [sp]!, x1!, x2
setgp [x0]!, sp!, x2
setgp [x0]!, x1!, sp
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
setgm [sp]!, x1!, x2
setgm [x0]!, sp!, x2
setgm [x0]!, x1!, sp
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
setge [sp]!, x1!, x2
setge [x0]!, sp!, x2
setge [x0]!, x1!, sp
// XZR can only be used at:
// - the size operand in CPY.
// - the size or source operands in SET.
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpyfp [x0]!, [x1]!, xzr!
cpyfp [xzr]!, [x1]!, x2!
cpyfp [x0]!, [xzr]!, x2!
cpyfp [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpyfm [x0]!, [x1]!, xzr!
cpyfm [xzr]!, [x1]!, x2!
cpyfm [x0]!, [xzr]!, x2!
cpyfm [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpyfe [x0]!, [x1]!, xzr!
cpyfe [xzr]!, [x1]!, x2!
cpyfe [x0]!, [xzr]!, x2!
cpyfe [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpyp [x0]!, [x1]!, xzr!
cpyp [xzr]!, [x2]!, x2!
cpyp [x0]!, [xzr]!, x2!
cpyp [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpym [x0]!, [x1]!, xzr!
cpym [xzr]!, [x2]!, x2!
cpym [x0]!, [xzr]!, x2!
cpym [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: cpye [x0]!, [x1]!, xzr!
cpye [xzr]!, [x2]!, x2!
cpye [x0]!, [xzr]!, x2!
cpye [x0]!, [x1]!, xzr!
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: setp [x0]!, xzr!, x2
// CHECK: setp [x0]!, x1!, xzr
setp [xzr]!, x1!, x2
setp [x0]!, xzr!, x2
setp [x0]!, x1!, xzr
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: setm [x0]!, xzr!, x2
// CHECK: setm [x0]!, x1!, xzr
setm [xzr]!, x1!, x2
setm [x0]!, xzr!, x2
setm [x0]!, x1!, xzr
// CHECK-ERROR: error: invalid operand for instruction
// CHECK: sete [x0]!, xzr!, x2
// CHECK: sete [x0]!, x1!, xzr
sete [xzr]!, x1!, x2
sete [x0]!, xzr!, x2
sete [x0]!, x1!, xzr
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-MTE: setgp [x0]!, xzr!, x2
// CHECK-MTE: setgp [x0]!, x1!, xzr
setgp [xzr]!, x1!, x2
setgp [x0]!, xzr!, x2
setgp [x0]!, x1!, xzr
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-MTE: setgm [x0]!, xzr!, x2
// CHECK-MTE: setgm [x0]!, x1!, xzr
setgm [xzr]!, x1!, x2
setgm [x0]!, xzr!, x2
setgm [x0]!, x1!, xzr
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-MTE: setge [x0]!, xzr!, x2
// CHECK-MTE: setge [x0]!, x1!, xzr
setge [xzr]!, x1!, x2
setge [x0]!, xzr!, x2
setge [x0]!, x1!, xzr

View File

@ -0,0 +1,434 @@
# RUN: not llvm-mc -triple aarch64-arm-none-eabi -mattr=+mops,+mte -disassemble < %s 2> %t | FileCheck %s --check-prefixes=CHECK-MOPS,CHECK-MTE
# RUN: FileCheck %s --check-prefix=CHECK-INVALID < %t
# RUN: not llvm-mc -triple aarch64-arm-none-eabi -mattr=+v8.8a,+mte -disassemble < %s 2> %t | FileCheck %s --check-prefixes=CHECK-MOPS,CHECK-MTE
# RUN: FileCheck %s --check-prefix=CHECK-INVALID < %t
# RUN: not llvm-mc -triple aarch64-arm-none-eabi -mattr=+mops -disassemble < %s 2> %t | FileCheck %s --check-prefix=CHECK-MOPS
# RUN: FileCheck %s --check-prefixes=CHECK-INVALID,CHECK-NO-MTE < %t
# RUN: not llvm-mc -triple aarch64-arm-none-eabi -mattr=+v8.8a -disassemble < %s 2> %t | FileCheck %s --check-prefix=CHECK-MOPS
# RUN: FileCheck %s --check-prefixes=CHECK-INVALID,CHECK-NO-MTE < %t
# RUN: not llvm-mc -triple aarch64-arm-none-eabi -disassemble < %s 2> %t
# RUN: FileCheck %s --check-prefixes=CHECK-INVALID,CHECK-NO-MOPS,CHECK-NO-MTE < %t
[0x40,0x04,0x01,0x19]
[0x40,0x44,0x01,0x19]
[0x40,0x84,0x01,0x19]
[0x40,0xc4,0x01,0x19]
[0x40,0x14,0x01,0x19]
[0x40,0x54,0x01,0x19]
[0x40,0x94,0x01,0x19]
[0x40,0xd4,0x01,0x19]
[0x40,0x24,0x01,0x19]
[0x40,0x64,0x01,0x19]
[0x40,0xa4,0x01,0x19]
[0x40,0xe4,0x01,0x19]
[0x40,0x34,0x01,0x19]
[0x40,0x74,0x01,0x19]
[0x40,0xb4,0x01,0x19]
[0x40,0xf4,0x01,0x19]
# CHECK-MOPS: cpyfp [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfprn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpwt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpwtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpwtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpwtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfprt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfprtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfprtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfprtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfpt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfptwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfptrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfptn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x40,0x04,0x41,0x19]
[0x40,0x44,0x41,0x19]
[0x40,0x84,0x41,0x19]
[0x40,0xc4,0x41,0x19]
[0x40,0x14,0x41,0x19]
[0x40,0x54,0x41,0x19]
[0x40,0x94,0x41,0x19]
[0x40,0xd4,0x41,0x19]
[0x40,0x24,0x41,0x19]
[0x40,0x64,0x41,0x19]
[0x40,0xa4,0x41,0x19]
[0x40,0xe4,0x41,0x19]
[0x40,0x34,0x41,0x19]
[0x40,0x74,0x41,0x19]
[0x40,0xb4,0x41,0x19]
[0x40,0xf4,0x41,0x19]
# CHECK-MOPS: cpyfm [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmwt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmwtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmwtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmwtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmrt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmrtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmrtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmrtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfmtn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x40,0x04,0x81,0x19]
[0x40,0x44,0x81,0x19]
[0x40,0x84,0x81,0x19]
[0x40,0xc4,0x81,0x19]
[0x40,0x14,0x81,0x19]
[0x40,0x54,0x81,0x19]
[0x40,0x94,0x81,0x19]
[0x40,0xd4,0x81,0x19]
[0x40,0x24,0x81,0x19]
[0x40,0x64,0x81,0x19]
[0x40,0xa4,0x81,0x19]
[0x40,0xe4,0x81,0x19]
[0x40,0x34,0x81,0x19]
[0x40,0x74,0x81,0x19]
[0x40,0xb4,0x81,0x19]
[0x40,0xf4,0x81,0x19]
# CHECK-MOPS: cpyfe [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfewn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfern [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfen [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfewt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfewtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfewtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfewtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfert [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfertwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfertrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfertn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfet [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfetwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfetrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyfetn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x40,0x04,0x01,0x1d]
[0x40,0x44,0x01,0x1d]
[0x40,0x84,0x01,0x1d]
[0x40,0xc4,0x01,0x1d]
[0x40,0x14,0x01,0x1d]
[0x40,0x54,0x01,0x1d]
[0x40,0x94,0x01,0x1d]
[0x40,0xd4,0x01,0x1d]
[0x40,0x24,0x01,0x1d]
[0x40,0x64,0x01,0x1d]
[0x40,0xa4,0x01,0x1d]
[0x40,0xe4,0x01,0x1d]
[0x40,0x34,0x01,0x1d]
[0x40,0x74,0x01,0x1d]
[0x40,0xb4,0x01,0x1d]
[0x40,0xf4,0x01,0x1d]
# CHECK-MOPS: cpyp [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyprn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypwt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypwtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypwtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypwtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyprt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyprtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyprtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyprtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpypt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyptwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyptrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyptn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x40,0x04,0x41,0x1d]
[0x40,0x44,0x41,0x1d]
[0x40,0x84,0x41,0x1d]
[0x40,0xc4,0x41,0x1d]
[0x40,0x14,0x41,0x1d]
[0x40,0x54,0x41,0x1d]
[0x40,0x94,0x41,0x1d]
[0x40,0xd4,0x41,0x1d]
[0x40,0x24,0x41,0x1d]
[0x40,0x64,0x41,0x1d]
[0x40,0xa4,0x41,0x1d]
[0x40,0xe4,0x41,0x1d]
[0x40,0x34,0x41,0x1d]
[0x40,0x74,0x41,0x1d]
[0x40,0xb4,0x41,0x1d]
[0x40,0xf4,0x41,0x1d]
# CHECK-MOPS: cpym [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymwt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymwtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymwtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymwtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymrt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymrtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymrtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymrtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpymtn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x40,0x04,0x81,0x1d]
[0x40,0x44,0x81,0x1d]
[0x40,0x84,0x81,0x1d]
[0x40,0xc4,0x81,0x1d]
[0x40,0x14,0x81,0x1d]
[0x40,0x54,0x81,0x1d]
[0x40,0x94,0x81,0x1d]
[0x40,0xd4,0x81,0x1d]
[0x40,0x24,0x81,0x1d]
[0x40,0x64,0x81,0x1d]
[0x40,0xa4,0x81,0x1d]
[0x40,0xe4,0x81,0x1d]
[0x40,0x34,0x81,0x1d]
[0x40,0x74,0x81,0x1d]
[0x40,0xb4,0x81,0x1d]
[0x40,0xf4,0x81,0x1d]
# CHECK-MOPS: cpye [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyewn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyern [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyen [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyewt [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyewtwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyewtrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyewtn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyert [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyertwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyertrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyertn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyet [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyetwn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyetrn [x0]!, [x1]!, x2!
# CHECK-MOPS: cpyetn [x0]!, [x1]!, x2!
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x20,0x04,0xc2,0x19]
[0x20,0x14,0xc2,0x19]
[0x20,0x24,0xc2,0x19]
[0x20,0x34,0xc2,0x19]
# CHECK-MOPS: setp [x0]!, x1!, x2
# CHECK-MOPS: setpt [x0]!, x1!, x2
# CHECK-MOPS: setpn [x0]!, x1!, x2
# CHECK-MOPS: setptn [x0]!, x1!, x2
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x20,0x44,0xc2,0x19]
[0x20,0x54,0xc2,0x19]
[0x20,0x64,0xc2,0x19]
[0x20,0x74,0xc2,0x19]
# CHECK-MOPS: setm [x0]!, x1!, x2
# CHECK-MOPS: setmt [x0]!, x1!, x2
# CHECK-MOPS: setmn [x0]!, x1!, x2
# CHECK-MOPS: setmtn [x0]!, x1!, x2
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x20,0x84,0xc2,0x19]
[0x20,0x94,0xc2,0x19]
[0x20,0xa4,0xc2,0x19]
[0x20,0xb4,0xc2,0x19]
# CHECK-MOPS: sete [x0]!, x1!, x2
# CHECK-MOPS: setet [x0]!, x1!, x2
# CHECK-MOPS: seten [x0]!, x1!, x2
# CHECK-MOPS: setetn [x0]!, x1!, x2
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
# CHECK-NO-MOPS: warning: invalid instruction encoding
[0x20,0x04,0xc2,0x1d]
[0x20,0x14,0xc2,0x1d]
[0x20,0x24,0xc2,0x1d]
[0x20,0x34,0xc2,0x1d]
# CHECK-MTE: setgp [x0]!, x1!, x2
# CHECK-MTE: setgpt [x0]!, x1!, x2
# CHECK-MTE: setgpn [x0]!, x1!, x2
# CHECK-MTE: setgptn [x0]!, x1!, x2
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
[0x20,0x44,0xc2,0x1d]
[0x20,0x54,0xc2,0x1d]
[0x20,0x64,0xc2,0x1d]
[0x20,0x74,0xc2,0x1d]
# CHECK-MTE: setgm [x0]!, x1!, x2
# CHECK-MTE: setgmt [x0]!, x1!, x2
# CHECK-MTE: setgmn [x0]!, x1!, x2
# CHECK-MTE: setgmtn [x0]!, x1!, x2
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
[0x20,0x84,0xc2,0x1d]
[0x20,0x94,0xc2,0x1d]
[0x20,0xa4,0xc2,0x1d]
[0x20,0xb4,0xc2,0x1d]
# CHECK-MTE: setge [x0]!, x1!, x2
# CHECK-MTE: setget [x0]!, x1!, x2
# CHECK-MTE: setgen [x0]!, x1!, x2
# CHECK-MTE: setgetn [x0]!, x1!, x2
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# CHECK-NO-MTE: warning: invalid instruction encoding
# Register number 31 (SP or XZR) is not allowed in address positions.
# cpyfp
[0x5f,0x04,0x01,0x19]
[0x40,0x04,0x1f,0x19]
# cpyfm
[0x5f,0x04,0x41,0x19]
[0x40,0x04,0x5f,0x19]
# cpyfe
[0x5f,0x04,0x81,0x19]
[0x40,0x04,0x9f,0x19]
# cpyp
[0x5f,0x04,0x01,0x1d]
[0x40,0x04,0x1f,0x1d]
# cpym
[0x5f,0x04,0x41,0x1d]
[0x40,0x04,0x5f,0x1d]
# cpye
[0x5f,0x04,0x81,0x1d]
[0x40,0x04,0x9f,0x1d]
# setp
[0x5f,0x04,0xc2,0x19]
# setm
[0x5f,0x44,0xc2,0x19]
# sete
[0x5f,0x84,0xc2,0x19]
# setgp
[0x5f,0x04,0xc2,0x1d]
# setgm
[0x5f,0x44,0xc2,0x1d]
# setge
[0x5f,0x84,0xc2,0x1d]
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding
# CHECK-INVALID: warning: invalid instruction encoding