diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 7f629a78fb442c..8516ab2c7dd71c 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1210,6 +1210,15 @@ def ZPRMul2AsmOp32_Hi : ZPRAsmOperand<"VectorS_Hi", 32, "Mul2_Hi">; def ZPRMul2AsmOp64_Lo : ZPRAsmOperand<"VectorD_Lo", 64, "Mul2_Lo">; def ZPRMul2AsmOp64_Hi : ZPRAsmOperand<"VectorD_Hi", 64, "Mul2_Hi">; +def ZPR_K : RegisterClass<"AArch64", [untyped], 128, + (add Z20, Z21, Z22, Z23, Z28, Z29, Z30, Z31)>; + +def ZK : RegisterOperand">{ + let EncoderMethod = "EncodeZK"; + let DecoderMethod = "DecodeZK"; + let ParserMatchClass = ZPRAsmOperand<"Vector_20to23or28to31", 0, "_K">; +} + def ZPR8Mul2_Lo : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Lo, 0, 14, ElementSizeB, ZPRMul2_Lo>; def ZPR8Mul2_Hi : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Hi, 16, 30, ElementSizeB, ZPRMul2_Hi>; def ZPR16Mul2_Lo : ZPRMul2_MinToMaxRegOp<"h", ZPRMul2AsmOp16_Lo, 0, 14, ElementSizeH, ZPRMul2_Lo>; diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td index 802797a14ee42d..6044b5bb7d8151 100644 --- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -1000,3 +1000,24 @@ defm FMOPA_MPPZZ_BtoS : sme_outer_product_fp32<0b0, 0b01, ZPR8, "fmopa", null_fr } //[HasSMEF8F32] +let Predicates = [HasSME2p2] in { + def FTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b11000, ZZ_h_mul_r, ZPR16, "ftmopa">; + def FTMOPA_M2ZZZI_StoS : sme_tmopa_32b<0b00000, ZZ_s_mul_r, ZPR32, "ftmopa">; + def BFTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b10000, ZZ_h_mul_r, ZPR16, "bftmopa">; +} // [HasSME2p2] + +let Predicates = [HasSME2p2, HasSMEB16B16] in { + def BFTMOPA_M2ZZZI_HtoH : sme_tmopa_16b<0b11001, ZZ_h_mul_r, ZPR16, "bftmopa">; +} // [HasSME2p2, HasSMEB16B16] + +let Predicates = [HasSME2p2, HasSMEF8F32], Uses = [FPMR, FPCR] in { + def FTMOPA_M2ZZZI_BtoS : sme_tmopa_32b<0b01000, ZZ_b_mul_r, ZPR8, "ftmopa">; +} // [HasSME2p2, HasSMEF8F32], Uses = [FPMR, FPCR] + +let Predicates = [HasSME2p2, HasSMEF8F16], Uses = [FPMR, FPCR] in { + def FTMOPA_M2ZZZI_BtoH : sme_tmopa_16b<0b01001, ZZ_b_mul_r, ZPR8, "ftmopa">; +} // [HasSME2p2, HasSMEF8F16], Uses = [FPMR, FPCR] + +let Predicates = [HasSME2p2, HasSMEF16F16] in { + def FTMOPA_M2ZZZI_HtoH : sme_tmopa_16b<0b10001, ZZ_h_mul_r, ZPR16, "ftmopa">; +} // [HasSME2p2, HasSMEF16F16] diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 9fb3501286e531..b48ae77b8c95ed 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1285,6 +1285,7 @@ class AArch64Operand : public MCParsedAsmOperand { case AArch64::ZPR_4bRegClassID: case AArch64::ZPRMul2_LoRegClassID: case AArch64::ZPRMul2_HiRegClassID: + case AArch64::ZPR_KRegClassID: RK = RegKind::SVEDataVector; break; case AArch64::PPRRegClassID: @@ -6179,6 +6180,9 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_InvalidZPRMul2_Hi64: return Error(Loc, "Invalid restricted vector register, expected even " "register in z16.d..z30.d"); + case Match_InvalidZPR_K0: + return Error(Loc, "invalid restricted vector register, expected register " + "in z20..z23 or z28..z31"); case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); case Match_InvalidSVEPPRorPNRAnyReg: @@ -6888,6 +6892,7 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidZPRMul2_Hi32: case Match_InvalidZPRMul2_Lo64: case Match_InvalidZPRMul2_Hi64: + case Match_InvalidZPR_K0: case Match_InvalidSVEVectorList2x8Mul2: case Match_InvalidSVEVectorList2x16Mul2: case Match_InvalidSVEVectorList2x32Mul2: diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index 8e2dc3d217cb9f..db4106c1cf2799 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -49,6 +49,8 @@ template static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder); template static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, @@ -387,6 +389,17 @@ static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, return Success; } +static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder) { + if (RegNo > 7) + return Fail; + + unsigned Register = + AArch64MCRegisterClasses[AArch64::ZPR_KRegClassID].getRegister(RegNo); + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp index 61b83847666908..a019ff8eac3328 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -195,6 +195,9 @@ class AArch64MCCodeEmitter : public MCCodeEmitter { uint32_t EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + uint32_t EncodeZK(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; uint32_t EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; @@ -573,6 +576,25 @@ AArch64MCCodeEmitter::EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx, return (RegVal - Min) / Multiple; } +// Zk Is the name of the control vector register Z20-Z23 or Z28-Z31, encoded in +// the "K:Zk" fields. Z20-Z23 = 000, 001,010, 011 and Z28-Z31 = 100, 101, 110, +// 111 +uint32_t AArch64MCCodeEmitter::EncodeZK(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + auto RegOpnd = MI.getOperand(OpIdx).getReg(); + unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd); + + // ZZ8-Z31 => Reg is in 3..7 (offset 24) + if (RegOpnd > AArch64::Z27) + return (RegVal - 24); + + assert((RegOpnd > AArch64::Z19 && RegOpnd < AArch64::Z24) && + "Expected ZK in Z20..Z23 or Z28..Z31"); + // Z20-Z23 => Reg is in 0..3 (offset 20) + return (RegVal - 20); +} + uint32_t AArch64MCCodeEmitter::EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td index 38d256c8234118..08929ed5616b2c 100644 --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -3192,6 +3192,68 @@ multiclass sme2_int_bmopx_tile op, SDPatternOperator i def : SME_ZA_Tile_TwoPred_TwoVec_Pat; } +//===----------------------------------------------------------------------===// +// SME2 Sparse Outer Product and Accumulate + +class sme_tmopa_16b opc, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic> + : I<(outs TileOp16:$ZAda), + (ins TileOp16:$_ZAda, zn_ty:$Zn, zm_ty:$Zm, ZK:$Zk, VectorIndexS32b:$imm), + mnemonic, "\t$ZAda, $Zn, $Zm, $Zk$imm", + "", []>, + Sched<[]> { + bit ZAda; + bits<4> Zn; + bits<5> Zm; + bits<3> Zk; + bits<2> imm; + let Inst{31-25} = 0b1000000; + let Inst{24} = opc{4}; + let Inst{23-22} = 0b01; + let Inst{21} = opc{3}; + let Inst{20-16} = Zm; + let Inst{15} = opc{2}; + let Inst{14} = 0b0; + let Inst{13} = opc{1}; + let Inst{12-10} = Zk; + let Inst{9-6} = Zn; + let Inst{5-4} = imm; + let Inst{3} = opc{0}; + let Inst{2-1} = 0b00; + let Inst{0} = ZAda; + + let Constraints = "$ZAda = $_ZAda"; +} + +class sme_tmopa_32b opc, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic> + : I<(outs TileOp32:$ZAda), + (ins TileOp32:$_ZAda, zn_ty:$Zn, zm_ty:$Zm, ZK:$Zk, VectorIndexS32b:$imm), + mnemonic, "\t$ZAda, $Zn, $Zm, $Zk$imm", + "", []>, + Sched<[]> { + bits<2> ZAda; + bits<4> Zn; + bits<5> Zm; + bits<3> Zk; + bits<2> imm; + let Inst{31-25} = 0b1000000; + let Inst{24} = opc{4}; + let Inst{23-22} = 0b01; + let Inst{21} = opc{3}; + let Inst{20-16} = Zm; + let Inst{15} = opc{2}; + let Inst{14} = 0b0; + let Inst{13} = opc{1}; + let Inst{12-10} = Zk; + let Inst{9-6} = Zn; + let Inst{5-4} = imm; + let Inst{3} = opc{0}; + let Inst{2} = 0b0; + let Inst{1-0} = ZAda; + + let Constraints = "$ZAda = $_ZAda"; +} + + //===----------------------------------------------------------------------===/// // SME2 Zero Lookup Table. class sme2_zero_zt opc> diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir index 7186b3de442bcb..f1d1b691fe1aa5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir @@ -57,7 +57,7 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_reg_output - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 2490378 /* regdef:FPR32_with_hsub_in_FPR16_lo */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 @@ -75,7 +75,7 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_mixed_types - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 2490378 /* regdef:FPR32_with_hsub_in_FPR16_lo */, def %0, 3342346 /* regdef:GPR64 */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0, 3342346 /* regdef:FPR64 */, def %1 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1 ; CHECK-NEXT: $d0 = COPY [[COPY1]](s64) diff --git a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll index 2d12c08eb8eee9..9f8897575b3d58 100644 --- a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll @@ -13,7 +13,7 @@ define @test_svadd_i8( %Zn, asm "add $0.b, $1.b, $2.b", "=w,w,y"( %Zn, %Zm) @@ -29,7 +29,7 @@ define @test_svsub_i64( %Zn, asm "sub $0.d, $1.d, $2.d", "=w,w,x"( %Zn, %Zm) @@ -45,7 +45,7 @@ define @test_svfmul_f16( %Zn, asm "fmul $0.h, $1.h, $2.h", "=w,w,y"( %Zn, %Zm) @@ -61,7 +61,7 @@ define @test_svfmul_f( %Zn, asm "fmul $0.s, $1.s, $2.s", "=w,w,x"( %Zn, %Zm) @@ -79,7 +79,7 @@ define @test_svfadd_f16( %Pg, asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"( %Pg, %Zn, %Zm) @@ -95,7 +95,7 @@ define @test_incp( %Pg, ; CHECK-NEXT: [[COPY1:%[0-9]+]]:ppr = COPY $p0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:ppr = COPY [[COPY1]] ; CHECK-NEXT: [[COPY3:%[0-9]+]]:zpr = COPY [[COPY]] - ; CHECK-NEXT: INLINEASM &"incp $0.s, $1", 0 /* attdialect */, 5701642 /* regdef:ZPR */, def %2, 393225 /* reguse:PPR */, [[COPY2]], 2147483657 /* reguse tiedto:$0 */, [[COPY3]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"incp $0.s, $1", 0 /* attdialect */, 5767178 /* regdef:ZPR */, def %2, 458761 /* reguse:PPR */, [[COPY2]], 2147483657 /* reguse tiedto:$0 */, [[COPY3]](tied-def 3) ; CHECK-NEXT: $z0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $z0 %1 = tail call asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg, %Zn) @@ -113,7 +113,7 @@ define @test_svfadd_f16_Uph_constraint( %P ; CHECK-NEXT: [[COPY3:%[0-9]+]]:ppr_p8to15 = COPY [[COPY2]] ; CHECK-NEXT: [[COPY4:%[0-9]+]]:zpr = COPY [[COPY1]] ; CHECK-NEXT: [[COPY5:%[0-9]+]]:zpr = COPY [[COPY]] - ; CHECK-NEXT: INLINEASM &"fadd $0.h, $1/m, $2.h, $3.h", 0 /* attdialect */, 5701642 /* regdef:ZPR */, def %3, 720905 /* reguse:PPR_p8to15 */, [[COPY3]], 5701641 /* reguse:ZPR */, [[COPY4]], 5701641 /* reguse:ZPR */, [[COPY5]] + ; CHECK-NEXT: INLINEASM &"fadd $0.h, $1/m, $2.h, $3.h", 0 /* attdialect */, 5767178 /* regdef:ZPR */, def %3, 786441 /* reguse:PPR_p8to15 */, [[COPY3]], 5767177 /* reguse:ZPR */, [[COPY4]], 5767177 /* reguse:ZPR */, [[COPY5]] ; CHECK-NEXT: $z0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $z0 %1 = tail call asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Uph,w,w"( %Pg, %Zn, %Zm) diff --git a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir index 260f816417701b..ffa7453e48b4f0 100644 --- a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir +++ b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir @@ -91,10 +91,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[LOADgot:%[0-9]+]]:gpr64common = LOADgot target-flags(aarch64-got) @c ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:GPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY %2 ; CHECK-NEXT: [[LDRDui1:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:GPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) ; CHECK-NEXT: [[FNEGDr:%[0-9]+]]:fpr64 = FNEGDr %2 ; CHECK-NEXT: nofpexcept FCMPDrr %4, killed [[FNEGDr]], implicit-def $nzcv, implicit $fpcr ; CHECK-NEXT: Bcc 1, %bb.2, implicit $nzcv diff --git a/llvm/test/CodeGen/AArch64/fmlal-loreg.ll b/llvm/test/CodeGen/AArch64/fmlal-loreg.ll index 20737a73183944..31ead890ba8ac7 100644 --- a/llvm/test/CodeGen/AArch64/fmlal-loreg.ll +++ b/llvm/test/CodeGen/AArch64/fmlal-loreg.ll @@ -11,8 +11,8 @@ define <4 x float> @test(ptr %lhs_panel, ptr %rhs_panel, <4 x float> %a) { ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_offset b8, -16 ; CHECK-NEXT: fmov x8, d0 -; CHECK-NEXT: ldr q8, [x0] ; CHECK-NEXT: ldr q16, [x1] +; CHECK-NEXT: ldr q8, [x0] ; CHECK-NEXT: lsr x9, x8, #32 ; CHECK-NEXT: //APP ; CHECK-NEXT: nop diff --git a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir index 822083bbf8d55e..f8af5b96370178 100644 --- a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir +++ b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir @@ -487,7 +487,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0 ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[DEF]] - ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 3342346 /* regdef:GPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] + ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 3342346 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] ; CHECK-NEXT: [[MOVIv2d_ns:%[0-9]+]]:fpr128 = MOVIv2d_ns 0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[MOVIv2d_ns]].dsub ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF diff --git a/llvm/test/MC/AArch64/SME2p2/bftmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/bftmopa-diagnostics.s new file mode 100644 index 00000000000000..2577a286354c95 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/bftmopa-diagnostics.s @@ -0,0 +1,114 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-b16b16 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid ZA register (range) + +bftmopa za2.h, {z30.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za2.h, {z30.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za4.s, {z30.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za4.s, {z30.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid ZA register (type-suffix) + +bftmopa za3.d, {z28.h-z29.h}, z31.h, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s +// CHECK-NEXT: bftmopa za3.d, {z28.h-z29.h}, z31.h, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list operand + +bftmopa za0.h, {z28.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za0.h, {z28.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.h, {z29.h-z30.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: bftmopa za0.h, {z29.h-z30.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.s, {z28.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za0.s, {z28.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z29.h-z30.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: bftmopa za3.s, {z29.h-z30.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid ZK register + +bftmopa za0.h, {z28.h-z29.h}, z31.h, z19[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za0.h, {z28.h-z29.h}, z31.h, z19[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.h, {z28.h-z29.h}, z31.h, z24[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za0.h, {z28.h-z29.h}, z31.h, z24[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z28.h-z29.h}, z31.h, z19[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za3.s, {z28.h-z29.h}, z31.h, z19[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z28.h-z29.h}, z31.h, z27[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za3.s, {z28.h-z29.h}, z31.h, z27[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.h, {z28.h-z29.h}, z31.h, z21.h[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za0.h, {z28.h-z29.h}, z31.h, z21.h[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.s, {z28.h-z29.h}, z31.h, z30.h[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: bftmopa za0.s, {z28.h-z29.h}, z31.h, z30.h[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate + +bftmopa za0.h, {z28.h-z29.h}, z31.h, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3] +// CHECK-NEXT: bftmopa za0.h, {z28.h-z29.h}, z31.h, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z28.h-z29.h}, z31.h, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3] +// CHECK-NEXT: bftmopa za3.s, {z28.h-z29.h}, z31.h, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid ZPR type suffix + +bftmopa za0.h, {z28.h-z29.h}, z31.s, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bftmopa za0.h, {z28.h-z29.h}, z31.s, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za0.h, {z28.b-z29.b}, z31.b, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za0.h, {z28.b-z29.b}, z31.b, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z28.h-z29.h}, z31.s, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bftmopa za3.s, {z28.h-z29.h}, z31.s, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bftmopa za3.s, {z28.s-z29.s}, z31.s, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bftmopa za3.s, {z28.s-z29.s}, z31.s, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2p2/bftmopa.s b/llvm/test/MC/AArch64/SME2p2/bftmopa.s new file mode 100644 index 00000000000000..dc7b5456ddab33 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/bftmopa.s @@ -0,0 +1,53 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-b16b16 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-b16b16 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2p2,+sme-b16b16 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-b16b16 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-b16b16 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-b16b16 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// non-widening + +bftmopa za0.h, {z0.h-z1.h}, z0.h, z20[0] // 10000001-01100000-00000000-00001000 +// CHECK-INST: bftmopa za0.h, { z0.h, z1.h }, z0.h, z20[0] +// CHECK-ENCODING: [0x08,0x00,0x60,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-b16b16 +// CHECK-UNKNOWN: 81600008 + +bftmopa za1.h, {z12.h-z13.h}, z8.h, z23[3] // 10000001-01101000-00001101-10111001 +// CHECK-INST: bftmopa za1.h, { z12.h, z13.h }, z8.h, z23[3] +// CHECK-ENCODING: [0xb9,0x0d,0x68,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-b16b16 +// CHECK-UNKNOWN: 81680db9 + +bftmopa za1.h, {z30.h-z31.h}, z31.h, z31[3] // 10000001-01111111-00011111-11111001 +// CHECK-INST: bftmopa za1.h, { z30.h, z31.h }, z31.h, z31[3] +// CHECK-ENCODING: [0xf9,0x1f,0x7f,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-b16b16 +// CHECK-UNKNOWN: 817f1ff9 + +// widening + +bftmopa za0.s, {z0.h-z1.h}, z0.h, z20[0] // 10000001-01000000-00000000-00000000 +// CHECK-INST: bftmopa za0.s, { z0.h, z1.h }, z0.h, z20[0] +// CHECK-ENCODING: [0x00,0x00,0x40,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 81400000 + +bftmopa za3.s, {z12.h-z13.h}, z8.h, z23[3] // 10000001-01001000-00001101-10110011 +// CHECK-INST: bftmopa za3.s, { z12.h, z13.h }, z8.h, z23[3] +// CHECK-ENCODING: [0xb3,0x0d,0x48,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 81480db3 + +bftmopa za3.s, {z30.h-z31.h}, z31.h, z31[3] // 10000001-01011111-00011111-11110011 +// CHECK-INST: bftmopa za3.s, { z30.h, z31.h }, z31.h, z31[3] +// CHECK-ENCODING: [0xf3,0x1f,0x5f,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 815f1ff3 diff --git a/llvm/test/MC/AArch64/SME2p2/directive-arch-negative.s b/llvm/test/MC/AArch64/SME2p2/directive-arch-negative.s new file mode 100644 index 00000000000000..27169bac8133e7 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-arch-negative.s @@ -0,0 +1,7 @@ +// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.arch armv9-a+sme2p2 +.arch armv9-a+nosme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: error: instruction requires: sme2p2 +// CHECK: ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SME2p2/directive-arch.s b/llvm/test/MC/AArch64/SME2p2/directive-arch.s new file mode 100644 index 00000000000000..bb4e943a88478e --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-arch.s @@ -0,0 +1,5 @@ +// RUN: llvm-mc -triple aarch64 -o - %s 2>&1 | FileCheck %s + +.arch armv9-a+sme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: ftmopa za0.s, { z0.s, z1.s }, z0.s, z20[0] diff --git a/llvm/test/MC/AArch64/SME2p2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SME2p2/directive-arch_extension-negative.s new file mode 100644 index 00000000000000..68784db1c6272b --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-arch_extension-negative.s @@ -0,0 +1,7 @@ +// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.arch_extension sme2p2 +.arch_extension nosme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: error: instruction requires: sme2p2 +// CHECK: ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] diff --git a/llvm/test/MC/AArch64/SME2p2/directive-arch_extension.s b/llvm/test/MC/AArch64/SME2p2/directive-arch_extension.s new file mode 100644 index 00000000000000..2e281e13f8ddb9 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-arch_extension.s @@ -0,0 +1,5 @@ +// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.arch_extension sme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: ftmopa za0.s, { z0.s, z1.s }, z0.s, z20[0] diff --git a/llvm/test/MC/AArch64/SME2p2/directive-cpu-negative.s b/llvm/test/MC/AArch64/SME2p2/directive-cpu-negative.s new file mode 100644 index 00000000000000..7cc829fbddd6ac --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-cpu-negative.s @@ -0,0 +1,7 @@ +// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.cpu generic+sme2p2 +.cpu generic+nosme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: error: instruction requires: sme2p2 +// CHECK: ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] diff --git a/llvm/test/MC/AArch64/SME2p2/directive-cpu.s b/llvm/test/MC/AArch64/SME2p2/directive-cpu.s new file mode 100644 index 00000000000000..152da398a90654 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/directive-cpu.s @@ -0,0 +1,5 @@ +// RUN: llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.cpu generic+sme2p2 +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] +// CHECK: ftmopa za0.s, { z0.s, z1.s }, z0.s, z20[0] \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SME2p2/ftmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/ftmopa-diagnostics.s new file mode 100644 index 00000000000000..e1f328819a9167 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/ftmopa-diagnostics.s @@ -0,0 +1,212 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid ZA register (range) + +ftmopa za2.h, {z30.b-z31.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za2.h, {z30.b-z31.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za2.h, {z30.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za2.h, {z30.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za4.s, {z30.b-z31.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za4.s, {z30.b-z31.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za4.s, {z30.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za4.s, {z30.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za4.s, {z30.s-z31.s}, z31.s, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za4.s, {z30.s-z31.s}, z31.s, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid ZA register (type suffix) + +ftmopa za0.b, {z30.b-z31.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s +// CHECK-NEXT: ftmopa za0.b, {z30.b-z31.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.d, {z30.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s +// CHECK-NEXT: ftmopa za0.d, {z30.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z30.s-z31.s}, z31.s, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za0.h, {z30.s-z31.s}, z31.s, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list operand + +ftmopa za0.h, {z28.b-z31.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za0.h, {z28.b-z31.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z29.b-z30.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: ftmopa za0.h, {z29.b-z30.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za0.h, {z28.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z29.h-z30.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: ftmopa za0.h, {z29.h-z30.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.b-z31.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za3.s, {z28.b-z31.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z29.b-z30.b}, z31.b, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: ftmopa za3.s, {z29.b-z30.b}, z31.b, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.h-z31.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za3.s, {z28.h-z31.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z29.h-z30.h}, z31.h, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: ftmopa za3.s, {z29.h-z30.h}, z31.h, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.s-z31.s}, z31.s, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ftmopa za3.s, {z28.s-z31.s}, z31.s, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z29.s-z30.s}, z31.s, z31[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: ftmopa za3.s, {z29.s-z30.s}, z31.s, z31[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// --------------------------------------------------------------------------// +// Invalid ZK register + +ftmopa za0.h, {z28.b-z29.b}, z31.b, z27[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za0.h, {z28.b-z29.b}, z31.b, z27[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.b-z29.b}, z31.b, z21.b[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za0.h, {z28.b-z29.b}, z31.b, z21.b[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.h-z29.h}, z31.h, z19[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za0.h, {z28.h-z29.h}, z31.h, z19[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.h-z29.h}, z31.h, z30.h[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za0.h, {z28.h-z29.h}, z31.h, z30.h[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.b-z29.b}, z31.b, z27[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.b-z29.b}, z31.b, z27[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.b-z29.b}, z31.b, z29.b[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.b-z29.b}, z31.b, z29.b[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.h-z29.h}, z31.h, z24[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.h-z29.h}, z31.h, z24[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.h-z29.h}, z31.h, z21.h[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.h-z29.h}, z31.h, z21.h[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.s-z29.s}, z31.s, z19[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.s-z29.s}, z31.s, z19[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.s-z29.s}, z31.s, z30.s[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31 +// CHECK-NEXT: ftmopa za3.s, {z28.s-z29.s}, z31.s, z30.s[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate + +ftmopa za0.h, {z28.b-z29.b}, z31.b, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: ftmopa za0.h, {z28.b-z29.b}, z31.b, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.h-z29.h}, z31.h, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: ftmopa za0.h, {z28.h-z29.h}, z31.h, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.b-z29.b}, z31.b, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: ftmopa za3.s, {z28.b-z29.b}, z31.b, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.h-z29.h}, z31.h, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: ftmopa za3.s, {z28.h-z29.h}, z31.h, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za3.s, {z28.s-z29.s}, z31.s, z20[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: ftmopa za3.s, {z28.s-z29.s}, z31.s, z20[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid ZPR type suffix + +ftmopa za0.h, {z28.b-z29.b}, z31.h, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: ftmopa za0.h, {z28.b-z29.b}, z31.h, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.h, {z28.h-z29.h}, z31.s, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: ftmopa za0.h, {z28.h-z29.h}, z31.s, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.s, {z28.b-z29.b}, z31.h, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: ftmopa za0.s, {z28.b-z29.b}, z31.h, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.s, {z28.h-z29.h}, z31.s, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: ftmopa za0.s, {z28.h-z29.h}, z31.s, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ftmopa za0.s, {z28.s-z29.s}, z31.h, z20[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: ftmopa za0.s, {z28.s-z29.s}, z31.h, z20[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + diff --git a/llvm/test/MC/AArch64/SME2p2/ftmopa.s b/llvm/test/MC/AArch64/SME2p2/ftmopa.s new file mode 100644 index 00000000000000..6944b94e6a812c --- /dev/null +++ b/llvm/test/MC/AArch64/SME2p2/ftmopa.s @@ -0,0 +1,113 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2p2,+sme-f8f32,+sme-f8f16,+sme-f16f16 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// 2-way (fp8-to-fp16) + +ftmopa za0.h, {z0.b-z1.b}, z0.b, z20[0] // 10000000-01100000-00000000-00001000 +// CHECK-INST: ftmopa za0.h, { z0.b, z1.b }, z0.b, z20[0] +// CHECK-ENCODING: [0x08,0x00,0x60,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f16 +// CHECK-UNKNOWN: 80600008 + +ftmopa za1.h, {z10.b-z11.b}, z21.b, z29[1] // 10000000-01110101-00010101-01011001 +// CHECK-INST: ftmopa za1.h, { z10.b, z11.b }, z21.b, z29[1] +// CHECK-ENCODING: [0x59,0x15,0x75,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f16 +// CHECK-UNKNOWN: 80751559 + +ftmopa za1.h, {z30.b-z31.b}, z31.b, z31[3] // 10000000-01111111-00011111-11111001 +// CHECK-INST: ftmopa za1.h, { z30.b, z31.b }, z31.b, z31[3] +// CHECK-ENCODING: [0xf9,0x1f,0x7f,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f16 +// CHECK-UNKNOWN: 807f1ff9 + +// 2-way, (fp16-to-fp32) + +ftmopa za0.s, {z0.h-z1.h}, z0.h, z20[0] // 10000001-01100000-00000000-00000000 +// CHECK-INST: ftmopa za0.s, { z0.h, z1.h }, z0.h, z20[0] +// CHECK-ENCODING: [0x00,0x00,0x60,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 81600000 + +ftmopa za3.s, {z12.h-z13.h}, z8.h, z23[3] // 10000001-01101000-00001101-10110011 +// CHECK-INST: ftmopa za3.s, { z12.h, z13.h }, z8.h, z23[3] +// CHECK-ENCODING: [0xb3,0x0d,0x68,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 81680db3 + +ftmopa za3.s, {z30.h-z31.h}, z31.h, z31[3] // 10000001-01111111-00011111-11110011 +// CHECK-INST: ftmopa za3.s, { z30.h, z31.h }, z31.h, z31[3] +// CHECK-ENCODING: [0xf3,0x1f,0x7f,0x81] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 817f1ff3 + +// 4-way + +ftmopa za0.s, {z0.b-z1.b}, z0.b, z20[0] // 10000000-01100000-00000000-00000000 +// CHECK-INST: ftmopa za0.s, { z0.b, z1.b }, z0.b, z20[0] +// CHECK-ENCODING: [0x00,0x00,0x60,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f32 +// CHECK-UNKNOWN: 80600000 + +ftmopa za3.s, {z12.b-z13.b}, z8.b, z23[3] // 10000000-01101000-00001101-10110011 +// CHECK-INST: ftmopa za3.s, { z12.b, z13.b }, z8.b, z23[3] +// CHECK-ENCODING: [0xb3,0x0d,0x68,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f32 +// CHECK-UNKNOWN: 80680db3 + +ftmopa za3.s, {z30.b-z31.b}, z31.b, z31[3] // 10000000-01111111-00011111-11110011 +// CHECK-INST: ftmopa za3.s, { z30.b, z31.b }, z31.b, z31[3] +// CHECK-ENCODING: [0xf3,0x1f,0x7f,0x80] +// CHECK-ERROR: instruction requires: sme2p2 sme-f8f32 +// CHECK-UNKNOWN: 807f1ff3 + +// non-widening (half-precision) + +ftmopa za0.h, {z0.h-z1.h}, z0.h, z20[0] // 10000001-01000000-00000000-00001000 +// CHECK-INST: ftmopa za0.h, { z0.h, z1.h }, z0.h, z20[0] +// CHECK-ENCODING: [0x08,0x00,0x40,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-f16f16 +// CHECK-UNKNOWN: 81400008 + +ftmopa za1.h, {z12.h-z13.h}, z8.h, z23[3] // 10000001-01001000-00001101-10111001 +// CHECK-INST: ftmopa za1.h, { z12.h, z13.h }, z8.h, z23[3] +// CHECK-ENCODING: [0xb9,0x0d,0x48,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-f16f16 +// CHECK-UNKNOWN: 81480db9 + +ftmopa za1.h, {z30.h-z31.h}, z31.h, z31[3] // 10000001-01011111-00011111-11111011 +// CHECK-INST: ftmopa za1.h, { z30.h, z31.h }, z31.h, z31[3] +// CHECK-ENCODING: [0xf9,0x1f,0x5f,0x81] +// CHECK-ERROR: instruction requires: sme2p2 sme-f16f16 +// CHECK-UNKNOWN: 815f1ff9 + +// non-widening (single-precision) + +ftmopa za0.s, {z0.s-z1.s}, z0.s, z20[0] // 10000000-01000000-00000000-00000000 +// CHECK-INST: ftmopa za0.s, { z0.s, z1.s }, z0.s, z20[0] +// CHECK-ENCODING: [0x00,0x00,0x40,0x80] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 80400000 + +ftmopa za3.s, {z12.s-z13.s}, z8.s, z23[3] // 10000000-01001000-00001101-10110011 +// CHECK-INST: ftmopa za3.s, { z12.s, z13.s }, z8.s, z23[3] +// CHECK-ENCODING: [0xb3,0x0d,0x48,0x80] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 80480db3 + +ftmopa za3.s, {z30.s-z31.s}, z31.s, z31[3] // 10000000-01011111-00011111-11110011 +// CHECK-INST: ftmopa za3.s, { z30.s, z31.s }, z31.s, z31[3] +// CHECK-ENCODING: [0xf3,0x1f,0x5f,0x80] +// CHECK-ERROR: instruction requires: sme2p2 +// CHECK-UNKNOWN: 805f1ff3 \ No newline at end of file