diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -419,6 +419,9 @@ 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_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", diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -11430,6 +11430,125 @@ let Inst{20-16} = Rs; } +class MOPSMemoryCopyMoveBase 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 hasSideEffects = 1; + let mayLoad = 1; + let mayStore = 1; +} + +class MOPSMemoryCopy opcode, bits<2> op1, bits<2> op2, string asm> + : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; + +class MOPSMemoryMove opcode, bits<2> op1, bits<2> op2, string asm> + : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; + +class MOPSMemorySetBase 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 hasSideEffects = 1; + let mayLoad = 0; + let mayStore = 1; +} + +class MOPSMemorySet opcode, bit op1, bit op2, string asm> + : MOPSMemorySetBase<0, opcode, op1, op2, asm>; + +class MOPSMemorySetTagging opcode, bit op1, bit op2, string asm> + : MOPSMemorySetBase<1, opcode, op1, op2, asm>; + +multiclass MOPSMemoryCopyInsns opcode, string asm> { + def "" : MOPSMemoryCopy; + def WN : MOPSMemoryCopy; + def RN : MOPSMemoryCopy; + def N : MOPSMemoryCopy; + def WT : MOPSMemoryCopy; + def WTWN : MOPSMemoryCopy; + def WTRN : MOPSMemoryCopy; + def WTN : MOPSMemoryCopy; + def RT : MOPSMemoryCopy; + def RTWN : MOPSMemoryCopy; + def RTRN : MOPSMemoryCopy; + def RTN : MOPSMemoryCopy; + def T : MOPSMemoryCopy; + def TWN : MOPSMemoryCopy; + def TRN : MOPSMemoryCopy; + def TN : MOPSMemoryCopy; +} + +multiclass MOPSMemoryMoveInsns opcode, string asm> { + def "" : MOPSMemoryMove; + def WN : MOPSMemoryMove; + def RN : MOPSMemoryMove; + def N : MOPSMemoryMove; + def WT : MOPSMemoryMove; + def WTWN : MOPSMemoryMove; + def WTRN : MOPSMemoryMove; + def WTN : MOPSMemoryMove; + def RT : MOPSMemoryMove; + def RTWN : MOPSMemoryMove; + def RTRN : MOPSMemoryMove; + def RTN : MOPSMemoryMove; + def T : MOPSMemoryMove; + def TWN : MOPSMemoryMove; + def TRN : MOPSMemoryMove; + def TN : MOPSMemoryMove; +} + +multiclass MOPSMemorySetInsns opcode, string asm> { + def "" : MOPSMemorySet; + def T : MOPSMemorySet; + def N : MOPSMemorySet; + def TN : MOPSMemorySet; +} + +multiclass MOPSMemorySetTaggingInsns opcode, string asm> { + def "" : MOPSMemorySetTagging; + def T : MOPSMemorySetTagging; + def N : MOPSMemorySetTagging; + def TN : MOPSMemorySetTagging; +} + //---------------------------------------------------------------------------- // Allow the size specifier tokens to be upper case, not just lower. def : TokenAlias<".4B", ".4b">; // Add dot product diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -200,8 +200,10 @@ 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 @@ def : ST64BPattern; } +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), diff --git a/llvm/lib/Target/AArch64/AArch64SchedA57.td b/llvm/lib/Target/AArch64/AArch64SchedA57.td --- a/llvm/lib/Target/AArch64/AArch64SchedA57.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA57.td @@ -526,7 +526,7 @@ 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 diff --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td --- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td @@ -1891,7 +1891,7 @@ // 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 diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM3.td @@ -669,7 +669,7 @@ 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")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td @@ -810,7 +810,7 @@ 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")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM5.td @@ -848,7 +848,7 @@ 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")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td --- a/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td +++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td @@ -1499,7 +1499,7 @@ // 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 diff --git a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td --- a/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td +++ b/llvm/lib/Target/AArch64/AArch64SchedThunderX3T110.td @@ -1608,7 +1608,7 @@ // 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 diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -192,6 +192,7 @@ // Armv8.8-A Extensions bool HasHBC = false; + bool HasMOPS = false; // Arm SVE2 extensions bool HasSVE2 = false; @@ -579,6 +580,7 @@ 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; } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -4866,6 +4866,177 @@ } } + // 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 diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -238,6 +238,12 @@ 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 @@ } 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; +} \ No newline at end of file diff --git a/llvm/test/MC/AArch64/armv8.8a-mops.s b/llvm/test/MC/AArch64/armv8.8a-mops.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.8a-mops.s @@ -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 diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.8a-mops.txt b/llvm/test/MC/Disassembler/AArch64/armv8.8a-mops.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.8a-mops.txt @@ -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