From 709285c0440bbe1c84a2378078ea32dde157d044 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Tue, 14 Jul 2026 04:24:50 +0000 Subject: [PATCH 01/10] [RISCV] Introduce RVI AME (standard, pre-ratification) intrinsics --- llvm/include/llvm/IR/IntrinsicsRISCV.td | 1 + llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td | 571 ++++++++++++++++++ 2 files changed, 572 insertions(+) create mode 100644 llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 664dc8c3dea90..774cc58e7ac92 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2141,5 +2141,6 @@ include "llvm/IR/IntrinsicsRISCVXCV.td" include "llvm/IR/IntrinsicsRISCVXAndes.td" include "llvm/IR/IntrinsicsRISCVXMIPS.td" include "llvm/IR/IntrinsicsRISCVExt.td" +include "llvm/IR/IntrinsicsRISCVAMEExt.td" include "llvm/IR/IntrinsicsRISCVBOSCExt.td" include "llvm/IR/IntrinsicsRISCVBuckyballExt.td" diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td new file mode 100644 index 0000000000000..c1d817e54371d --- /dev/null +++ b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td @@ -0,0 +1,571 @@ +//===- IntrinsicsRISCVAMEExt.td ------------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file defines the intrinsics for the AME (RISC-V Matrix Extension) +// extension. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Datatype management intrinsics +//===----------------------------------------------------------------------===// +// Base class for "get datatype" instrinsics: reads the dtype of an M/Acc +// register into a GPR value. +// Signature: i32 (dtype_reg_index: i32) +class AME_DataType_Get_Intr + : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], + [IntrNoMem, IntrHasSideEffects, ImmArg>]>; + +// Base class for "set datatype" instrinsics: writes a GPR value into the dtype +// of an M/Acc register and zeroes that M/Acc register's contents. +// Signature: void (dtype_reg_index: i32, dtype_value: i32) +class AME_DataType_Set_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], + [IntrNoMem, IntrHasSideEffects, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // agettype - get the dtype of an Acc register + def int_riscv_ame_agettyp : AME_DataType_Get_Intr; + + // asettype - set the dtype of an Acc register; zeroes the Acc register + def int_riscv_ame_asettyp : AME_DataType_Set_Intr; + + // mgettype - get the dtype of a M (matrix) register + def int_riscv_ame_mgettype : AME_DataType_Get_Intr; + + // sgettype - set the dtype of a M (matrix) register; zeroes the M register + def int_riscv_ame_msettype : AME_DataType_Set_Intr; +} + +//===----------------------------------------------------------------------===// +// Elementwise arithmetic intrinsics +//===----------------------------------------------------------------------===// +// Base class for matrix-matrix elementwise arithmetic intrinsics +// Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) +class AME_Elementwise_Arithmetic_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> + ]>; + +// Base class for matrix-scalar elementwise arithmetic intrinsics +// Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) +class AME_Elementwise_Arithmetic_Scalar_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mabs.ew - md[i] = |ms1[i]| + // Signature: void (md_reg_index: i32, ms1_reg_index: i32) + def int_riscv_ame_mabs_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg> + ]>; + + // mabsdiff.ew - md[i] = |ms1[i] - ms2[i]| + def int_riscv_ame_mabsdiff_ew : AME_Elementwise_Arithmetic_Intr; + + // mabsdiff.ew.x - md[i] = |scalar - ms2[i]| + def int_riscv_ame_mabsdiff_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // madd.ew - md[i] = ms1[i] + ms2[i] + def int_riscv_ame_madd_ew : AME_Elementwise_Arithmetic_Intr; + + // madd.ew.x - md[i] = scalar + ms2[i] + def int_riscv_ame_madd_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // msub.ew - md[i] = ms2[i] - ms1[i] + def int_riscv_ame_msub_ew : AME_Elementwise_Arithmetic_Intr; + + // msub.ew.x - md[i] = scalar - ms2[i] + def int_riscv_ame_msub_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mhdiff.ew - md[i] = (ms2[i] - ms1[i]) * 0.5 + def int_riscv_ame_mhdiff_ew : AME_Elementwise_Arithmetic_Intr; + + // mhdiff.ew.x - md[i] = (scalar - ms2[i]) * 0.5 + def int_riscv_ame_mhdiff_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmax.ew - md[i] = max(ms1[i], ms2[i]) + def int_riscv_ame_mmax_ew : AME_Elementwise_Arithmetic_Intr; + + // mmax.ew.x - md[i] = max(scalar, ms2[i]) + def int_riscv_ame_mmax_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmean.ew - md[i] = (ms1[i] + ms2[i]) * 0.5 + def int_riscv_ame_mmean_ew : AME_Elementwise_Arithmetic_Intr; + + // mmean.ew.x - md[i] = (scalar + ms2[i]) * 0.5 + def int_riscv_ame_mmean_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmin.ew - md[i] = min(ms1[i], ms2[i]) + def int_riscv_ame_mmin_ew : AME_Elementwise_Arithmetic_Intr; + + // mmin.ew.x - md[i] = min(scalar, ms2[i]) + def int_riscv_ame_mmin_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmul.ew - md[i] = ms1[i] * ms2[i] + def int_riscv_ame_mmul_ew : AME_Elementwise_Arithmetic_Intr; + + // mmul.ew.x - md[i] = scalar * ms2[i] + def int_riscv_ame_mmul_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmulacc.ew - md[i] = md[i] + ms1[i] * ms2[i] + def int_riscv_ame_mmulacc_ew : AME_Elementwise_Arithmetic_Intr; + + // mmulacc.ew.x - md[i] = md[i] + scalar * ms2[i] + def int_riscv_ame_mmulacc_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmulaccneg.ew - md[i] = md[i] - ms1[i] * ms2[i] + def int_riscv_ame_mmulaccneg_ew : AME_Elementwise_Arithmetic_Intr; + + // mmulaccneg.ew.x - md[i] = md[i] - scalar * ms2[i] + def int_riscv_ame_mmulaccneg_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmuladd.ew - md[i] = ms1[i] + ms2[i] * md[i] + def int_riscv_ame_mmuladd_ew : AME_Elementwise_Arithmetic_Intr; + + // mmuladd.ew.x - md[i] = scalar + ms2[i] * md[i] + def int_riscv_ame_mmuladd_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmulneg.ew - md[i] = -(ms1[i] * ms2[i]) + def int_riscv_ame_mmulneg_ew : AME_Elementwise_Arithmetic_Intr; + + // mmulneg.ew.x - md[i] = -(scalar * ms2[i]) + def int_riscv_ame_mmulneg_ew_X : AME_Elementwise_Arithmetic_Scalar_Intr; + + // mmulsub.ew - md[i] = ms1[i] - ms2[i] * md[i] + def int_riscv_ame_mmulsub_ew : AME_Elementwise_Arithmetic_Intr; + + // mmulsub.ew.x - md[i] = scalar - ms2[i] * md[i] + def int_riscv_ame_mmulsub_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; +} + +//===----------------------------------------------------------------------===// +// Bitwise intrinsics +//===----------------------------------------------------------------------===// +// Base class for matrix-matrix bitwise ops. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) +class AME_Bitwise_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> + ]>; + +// Base class for matrix-scalar bitwise ops. +// Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) +class AME_Bitwise_Scalar_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mand.ew - md[i] = ms1[i] & ms2[i] + def int_riscv_ame_mand_ew : AME_Bitwise_Intr; + + // mand.ew.x - md[i] = scalar & ms2[i] + def int_riscv_ame_mand_ew_x : AME_Bitwise_Scalar_Intr; + + // mandnot.ew - md[i] = ms1[i] & ~ms2[i] + def int_riscv_ame_mandnot_ew : AME_Bitwise_Intr; + + // mandnot.ew.x - md[i] = scalar & ~ms2[i] + def int_riscv_ame_mandnot_ew_x : AME_Bitwise_Scalar_Intr; + + // mor.ew - md[i] = ms1[i] | ms2[i] + def int_riscv_ame_mor_ew : AME_Bitwise_Intr; + + // mor.ew.x - md[i] = scalar | ms2[i] + def int_riscv_ame_mor_ew_x : AME_Bitwise_Scalar_Intr; + + // mornot.ew - md[i] = ms1[i] | ~ms2[i] + def int_riscv_ame_mornot_ew : AME_Bitwise_Intr; + + // mornot.ew.x - md[i] = scalar | ~ms2[i] + def int_riscv_ame_mornot_ew_x : AME_Bitwise_Scalar_Intr; + + // mxor.ew - md[i] = ms1[i] ^ ms2[i] + def int_riscv_ame_mxor_ew : AME_Bitwise_Intr; + + // mxor.ew.x - md[i] = scalar ^ ms2[i] + def int_riscv_ame_mxor_ew_x : AME_Bitwise_Scalar_Intr; +} + +//===----------------------------------------------------------------------===// +// Scalar broadcast intrinsic +//===----------------------------------------------------------------------===// +let TargetPrefix = "riscv" in { + // mbcast.x - broadcast a GPR value to every element of a matrix register + // (md). Signature: void (md_reg_index: i32, scalar: i32) + def int_riscv_ame_mbcast_x + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>]>; +} + +//===----------------------------------------------------------------------===// +// Compare and predication intrinsics +//===----------------------------------------------------------------------===// +// Base class for matrix-matrix compare/predicate ops. +// Signature: void (md_reg_index: i32, pred_or_src0_reg_index: i32, +// src1_reg_index: i32) +class AME_Comp_Pred_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> + ]>; + +// Base class for matrix-scalar compare ops. +// Signature: void (md_reg_index: i32, scalar: i32, src1_reg_index: i32) +class AME_Comp_Pred_Scalar_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mcmovge.ew - md[i] = src1[i] if pred[i] >= 0, else md[i] unchanged. + def int_riscv_ame_mcmovge_ew : AME_Comp_Pred_Intr; + + // mcmovlt.ew - md[i] = src1[i] if pred[i] < 0, else md[i] unchanged. + def int_riscv_ame_mcmovlt_ew : AME_Comp_Pred_Intr; + + // mcmpge.ew - md[i] = (src0[i] >= src1[i]) ? -1 : 0. + def int_riscv_ame_mcmpge_ew : AME_Comp_Pred_Intr; + + // mcmpge.ew.x - md[i] = (scalar >= src1[i]) ? -1 : 0. + def int_riscv_ame_mcmpge_ew_x : AME_Comp_Pred_Scalar_Intr; + + // mcmplt.ew - md[i] = (src0[i] < src1[i]) ? -1 : 0. + def int_riscv_ame_mcmplt_ew : AME_Comp_Pred_Intr; + + // mcmplt.ew.x - md[i] = (scalar < src1[i]) ? -1 : 0. + def int_riscv_ame_mcmplt_ew_x : AME_Comp_Pred_Scalar_Intr; + + // mselge.ew - md[i] = src1[i] if pred[i] >= 0, else md[i] = 0 + def int_riscv_ame_mselge_ew : AME_Comp_Pred_Intr; + + // msellt.ew - md[i] = src1[i] if pred[i] < 0, else md[i] = 0 + def int_riscv_ame_msellt_ew : AME_Comp_Pred_Intr; +} + +//===----------------------------------------------------------------------===// +// Permutation intrinsics +//===----------------------------------------------------------------------===// +// Base class for 2-operand permutation intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32) +class AME_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, + ImmArg>, + ImmArg>, +]>; + +// Base class for 3-operand permutation intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) +class AME_Perm3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> +]>; + +let TargetPrefix = "riscv" in { + // Note: N = sqrt(AME_NELEM) + + // mcolunzip.ew - elementwise column un-zip (de-interleave). + // Given 0 <= i < N and 0 <= j < N/2 + // md[i, j] = ms1[i, 2j] + // md[i, j + N/2] = ms1[i, 2j + 1] + def int_riscv_ame_mcolunzip_ew : AME_Perm2_Intr; + + // mcolzip.ew - elementwise column zip (interleave). + // Given 0 <= i < N and 0 <= j < N/2 + // md[i, 2j] = ms1[i, j] + // md[i, 2j + 1] = ms1[i, j + N/2] + def int_riscv_ame_mcolzip_ew : AME_Perm2_Intr; + + // mgather.ew - elementwise gather + // Given 0 <= i < N and 0 <= j < N + // md[i, j] = ms1[i, ms2[i, j]] + def int_riscv_ame_mgather_ew : AME_Perm3_Intr; + + // mrowunzip.ew - row un-zip (de-interleave rows) + // Given 0 <= k < N, 0 <= j < N and that ms1 is treated as a conceptual 2N-row + // matrix stored across (ms1, ms+1). + // md[k, j] = ms1[2k, j] + // md+1[k, j] = ms1[2k+1, j] + def int_riscv_ame_mrowunzip_ew : AME_Perm2_Intr; + + // mrowzip.ew - row zip (interleave rows from 2 inputs) + // Given 0 <= k < 2N-1, 0 <= j < N and that md is treated as a conceptual + // 2N-row matrix stord across (md, md+1). md[2k, j] = ms1[k, j] md[2k+1, j] = + // ms2[k, j] + def int_riscv_ame_mrowzip_ew : AME_Perm3_Intr; + + // mscatadd.col - elementwise column scatter-add + // Given i <= 0 < N, 0 <= j < N + // md[ms2[i, j], j] += ms1[i, j] + def int_riscv_ame_mscatadd_col : AME_Perm3_Intr; + + // mscatadd.row - elementwise scatter-add + // Given i <= 0 < N, 0 <= j < N + // md[i, ms2[i, j]] += ms1[i, j] + def int_riscv_ame_mscatadd_row : AME_Perm3_Intr; + + // mscatmax.col - elementwise column scatter-max + // Given i <= 0 < N, 0 <= j < N + // md[ms2[i, j], j] = max(md[ms2[i, j], j], ms1[i, j]) + def int_riscv_ame_mscatmax_col : AME_Perm3_Intr; + + // mscatmax.row - elementwise scatter-max + // Given i <= 0 < N, 0 <= j < N + // md[i, ms2[i, j]] = max(md[i, ms2[i, j]], ms1[i, j]) + def int_riscv_ame_mscatmax_row : AME_Perm3_Intr; + + // mshift.ew - elementwise row shift by constant offset + // Given i <= 0 < N, 0 <= j < N + // md[i, j] = md[i, j + imm] if 0 <= j + imm < N else md[i, j] = 0 + def int_riscv_ame_mshift_ew : AME_Perm3_Intr; + + // mshift.m1 - alias for mshift.ew when imm = -1 + def int_riscv_ame_mshift_m1 : AME_Perm2_Intr; + + // mshift.p1 - alias for mshift.ew when imm = 1 + def int_riscv_ame_mshift_p1 : AME_Perm2_Intr; +} + +//===----------------------------------------------------------------------===// +// Register move / data conversion intrinsics +//===----------------------------------------------------------------------===// +// Base class for packing / unpacking intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32, scalar: i32) +class AME_PackUnpack_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, + ImmArg>, + ImmArg>, + ]>; + +let TargetPrefix = "riscv" in { + // mconv.ew - convert between packed and non-packed dtype (Md[ms1] vs + // Md[md]); exactly one side must be packed, else amestatus.UN. + // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 + // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid + // operands here. + def int_riscv_ame_mconv_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg> + ]>; + + // mpack.ew.x - pack the square from the ms1 register (unpacked, + // single-square) into the packed md (matrix) register's sub-square slot + // selected by scalar index + // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 + // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid + // operands here. + def int_riscv_ame_mpack_ew_x : AME_PackUnpack_Intr; + + // munpack.ew.x - extracts a square (selected by scalar index) from the ms1 + // register (packed) into the unpacked md (matrix) register + // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 + // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid + // operands here. + def int_riscv_ame_munpack_ew_x : AME_PackUnpack_Intr; +} + +//===----------------------------------------------------------------------===// +// Log2 and Exp2 intrinsics +//===----------------------------------------------------------------------===// +// Base class for 2-operand elementwise matrix-matrix log2/exp2 intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32) +class AME_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, + ImmArg>, + ImmArg>, +]>; + +// Base class for 3-operand elementwise matrix-matrix log2/exp2 intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) +class AME_Log2Exp2_3_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> + ]>; + +// Base class for elementwise matrix-scalar log2/exp2 intrinsics. +// Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) +class AME_Log2Exp2_Scalar_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mexp2.ew - md[i] = 2^ms1[i] + def int_riscv_ame_mexp2_ew : AME_Log2Exp2_2_Intr; + + // mldexp.ew - md[i] = ms1[i] * 2^ms1[i] + def int_riscv_ame_mldexp_ew : AME_Log2Exp2_3_Intr; + + // mldexp.ew.x - md[i] = ms2[i] * 2^scalar + def int_riscv_ame_mldexp_ew_x : AME_Log2Exp2_Scalar_Intr; + + // mldexpacc.ew - md[i] = md[i] + ms1[i] * 2^ms1[i] + def int_riscv_ame_mldexpacc_ew : AME_Log2Exp2_3_Intr; + + // mldexpacc.ew.x - md[i] = md[i] + ms2[i] * 2^scalar + def int_riscv_ame_mldexpacc_ew_x : AME_Log2Exp2_Scalar_Intr; + + // mlog2.ew - md[i] = log2(ms1[i]) + def int_riscv_ame_mlog2_ew : AME_Log2Exp2_2_Intr; + + // mlog2sub.ew - md[i] = log2(|ms1[i]|) - ms2[i] + def int_riscv_ame_mlog2sub_ew : AME_Log2Exp2_3_Intr; + + // mlog2sub.ew.x - md[i] = log2(|ms2[i]|) - scalar + def int_riscv_ame_mlog2sub_ew_x : AME_Log2Exp2_Scalar_Intr; + + // mrdexp.ew - md[i] = ms1[i] * 2^(-ms2[i]) + def int_riscv_ame_mrdexp_ew : AME_Log2Exp2_3_Intr; + + // mrdexpacc.ew - md[i] = md[i] + ms1[i] * 2^(-ms2[i]) + def int_riscv_ame_mrdexpacc_ew : AME_Log2Exp2_3_Intr; + + // msublog2.ew - md[i] = ms2[i] - log2(|ms1[i]|) + def int_riscv_ame_msublog2_ew : AME_Log2Exp2_3_Intr; + + // msublog2.ew.x - md[i] = scalar - log2(|ms2[i]|) + def int_riscv_ame_msublog2_ew_x : AME_Log2Exp2_Scalar_Intr; +} + +//===----------------------------------------------------------------------===// +// Load/store (memory) intrinsics +//===----------------------------------------------------------------------===// +// Base class for square loads: loads AME_NELEM elements from memory at addr +// into the matrix register group (md). +// Signature: void (md_reg_index: i32, addr: i32) +class AME_Load_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty], + [IntrReadMem, IntrHasSideEffects, ImmArg>]>; + +// Base class for square stores: stores AME_NELEM elements from the matrix +// register group (md) into memory at addr. +// Signature: void (md_reg_index: i32, addr: i32) +class AME_Store_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty], + [IntrWriteMem, IntrHasSideEffects, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mls - load using the implementation-defined layout (must match a pripr mss + // to memory). + def int_riscv_ame_mls : AME_Load_Intr; + + // mls.cm / mls.rm - load with an explicit column-major / row-major layout. + def int_riscv_ame_mls_cm : AME_Load_Intr; + def int_riscv_ame_mls_rm : AME_Load_Intr; + + // mss - store using the implementation-defined layout. + def int_riscv_ame_mss : AME_Store_Intr; + + // mss.cm / mss.rm - store with an explicit column-major / row-major layout. + def int_riscv_ame_mss_cm : AME_Store_Intr; + def int_riscv_ame_mss_rm : AME_Store_Intr; +} + +//===----------------------------------------------------------------------===// +// State management intrinsics +//===----------------------------------------------------------------------===// +// Base class for register-to-register move intrinsics: both operands are M/Acc +// registers Signature: void (dest_reg_index: i32, src_reg_index: i32) +class AME_Move_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mmov.a.m - copy an Acc register to an M register group; dtypes must + // match, else amestatus.UN is set and dest is left untouched + def int_riscv_ame_mmov_a_m : AME_Move_Intr; + + // mmov.m.m - copy one M register to another; dtypes must + // match, else amestatus.UN is set and dest is left untouched + def int_riscv_ame_mmov_m_m : AME_Move_Intr; + + // mzero.2d - zero every element of an Acc register. + // Signature: void (acc_reg_index: i32) + def int_riscv_ame_mzero_2d + : Intrinsic<[], [llvm_i64_ty], [IntrHasSideEffects, ImmArg>]>; +} + +//===----------------------------------------------------------------------===// +// Matrix multiply intrinsics +//===----------------------------------------------------------------------===// +// Base class for matrix multiply intrinsics +// Signature: void (acc_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) +class AME_MatMul_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ + IntrHasSideEffects, ImmArg>, ImmArg>, + ImmArg> +]>; + +let TargetPrefix = "riscv" in { + // mmul.2d - acc[i, j] = sum over k of (ms1[i, k] * ms2[k, j] + def int_riscv_ame_mmul_2d : AME_MatMul_Intr; + + // mmulneg.2d - acc[i, j] = -(sum over k of (ms1[i, k] * ms2[k, j]) + def int_riscv_ame_mmulneg_2d : AME_MatMul_Intr; + + // mmulacc.2d - acc[i, j] += sum over k of (ms1[i, k] * ms2[k, j] + def int_riscv_ame_mmulacc_2d : AME_MatMul_Intr; + + // mmulaccneg.2d - acc[i, j] -= sum over k of (ms1[i, k] * ms2[k, j] + def int_riscv_ame_mmulaccneg_2d : AME_MatMul_Intr; + + // mmulat.2d - acc[i, j] = sum over k of (ms1[k, i] * ms2[k, j] + def int_riscv_ame_mmulat_2d : AME_MatMul_Intr; + + // mmulatacc.2d - acc[i, j] += sum over k of (ms1[k, i] * ms2[k, j] + def int_riscv_ame_mmulatacc_2d : AME_MatMul_Intr; + + // mmulbt.2d - acc[i, j] = sum over k of (ms1[i, k] * ms2[j, k] + def int_riscv_ame_mmulbt_2d : AME_MatMul_Intr; + + // mmulbtacc.2d - acc[i, j] += sum over k of (ms1[i, k] * ms2[j, k] + def int_riscv_ame_mmulbtacc_2d : AME_MatMul_Intr; +} + +//===----------------------------------------------------------------------===// +// Reduction intrinsics +//===----------------------------------------------------------------------===// +// Base class for reduction intrinsics. +// Signature: void (md_reg_index: i32, ms1_reg_index: i32) +class AME_Reduction_Intr + : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], + [IntrHasSideEffects, ImmArg>, ImmArg>]>; + +let TargetPrefix = "riscv" in { + // mprefixadd.col - md[i, j] = sum over k <= i of ms1[k, j] + def int_riscv_ame_mprefixadd_col : AME_Reduction_Intr; + + // mprefixadd.row - md[i, j] = sum over k <= j of ms1[i, k] + def int_riscv_ame_mprefixadd_row : AME_Reduction_Intr; + + // mprefixmax.col - md[i, j] = max over k <= i of ms1[k, j] + def int_riscv_ame_mprefixmax_col : AME_Reduction_Intr; + + // mprefixmax.row - md[i, j] = max over k <= j of ms1[i, k] + def int_riscv_ame_mprefixmax_row : AME_Reduction_Intr; + + // mreduceadd.col - md[i, j] = sum over k of ms1[k, j] + def int_riscv_ame_mreduceadd_col : AME_Reduction_Intr; + + // mreduceadd.row - md[i, j] = sum over k of ms1[i, k] + def int_riscv_ame_mreduceadd_row : AME_Reduction_Intr; + + // mreducemax.col - md[i, j] = max over k of ms1[k, j] + def int_riscv_ame_mreducemax_col : AME_Reduction_Intr; + + // mreducemax.row - md[i, j] = max over k of ms1[i, k] + def int_riscv_ame_mreducemax_row : AME_Reduction_Intr; +} From 48fc747121c648eb328d77f7b90d0c4cb707fd1e Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Tue, 14 Jul 2026 22:03:58 +0000 Subject: [PATCH 02/10] [RISCV: Refactor] Reorganize all AME register definitions --- .../Target/RISCV/RISCVInstrInfoXBOSCAME.td | 196 ++++++++--------- .../Target/RISCV/RISCVInstrInfoXTHeadAME.td | 208 +++++++++--------- llvm/lib/Target/RISCV/RISCVMatrixExt.td | 187 +++++++--------- 3 files changed, 284 insertions(+), 307 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXBOSCAME.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXBOSCAME.td index 733144b6a116c..8b6f48f460e27 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXBOSCAME.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXBOSCAME.td @@ -25,11 +25,11 @@ // 32-bit encoding format with prefix 1110111 at bits [6:0] // // Register Model: -// - TileReg (tr0-tr7): Input matrices A and B, MLEN bits each -// - AccReg (acc0-acc7): Accumulator matrix C, MLEN×AMUL bits each +// - BOSCAMETileReg (tr0-tr7): Input matrices A and B, MLEN bits each +// - BOSCAMEAccReg (acc0-acc7): Accumulator matrix C, MLEN×AMUL bits each // // Data Flow: -// Memory --[mlae/mlbe]--> TileReg --[mma]--> AccReg --[msce]--> Memory +// Memory --[mlae/mlbe]--> BOSCAMETileReg --[mma]--> BOSCAMEAccReg --[msce]--> Memory // // Matrix Multiplication Instruction Format (32-bit): // | 31:26 | 25 | 24 | 23:20 | 19 | 18:15 | 14:12 | 11 | 10:7 | 6:0 | @@ -67,14 +67,14 @@ def BOSCAMEAccIndexAsmOperand : AsmOperandClass { let DiagnosticType = "InvalidBOSCAMEAccIndex"; } -// Operand type for TileReg index (0-7), printed with "tr" prefix in AsmString +// Operand type for BOSCAMETileReg index (0-7), printed with "tr" prefix in AsmString def BOSCAMETileIndex : RISCVOp { let ParserMatchClass = BOSCAMETileIndexAsmOperand; let DecoderMethod = "decodeUImmOperand<3>"; let OperandType = "OPERAND_UIMM3"; } -// Operand type for AccReg index (0-7), printed with "acc" prefix in AsmString +// Operand type for BOSCAMEAccReg index (0-7), printed with "acc" prefix in AsmString def BOSCAMEAccIndex : RISCVOp { let ParserMatchClass = BOSCAMEAccIndexAsmOperand; let DecoderMethod = "decodeUImmOperand<3>"; @@ -118,10 +118,10 @@ class RVInstBOSCAME32 // Format: mma.{h|w|dw}.mm acc, tr, tr // Semantics: acc = acc + tr1 * tr2 // -// Data Flow: TileReg × TileReg → AccReg (accumulate) -// - ms1: TileReg for matrix A -// - ms2: TileReg for matrix B -// - md: AccReg for accumulation result C +// Data Flow: BOSCAMETileReg × BOSCAMETileReg → BOSCAMEAccReg (accumulate) +// - ms1: BOSCAMETileReg for matrix A +// - ms2: BOSCAMETileReg for matrix B +// - md: BOSCAMEAccReg for accumulation result C // // eew encoding: // 000 = int8 (b), 001 = int16 (h), 010 = int32 (w), 011 = int64 (dw) @@ -138,8 +138,8 @@ class RVInstBOSCAME32 // Input and output have the same element width class BOSC_AME_MMA_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$md_in, TileReg:$ms1, TileReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$md_in, BOSCAMETileReg:$ms1, BOSCAMETileReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let Constraints = "$md = $md_in"; // Accumulator constraint let funct6 = 0b001000; // No widening @@ -186,8 +186,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // double-widen matrix multiply-accumulate: acc = acc + tr1 * tr2 class BOSC_AME_MMA_DOUBLE_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$md_in, TileReg:$ms1, TileReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$md_in, BOSCAMETileReg:$ms1, BOSCAMETileReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let Constraints = "$md = $md_in"; let funct6 = 0b001001; @@ -230,8 +230,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // quad-widen matrix multiply-accumulate: acc = acc + tr1 * tr2 class BOSC_AME_MMA_QUAD_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$md_in, TileReg:$ms1, TileReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$md_in, BOSCAMETileReg:$ms1, BOSCAMETileReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let Constraints = "$md = $md_in"; let funct6 = 0b001010; @@ -264,8 +264,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // oct-widen matrix multiply-accumulate: acc = acc + tr1 * tr2 class BOSC_AME_MMA_OCT_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$md_in, TileReg:$ms1, TileReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$md_in, BOSCAMETileReg:$ms1, BOSCAMETileReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let Constraints = "$md = $md_in"; let funct6 = 0b001011; @@ -298,8 +298,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // Matrix element-wise add/sub/multiply instructions. class BOSC_AME_MADD_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001000; let fp = fp_val; @@ -349,8 +349,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MADD_DOUBLE_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001001; let fp = fp_val; @@ -383,8 +383,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MSUB_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001010; let fp = fp_val; @@ -434,8 +434,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MSUB_DOUBLE_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001011; let fp = fp_val; @@ -468,8 +468,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MMINMAX_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001100; let fp = fp_val; @@ -525,8 +525,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MMUL_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001101; let fp = fp_val; @@ -569,8 +569,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MMULH_DIV_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001110; let fp = fp_val; @@ -620,8 +620,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_MMUL_DOUBLE_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b001111; let fp = fp_val; @@ -659,8 +659,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore } class BOSC_AME_LOGIC_NO_WIDEN - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b010000; let fp = 0b0; @@ -672,8 +672,8 @@ class BOSC_AME_LOGIC_NO_WIDEN } class BOSC_AME_SQRT_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1), opcodestr, "$md, $ms1"> { let funct6 = 0b010000; let fp = 0b1; @@ -700,8 +700,8 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore class BOSC_AME_SHIFT_NO_WIDEN eew_val, string opcodestr> - : RVInstBOSCAME32<(outs AccReg:$md), - (ins AccReg:$ms1, AccReg:$ms2), + : RVInstBOSCAME32<(outs BOSCAMEAccReg:$md), + (ins BOSCAMEAccReg:$ms1, BOSCAMEAccReg:$ms2), opcodestr, "$md, $ms1, $ms2"> { let funct6 = 0b010001; let fp = 0b0; @@ -813,19 +813,19 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 1, mayLoad = 0, mayStore // eew: 000=int8, 001=int16, 010=int32, 011=int64, 111=int4 // // Data Flow Examples: -// mlae32.m tr0, (a0), a1 # Load matrix A into TileReg -// mlbe32.m tr1, (a0), a1 # Load matrix B into TileReg -// mqma.b.mm acc0, tr0, tr1 # Compute: AccReg = AccReg + TileReg × TileReg -// msce32.m acc0, (a0), a1 # Store AccReg to memory +// mlae32.m tr0, (a0), a1 # Load matrix A into BOSCAMETileReg +// mlbe32.m tr1, (a0), a1 # Load matrix B into BOSCAMETileReg +// mqma.b.mm acc0, tr0, tr1 # Compute: BOSCAMEAccReg = BOSCAMEAccReg + BOSCAMETileReg × BOSCAMETileReg +// msce32.m acc0, (a0), a1 # Store BOSCAMEAccReg to memory //===----------------------------------------------------------------------===// -// Load into TileReg (for matrix A and B) +// Load into BOSCAMETileReg (for matrix A and B) class RVInstBOSCAMELoadTile32 funct6_val, bits<3> eew_val, bit tr_val, string opcodestr> - : RVInst<(outs TileReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInst<(outs BOSCAMETileReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, (${rs1}), $rs2", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; - bits<4> md; // TileReg index for load + bits<4> md; // BOSCAMETileReg index for load let Inst{6-0} = 0b1110111; // AME prefix let Inst{10-7} = md; @@ -837,13 +837,13 @@ class RVInstBOSCAMELoadTile32 funct6_val, bits<3> eew_val, bit tr_val, s let Inst{31-26} = funct6_val; // funct6 } -// Load into AccReg (for accumulator C) +// Load into BOSCAMEAccReg (for accumulator C) class RVInstBOSCAMELoadAcc32 funct6_val, bits<3> eew_val, bit tr_val, string opcodestr> - : RVInst<(outs AccReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInst<(outs BOSCAMEAccReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, (${rs1}), $rs2", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; - bits<4> md; // AccReg index for load + bits<4> md; // BOSCAMEAccReg index for load let Inst{6-0} = 0b1110111; // AME prefix let Inst{10-7} = md; @@ -855,13 +855,13 @@ class RVInstBOSCAMELoadAcc32 funct6_val, bits<3> eew_val, bit tr_val, st let Inst{31-26} = funct6_val; // funct6 } -// Store from TileReg (for matrix A and B) +// Store from BOSCAMETileReg (for matrix A and B) class RVInstBOSCAMEStoreTile32 funct6_val, bits<3> eew_val, bit tr_val, string opcodestr> - : RVInst<(outs), (ins TileReg:$ms3, GPR:$rs1, GPR:$rs2), + : RVInst<(outs), (ins BOSCAMETileReg:$ms3, GPR:$rs1, GPR:$rs2), opcodestr, "$ms3, (${rs1}), $rs2", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; - bits<4> ms3; // TileReg index for store + bits<4> ms3; // BOSCAMETileReg index for store let Inst{6-0} = 0b1110111; // AME prefix let Inst{10-7} = ms3; @@ -873,13 +873,13 @@ class RVInstBOSCAMEStoreTile32 funct6_val, bits<3> eew_val, bit tr_val, let Inst{31-26} = funct6_val; // funct6 } -// Store from AccReg (for accumulator C) +// Store from BOSCAMEAccReg (for accumulator C) class RVInstBOSCAMEStoreAcc32 funct6_val, bits<3> eew_val, bit tr_val, string opcodestr> - : RVInst<(outs), (ins AccReg:$ms3, GPR:$rs1, GPR:$rs2), + : RVInst<(outs), (ins BOSCAMEAccReg:$ms3, GPR:$rs1, GPR:$rs2), opcodestr, "$ms3, (${rs1}), $rs2", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; - bits<4> ms3; // AccReg index for store + bits<4> ms3; // BOSCAMEAccReg index for store let Inst{6-0} = 0b1110111; // AME prefix let Inst{10-7} = ms3; @@ -892,9 +892,9 @@ class RVInstBOSCAMEStoreAcc32 funct6_val, bits<3> eew_val, bit tr_val, s } //===----------------------------------------------------------------------===// -// Load matrix A into TileReg - mlae*.m +// Load matrix A into BOSCAMETileReg - mlae*.m // Syntax: mlae{8|16|32|64}.m md, (rs1), rs2 -// md: Destination TileReg +// md: Destination BOSCAMETileReg // rs1: Base address (GPR) // rs2: Row stride in bytes (GPR) //===----------------------------------------------------------------------===// @@ -916,7 +916,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 1, mayStore } //===----------------------------------------------------------------------===// -// Load matrix B into TileReg - mlbe*.m +// Load matrix B into BOSCAMETileReg - mlbe*.m // Syntax: mlbe{8|16|32|64}.m md, (rs1), rs2 //===----------------------------------------------------------------------===// let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { @@ -932,9 +932,9 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 1, mayStore } //===----------------------------------------------------------------------===// -// Load matrix C (accumulator) into AccReg - mlce*.m +// Load matrix C (accumulator) into BOSCAMEAccReg - mlce*.m // Syntax: mlce{8|16|32|64}.m md, (rs1), rs2 -// md: Destination AccReg (MLEN×AMUL bits) +// md: Destination BOSCAMEAccReg (MLEN×AMUL bits) // Note: eew here refers to the output element width after widening //===----------------------------------------------------------------------===// let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { @@ -955,7 +955,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 1, mayStore } //===----------------------------------------------------------------------===// -// Store matrix A from TileReg - msae*.m +// Store matrix A from BOSCAMETileReg - msae*.m // Syntax: msae{8|16|32|64}.m ms3, (rs1), rs2 //===----------------------------------------------------------------------===// let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { @@ -976,7 +976,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore } //===----------------------------------------------------------------------===// -// Store matrix B from TileReg - msbe*.m +// Store matrix B from BOSCAMETileReg - msbe*.m // Syntax: msbe{8|16|32|64}.m ms3, (rs1), rs2 //===----------------------------------------------------------------------===// let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { @@ -992,9 +992,9 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore } //===----------------------------------------------------------------------===// -// Store matrix C (accumulator) from AccReg - msce*.m +// Store matrix C (accumulator) from BOSCAMEAccReg - msce*.m // Syntax: msce{8|16|32|64}.m ms3, (rs1), rs2 -// ms3: Source AccReg (MLEN×AMUL bits) +// ms3: Source BOSCAMEAccReg (MLEN×AMUL bits) // This is the primary store for computation results //===----------------------------------------------------------------------===// let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { @@ -1042,10 +1042,10 @@ class RVInstBOSCAMEMove // Data Move Instructions between Matrix Registers class RVInstBOSCAMEMove_T_T eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins TileReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins BOSCAMETileReg:$ms1), opcodestr, "$md, $ms1"> { - bits<5> md; // TileReg index for store - bits<5> ms1; // TileReg index for load + bits<5> md; // BOSCAMETileReg index for store + bits<5> ms1; // BOSCAMETileReg index for load let funct6 = 0b000111; let di = 0b0; @@ -1057,10 +1057,10 @@ class RVInstBOSCAMEMove_T_T eew_val, string opcodestr> } class RVInstBOSCAMEMove_A_A eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins AccReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins BOSCAMEAccReg:$ms1), opcodestr, "$md, $ms1"> { - bits<5> md; // AccReg index for store - bits<5> ms1; // AccReg index for load + bits<5> md; // BOSCAMEAccReg index for store + bits<5> ms1; // BOSCAMEAccReg index for load let funct6 = 0b000111; let di = 0b0; @@ -1072,10 +1072,10 @@ class RVInstBOSCAMEMove_A_A eew_val, string opcodestr> } class RVInstBOSCAMEMove_A_T eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins TileReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins BOSCAMETileReg:$ms1, GPR:$rs2), opcodestr, "$md, $ms1, $rs2"> { - bits<5> md; // AccReg index for store - bits<5> ms1; // TileReg index for load + bits<5> md; // BOSCAMEAccReg index for store + bits<5> ms1; // BOSCAMETileReg index for load let funct6 = 0b000100; let di = 0b0; @@ -1086,10 +1086,10 @@ class RVInstBOSCAMEMove_A_T eew_val, string opcodestr> } class RVInstBOSCAMEMove_T_A eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins AccReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins BOSCAMEAccReg:$ms1, GPR:$rs2), opcodestr, "$md, $ms1, $rs2"> { - bits<5> md; // TileReg index for load - bits<5> ms1; // AccReg index for store + bits<5> md; // BOSCAMETileReg index for load + bits<5> ms1; // BOSCAMEAccReg index for store let funct6 = 0b000100; let di = 0b1; @@ -1100,7 +1100,7 @@ class RVInstBOSCAMEMove_T_A eew_val, string opcodestr> } class RVInstBOSCAMEMoveImm_A_T eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins TileReg:$ms1, uimm5:$imm), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins BOSCAMETileReg:$ms1, uimm5:$imm), opcodestr, "$md, $ms1, $imm"> { bits<5> imm; bits<5> ms1; @@ -1116,7 +1116,7 @@ class RVInstBOSCAMEMoveImm_A_T eew_val, string opcodestr> } class RVInstBOSCAMEMoveImm_T_A eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins AccReg:$ms1, uimm5:$imm), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins BOSCAMEAccReg:$ms1, uimm5:$imm), opcodestr, "$md, $ms1, $imm"> { bits<5> imm; bits<5> ms1; @@ -1166,7 +1166,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // Data Move Instructions between Matrix and Integer class RVInstBOSCAMEMove_X_T eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs GPR:$rd), (ins TileReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs GPR:$rd), (ins BOSCAMETileReg:$ms1, GPR:$rs2), opcodestr, "$rd, $ms1, $rs2"> { bits<5> rs2; bits<5> ms1; @@ -1179,7 +1179,7 @@ class RVInstBOSCAMEMove_X_T eew_val, string opcodestr> } class RVInstBOSCAMEMove_T_X eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, $rs1, $rs2"> { bits<5> rs2; bits<5> rs1; @@ -1192,7 +1192,7 @@ class RVInstBOSCAMEMove_T_X eew_val, string opcodestr> } class RVInstBOSCAMEMove_X_A eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs GPR:$rd), (ins AccReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs GPR:$rd), (ins BOSCAMEAccReg:$ms1, GPR:$rs2), opcodestr, "$rd, $ms1, $rs2"> { bits<5> rs2; bits<5> ms1; @@ -1205,7 +1205,7 @@ class RVInstBOSCAMEMove_X_A eew_val, string opcodestr> } class RVInstBOSCAMEMove_A_X eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, $rs1, $rs2"> { bits<5> rs2; bits<5> rs1; @@ -1242,7 +1242,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // Data Move Instructions between Matrix and Float-point class RVInstBOSCAMEFMove_F_T eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs GPR:$rd), (ins TileReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs GPR:$rd), (ins BOSCAMETileReg:$ms1, GPR:$rs2), opcodestr, "$rd, $ms1, $rs2"> { bits<5> rs2; bits<5> ms1; @@ -1255,7 +1255,7 @@ class RVInstBOSCAMEFMove_F_T eew_val, string opcodestr> } class RVInstBOSCAMEFMove_T_F eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, $rs1, $rs2"> { bits<5> rs2; bits<5> rs1; @@ -1268,7 +1268,7 @@ class RVInstBOSCAMEFMove_T_F eew_val, string opcodestr> } class RVInstBOSCAMEFMove_F_A eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs GPR:$rd), (ins AccReg:$ms1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs GPR:$rd), (ins BOSCAMEAccReg:$ms1, GPR:$rs2), opcodestr, "$rd, $ms1, $rs2"> { bits<5> rs2; bits<5> ms1; @@ -1281,7 +1281,7 @@ class RVInstBOSCAMEFMove_F_A eew_val, string opcodestr> } class RVInstBOSCAMEFMove_A_F eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins GPR:$rs1, GPR:$rs2), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins GPR:$rs1, GPR:$rs2), opcodestr, "$md, $rs1, $rs2"> { bits<5> rs2; bits<5> rs1; @@ -1318,7 +1318,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // Data Broadcast Instructions class RVInstBOSCAMEBroadcastTile rs2_val, bits<3> eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins TileReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins BOSCAMETileReg:$ms1), opcodestr, "$md, $ms1"> { bits<5> md; bits<5> ms1; @@ -1333,7 +1333,7 @@ class RVInstBOSCAMEBroadcastTile rs2_val, bits<3> eew_val, string opcode } class RVInstBOSCAMEBroadcastAcc rs2_val, bits<3> eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins AccReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins BOSCAMEAccReg:$ms1), opcodestr, "$md, $ms1"> { bits<5> md; bits<5> ms1; @@ -1348,36 +1348,36 @@ class RVInstBOSCAMEBroadcastAcc rs2_val, bits<3> eew_val, string opcodes } let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { - // Row broadcast from TileReg/AccReg + // Row broadcast from BOSCAMETileReg/BOSCAMEAccReg def BOSC_AME_MBCAR_M : RVInstBOSCAMEBroadcastTile<0b10001, 0b000, "mbcar.m">; def BOSC_AME_MBCBR_M : RVInstBOSCAMEBroadcastTile<0b10010, 0b000, "mbcbr.m">; def BOSC_AME_MBCCR_M : RVInstBOSCAMEBroadcastAcc<0b10000, 0b000, "mbccr.m">; - // Column broadcast from TileReg + // Column broadcast from BOSCAMETileReg def BOSC_AME_MBCACE8_M : RVInstBOSCAMEBroadcastTile<0b10101, 0b000, "mbcace8.m">; def BOSC_AME_MBCACE16_M : RVInstBOSCAMEBroadcastTile<0b10101, 0b001, "mbcace16.m">; def BOSC_AME_MBCACE32_M : RVInstBOSCAMEBroadcastTile<0b10101, 0b010, "mbcace32.m">; def BOSC_AME_MBCACE64_M : RVInstBOSCAMEBroadcastTile<0b10101, 0b011, "mbcace64.m">; - // Column broadcast from TileReg + // Column broadcast from BOSCAMETileReg def BOSC_AME_MBCBCE8_M : RVInstBOSCAMEBroadcastTile<0b10110, 0b000, "mbcbce8.m">; def BOSC_AME_MBCBCE16_M : RVInstBOSCAMEBroadcastTile<0b10110, 0b001, "mbcbce16.m">; def BOSC_AME_MBCBCE32_M : RVInstBOSCAMEBroadcastTile<0b10110, 0b010, "mbcbce32.m">; def BOSC_AME_MBCBCE64_M : RVInstBOSCAMEBroadcastTile<0b10110, 0b011, "mbcbce64.m">; - // Column broadcast from AccReg + // Column broadcast from BOSCAMEAccReg def BOSC_AME_MBCCCE8_M : RVInstBOSCAMEBroadcastAcc<0b10100, 0b000, "mbccce8.m">; def BOSC_AME_MBCCCE16_M : RVInstBOSCAMEBroadcastAcc<0b10100, 0b001, "mbccce16.m">; def BOSC_AME_MBCCCE32_M : RVInstBOSCAMEBroadcastAcc<0b10100, 0b010, "mbccce32.m">; def BOSC_AME_MBCCCE64_M : RVInstBOSCAMEBroadcastAcc<0b10100, 0b011, "mbccce64.m">; - // Element broadcast from TileReg + // Element broadcast from BOSCAMETileReg def BOSC_AME_MBCAEE8_M : RVInstBOSCAMEBroadcastTile<0b11001, 0b000, "mbcaee8.m">; def BOSC_AME_MBCAEE16_M : RVInstBOSCAMEBroadcastTile<0b11001, 0b001, "mbcaee16.m">; def BOSC_AME_MBCAEE32_M : RVInstBOSCAMEBroadcastTile<0b11001, 0b010, "mbcaee32.m">; def BOSC_AME_MBCAEE64_M : RVInstBOSCAMEBroadcastTile<0b11001, 0b011, "mbcaee64.m">; - // Element broadcast from TileReg + // Element broadcast from BOSCAMETileReg def BOSC_AME_MBCBEE8_M : RVInstBOSCAMEBroadcastTile<0b11010, 0b000, "mbcbee8.m">; def BOSC_AME_MBCBEE16_M : RVInstBOSCAMEBroadcastTile<0b11010, 0b001, "mbcbee16.m">; def BOSC_AME_MBCBEE32_M : RVInstBOSCAMEBroadcastTile<0b11010, 0b010, "mbcbee32.m">; def BOSC_AME_MBCBEE64_M : RVInstBOSCAMEBroadcastTile<0b11010, 0b011, "mbcbee64.m">; - // Element broadcast from AccReg + // Element broadcast from BOSCAMEAccReg def BOSC_AME_MBCCEE8_M : RVInstBOSCAMEBroadcastAcc<0b11000, 0b000, "mbccee8.m">; def BOSC_AME_MBCCEE16_M : RVInstBOSCAMEBroadcastAcc<0b11000, 0b001, "mbccee16.m">; def BOSC_AME_MBCCEE32_M : RVInstBOSCAMEBroadcastAcc<0b11000, 0b010, "mbccee32.m">; @@ -1386,7 +1386,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 0, mayLoad = 0, mayStore // Matrix Transpose Instructions class RVInstBOSCAMETransposeTile rs2_val, bits<3> eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs TileReg:$md), (ins TileReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMETileReg:$md), (ins BOSCAMETileReg:$ms1), opcodestr, "$md, $ms1"> { bits<5> md; bits<5> ms1; @@ -1401,7 +1401,7 @@ class RVInstBOSCAMETransposeTile rs2_val, bits<3> eew_val, string opcode } class RVInstBOSCAMETransposeAcc rs2_val, bits<3> eew_val, string opcodestr> - : RVInstBOSCAMEMove<(outs AccReg:$md), (ins AccReg:$ms1), + : RVInstBOSCAMEMove<(outs BOSCAMEAccReg:$md), (ins BOSCAMEAccReg:$ms1), opcodestr, "$md, $ms1"> { bits<5> md; bits<5> ms1; @@ -2179,7 +2179,7 @@ let Predicates = [HasVendorXBOSCAME], hasSideEffects = 1, isCodeGenOnly = 1 in { } // Pseudo matrix multiply instruction -// md: AccReg index (0-7), ms1/ms2: TileReg indices (0-7) +// md: BOSCAMEAccReg index (0-7), ms1/ms2: BOSCAMETileReg indices (0-7) // Base Pseudo class for all MMA instructions class RVInstBOSCAMEMMA_Pseudo : Pseudo<(outs), (ins BOSCAMEAccIndex:$md, BOSCAMETileIndex:$ms1, BOSCAMETileIndex:$ms2), []> { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadAME.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadAME.td index 917b0b8af0d5e..b09e2026205e1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadAME.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadAME.td @@ -23,30 +23,30 @@ //===----------------------------------------------------------------------===// // Reference: RISC-V Matrix Extension Specification -def MatrixIndexAsmOperand : AsmOperandClass { - let Name = "MatrixIndex"; +def THeadAMEMatrixIndexAsmOperand : AsmOperandClass { + let Name = "THeadAMEMatrixIndex"; let RenderMethod = "addImmOperands"; let PredicateMethod = "isUImm3"; - let DiagnosticType = "InvalidMatrixIndex"; + let DiagnosticType = "InvalidTHeadAMEMatrixIndex"; } -// Operand type for MatrixReg index (0-7), printed with "m" prefix in AsmString -def MatrixIndex : RISCVOp { - let ParserMatchClass = MatrixIndexAsmOperand; +// Operand type for THeadAMEMatrixReg index (0-7), printed with "m" prefix in AsmString +def THeadAMEMatrixIndex : RISCVOp { + let ParserMatchClass = THeadAMEMatrixIndexAsmOperand; let DecoderMethod = "decodeUImmOperand<3>"; let OperandType = "OPERAND_UIMM3"; } -def MatrixRegAsmOperand : AsmOperandClass { - let Name = "MatrixRegOp"; - let ParserMethod = "parseMatrixReg"; +def THeadAMEMatrixRegAsmOperand : AsmOperandClass { + let Name = "THeadAMEMatrixRegOp"; + let ParserMethod = "parseTHeadAMEMatrixReg"; let RenderMethod = "addRegOperands"; - let PredicateMethod = "isMatrixReg"; + let PredicateMethod = "isTHeadAMEMatrixReg"; } -def MatrixRegOp : RegisterOperand { - let ParserMatchClass = MatrixRegAsmOperand; - let PrintMethod = "printMatrixReg"; +def THeadAMEMatrixRegOp : RegisterOperand { + let ParserMatchClass = THeadAMEMatrixRegAsmOperand; + let PrintMethod = "printTHeadAMEMatrixReg"; } //===----------------------------------------------------------------------===// @@ -54,7 +54,7 @@ def MatrixRegOp : RegisterOperand { //===----------------------------------------------------------------------===// // Base class for XTAME 32-bit matrix multiplication instructions -// Uses MatrixReg for inputs (ms1, ms2) and MatrixReg for output (md) +// Uses THeadAMEMatrixReg for inputs (ms1, ms2) and THeadAMEMatrixReg for output (md) class RVInstXTAME32 : RVInst { bits<4> func4; @@ -84,8 +84,8 @@ class RVInstXTAME32 // AME Matrix Multiplication Instructions //===----------------------------------------------------------------------===// class TH_MMACC type_val, string opcodestr> - : RVInstXTAME32<(outs MatrixRegOp:$md), - (ins MatrixRegOp:$md_in, MatrixRegOp:$ms2, MatrixRegOp:$ms1), + : RVInstXTAME32<(outs THeadAMEMatrixRegOp:$md), + (ins THeadAMEMatrixRegOp:$md_in, THeadAMEMatrixRegOp:$ms2, THeadAMEMatrixRegOp:$ms1), opcodestr, "$md, $ms2, $ms1"> { let Constraints = "$md = $md_in"; let func4 = 0b0010; @@ -114,8 +114,8 @@ def TH_MMACCSU_W_B : TH_MMACC<0b011, "th.mmaccsu.w.b">; // AME Matrix Multiplication Instructions (float) //===----------------------------------------------------------------------===// class TH_MFMACC size_w_val, bits<3> type_val, string opcodestr> - : RVInstXTAME32<(outs MatrixRegOp:$md), - (ins MatrixRegOp:$md_in, MatrixRegOp:$ms2, MatrixRegOp:$ms1), + : RVInstXTAME32<(outs THeadAMEMatrixRegOp:$md), + (ins THeadAMEMatrixRegOp:$md_in, THeadAMEMatrixRegOp:$ms2, THeadAMEMatrixRegOp:$ms1), opcodestr, "$md, $ms2, $ms1"> { let Constraints = "$md = $md_in"; let func4 = 0b0001; @@ -266,7 +266,7 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore // Base class for all 32-bit load instructions (uop = 100) class RVInstXTAMELoad32 func4_val, string opcodestr> - : RVInst<(outs MatrixRegOp:$md), (ins GPR:$rs2, GPR:$rs1), + : RVInst<(outs THeadAMEMatrixRegOp:$md), (ins GPR:$rs2, GPR:$rs1), opcodestr, "$md, $rs2, $rs1", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; @@ -302,7 +302,7 @@ class RVInstXTAMEPrefetch32 func4_val, string opcodestr> // Base class for all 32-bit store instructions (uop = 101) class RVInstXTAMEStore32 func4_val, string opcodestr> - : RVInst<(outs), (ins MatrixRegOp:$ms3, GPR:$rs1, GPR:$rs2), + : RVInst<(outs), (ins THeadAMEMatrixRegOp:$ms3, GPR:$rs1, GPR:$rs2), opcodestr, "$ms3, $rs2, $rs1", [], InstFormatOther> { bits<5> rs2; bits<5> rs1; @@ -471,28 +471,28 @@ class RVInstXTAMEMISC { let uimm3 = 0b000; } // Zero 2 matrix registers (uimm3 = 001) - def TH_MZERO2R : RVInstXTAMEMISC<(outs), (ins MatrixRegOp:$md), + def TH_MZERO2R : RVInstXTAMEMISC<(outs), (ins THeadAMEMatrixRegOp:$md), "th.mzero2r", "$md", 0b1010, 0b000> { let uimm3 = 0b001; } // Zero 4 matrix registers (uimm3 = 011) - def TH_MZERO4R : RVInstXTAMEMISC<(outs), (ins MatrixRegOp:$md), + def TH_MZERO4R : RVInstXTAMEMISC<(outs), (ins THeadAMEMatrixRegOp:$md), "th.mzero4r", "$md", 0b1010, 0b000> { let uimm3 = 0b011; } // Zero 8 matrix registers (uimm3 = 111) - def TH_MZERO8R : RVInstXTAMEMISC<(outs), (ins MatrixRegOp:$md), + def TH_MZERO8R : RVInstXTAMEMISC<(outs), (ins THeadAMEMatrixRegOp:$md), "th.mzero8r", "$md", 0b1010, 0b000> { let uimm3 = 0b111; @@ -531,7 +531,7 @@ class RVInstXTAMEMMOV // th.mmov.mm - move between matrix registers (uop = 000) let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -def TH_MMOV_MM : RVInstXTAMEMMOV<(outs MatrixReg:$md), (ins MatrixReg:$ms1), +def TH_MMOV_MM : RVInstXTAMEMMOV<(outs THeadAMEMatrixReg:$md), (ins THeadAMEMatrixReg:$ms1), "th.mmov.mm", "$md, $ms1"> { let uop = 0b000; let type = 0b001; @@ -562,7 +562,7 @@ class RVInstXTAMESMMOVE func4_val, // matrix-scalar mov with duplicate class TH_MDUP sz, string opcodestr> - : RVInstXTAMESMMOVE<0b0001, (outs MatrixReg:$md), (ins GPR:$rs2), + : RVInstXTAMESMMOVE<0b0001, (outs THeadAMEMatrixReg:$md), (ins GPR:$rs2), opcodestr, "$md, $rs2"> { let rs1 = 0b00000; let size = sz; @@ -581,7 +581,7 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore // matrix-scalar move class TH_MMOV sz, string opcodestr> - : RVInstXTAMESMMOVE<0b0010, (outs MatrixReg:$md), (ins GPR:$rs2, GPR:$rs1), + : RVInstXTAMESMMOVE<0b0010, (outs THeadAMEMatrixReg:$md), (ins GPR:$rs2, GPR:$rs1), opcodestr, "$md, $rs2, $rs1"> { let size = sz; } @@ -599,7 +599,7 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore // scalar-matrix move instructions (uop = 110) class RVInstXTAMEMSMOVE sz, string opcodestr> - : RVInst<(outs GPR:$rd), (ins MatrixReg:$ms2, GPR:$rs1), + : RVInst<(outs GPR:$rd), (ins THeadAMEMatrixReg:$ms2, GPR:$rs1), opcodestr, "$rd, $ms2, $rs1", [], InstFormatOther> { bits<5> rd; bits<3> ms2; @@ -632,7 +632,7 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore // Data Broadcast Instructions class RVInstXTAMEDB func4_val, bits<3> uop_val, bits<2> sz, string opcodestr> - : RVInstXTAME32<(outs MatrixReg:$md), (ins MatrixReg:$ms1, uimm3:$uimm3), + : RVInstXTAME32<(outs THeadAMEMatrixReg:$md), (ins THeadAMEMatrixReg:$ms1, uimm3:$uimm3), opcodestr, "$md, $ms1[$uimm3]"> { bits<3> uimm3; @@ -664,7 +664,7 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 0, mayLoad = 0, mayStore // Matrix Pack Instructions class TH_MPACK type_val, string opcodestr> - : RVInstXTAME32<(outs MatrixReg:$md), (ins MatrixReg:$ms2, MatrixReg:$ms1), + : RVInstXTAME32<(outs THeadAMEMatrixReg:$md), (ins THeadAMEMatrixReg:$ms2, THeadAMEMatrixReg:$ms1), opcodestr, "$md, $ms2, $ms1"> { let func4 = 0b0011; let uop = 0b110; @@ -722,16 +722,16 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore // Zero instruction (single matrix register) let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1 in { - def TH_MZERO_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md), []> { + def TH_MZERO_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md), []> { let AsmString = "th.mzero\tm$md"; } - def TH_MZERO2R_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md), []> { + def TH_MZERO2R_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md), []> { let AsmString = "th.mzero2r\tm$md"; } - def TH_MZERO4R_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md), []> { + def TH_MZERO4R_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md), []> { let AsmString = "th.mzero4r\tm$md"; } - def TH_MZERO8R_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md), []> { + def TH_MZERO8R_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md), []> { let AsmString = "th.mzero8r\tm$md"; } } @@ -740,72 +740,72 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1 in { // 1. Data Move Instructions between Matrix Registers - def TH_MMOV_MM_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1), []> { + def TH_MMOV_MM_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mmov.mm\tm$md, m$ms1"; } // 2. Data Move Instructions between Integer and Matrix (Duplicate) - def TH_MDUPB_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2), []> { + def TH_MDUPB_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2), []> { let AsmString = "th.mdupb.m.x\tm$md, $rs2"; } - def TH_MDUPH_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2), []> { + def TH_MDUPH_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2), []> { let AsmString = "th.mduph.m.x\tm$md, $rs2"; } - def TH_MDUPW_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2), []> { + def TH_MDUPW_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2), []> { let AsmString = "th.mdupw.m.x\tm$md, $rs2"; } - def TH_MDUPD_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2), []> { + def TH_MDUPD_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2), []> { let AsmString = "th.mdupd.m.x\tm$md, $rs2"; } // 3. Data Move Instructions between Integer and Matrix (Scalar to Matrix) - def TH_MMOVB_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MMOVB_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mmovb.m.x\tm$md, $rs2, $rs1"; } - def TH_MMOVH_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MMOVH_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mmovh.m.x\tm$md, $rs2, $rs1"; } - def TH_MMOVW_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MMOVW_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mmovw.m.x\tm$md, $rs2, $rs1"; } - def TH_MMOVD_M_X_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MMOVD_M_X_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mmovd.m.x\tm$md, $rs2, $rs1"; } // 4. Data Move Instructions between Integer and Matrix (Matrix to Scalar) - def TH_MMOVB_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins MatrixIndex:$ms2, GPR:$rs1), []> { + def TH_MMOVB_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins THeadAMEMatrixIndex:$ms2, GPR:$rs1), []> { let AsmString = "th.mmovb.x.m\t$rd, m$ms2, $rs1"; } - def TH_MMOVH_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins MatrixIndex:$ms2, GPR:$rs1), []> { + def TH_MMOVH_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins THeadAMEMatrixIndex:$ms2, GPR:$rs1), []> { let AsmString = "th.mmovh.x.m\t$rd, m$ms2, $rs1"; } - def TH_MMOVW_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins MatrixIndex:$ms2, GPR:$rs1), []> { + def TH_MMOVW_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins THeadAMEMatrixIndex:$ms2, GPR:$rs1), []> { let AsmString = "th.mmovw.x.m\t$rd, m$ms2, $rs1"; } - def TH_MMOVD_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins MatrixIndex:$ms2, GPR:$rs1), []> { + def TH_MMOVD_X_M_PSEUDO : Pseudo<(outs GPR:$rd), (ins THeadAMEMatrixIndex:$ms2, GPR:$rs1), []> { let AsmString = "th.mmovd.x.m\t$rd, m$ms2, $rs1"; } // 5. Data Broadcast Instructions - def TH_MMOV_MV_I_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1, uimm3:$uimm3), []> { + def TH_MMOV_MV_I_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1, uimm3:$uimm3), []> { let AsmString = "th.mmov.mv.i\tm$md, m$ms1[$uimm3]"; } - def TH_MCMOVB_MV_I_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1, uimm3:$uimm3), []> { + def TH_MCMOVB_MV_I_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1, uimm3:$uimm3), []> { let AsmString = "th.mcmovb.mv.i\tm$md, m$ms1[$uimm3]"; } - def TH_MCMOVH_MV_I_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1, uimm3:$uimm3), []> { + def TH_MCMOVH_MV_I_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1, uimm3:$uimm3), []> { let AsmString = "th.mcmovh.mv.i\tm$md, m$ms1[$uimm3]"; } - def TH_MCMOVW_MV_I_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1, uimm3:$uimm3), []> { + def TH_MCMOVW_MV_I_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1, uimm3:$uimm3), []> { let AsmString = "th.mcmovw.mv.i\tm$md, m$ms1[$uimm3]"; } - def TH_MCMOVD_MV_I_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms1, uimm3:$uimm3), []> { + def TH_MCMOVD_MV_I_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms1, uimm3:$uimm3), []> { let AsmString = "th.mcmovd.mv.i\tm$md, m$ms1[$uimm3]"; } // 6. Matrix Pack Instructions - def TH_MPACK_MM_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + def TH_MPACK_MM_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mpack.mm\tm$md, m$ms2, m$ms1"; } - def TH_MPACKHL_MM_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + def TH_MPACKHL_MM_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mpackhl.mm\tm$md, m$ms2, m$ms1"; } - def TH_MPACKHH_MM_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + def TH_MPACKHH_MM_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mpackhh.mm\tm$md, m$ms2, m$ms1"; } } @@ -813,52 +813,52 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore // Load instructions (normal and transposed) let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1 in { - def TH_MLDE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mlde8\tm$md, $rs2, ($rs1)"; } - def TH_MLDE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mlde16\tm$md, $rs2, ($rs1)"; } - def TH_MLDE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mlde32\tm$md, $rs2, ($rs1)"; } - def TH_MLDE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mlde64\tm$md, $rs2, ($rs1)"; } - def TH_MLDTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mldte8\tm$md, $rs2, ($rs1)"; } - def TH_MLDTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mldte16\tm$md, $rs2, ($rs1)"; } - def TH_MLDTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mldte32\tm$md, $rs2, ($rs1)"; } - def TH_MLDTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MLDTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mldte64\tm$md, $rs2, ($rs1)"; } - def TH_MSLDE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mslde8\tm$md, $rs2, ($rs1)"; } - def TH_MSLDE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mslde16\tm$md, $rs2, ($rs1)"; } - def TH_MSLDE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mslde32\tm$md, $rs2, ($rs1)"; } - def TH_MSLDE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mslde64\tm$md, $rs2, ($rs1)"; } - def TH_MSLDTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msldte8\tm$md, $rs2, ($rs1)"; } - def TH_MSLDTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msldte16\tm$md, $rs2, ($rs1)"; } - def TH_MSLDTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msldte32\tm$md, $rs2, ($rs1)"; } - def TH_MSLDTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { + def TH_MSLDTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$md, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msldte64\tm$md, $rs2, ($rs1)"; } } @@ -895,52 +895,52 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 1, mayStore // Store instruction let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1 in { - def TH_MSTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mste8\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mste16\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mste32\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mste64\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mstte8\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mstte16\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mstte32\tm$ms3, $rs2, ($rs1)"; } - def TH_MSTTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSTTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.mstte64\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msste8\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msste16\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msste32\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msste64\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTTE8_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTTE8_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msstte8\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTTE16_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTTE16_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msstte16\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTTE32_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTTE32_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msstte32\tm$ms3, $rs2, ($rs1)"; } - def TH_MSSTTE64_PSEUDO : Pseudo<(outs), (ins MatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { + def TH_MSSTTE64_PSEUDO : Pseudo<(outs), (ins THeadAMEMatrixIndex:$ms3, GPR:$rs2, GPR:$rs1), []> { let AsmString = "th.msstte64\tm$ms3, $rs2, ($rs1)"; } } @@ -949,71 +949,71 @@ let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, mayLoad = 0, mayStore let Predicates = [HasVendorXTHeadAME], hasSideEffects = 1, isCodeGenOnly = 1 in { def TH_MMACC_W_B_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mmacc.w.b\tm$md, m$ms2, m$ms1"; } def TH_MMACCU_W_B_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mmaccu.w.b\tm$md, m$ms2, m$ms1"; } def TH_MMACCUS_W_B_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mmaccus.w.b\tm$md, m$ms2, m$ms1"; } def TH_MMACCSU_W_B_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mmaccsu.w.b\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_H_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.h\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_BF16_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.bf16\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_S_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.s\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_D_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.d\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_H_E4M3_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.h.e4m3\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_H_E5M2_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.h.e5m2\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_BF16_E4M3_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.bf16.e4m3\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_BF16_E5M2_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.bf16.e5m2\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_S_H_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.s.h\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_S_BF16_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.s.bf16\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_D_S_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.d.s\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_S_E4M3_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.s.e4m3\tm$md, m$ms2, m$ms1"; } def TH_MFMACC_S_E5M2_PSEUDO : Pseudo<(outs), - (ins MatrixIndex:$md, MatrixIndex:$ms2, MatrixIndex:$ms1), []> { + (ins THeadAMEMatrixIndex:$md, THeadAMEMatrixIndex:$ms2, THeadAMEMatrixIndex:$ms1), []> { let AsmString = "th.mfmacc.s.e5m2\tm$md, m$ms2, m$ms1"; } } diff --git a/llvm/lib/Target/RISCV/RISCVMatrixExt.td b/llvm/lib/Target/RISCV/RISCVMatrixExt.td index c2c660a268074..a2939a319e857 100644 --- a/llvm/lib/Target/RISCV/RISCVMatrixExt.td +++ b/llvm/lib/Target/RISCV/RISCVMatrixExt.td @@ -20,20 +20,9 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// AME (RISC-V Matrix Extension) Register Definitions +// Vendor-Specific AME (RISC-V Matrix Extension) Register Definitions //===----------------------------------------------------------------------===// -// Reference: RISC-V Matrix Extension Specification -// -// Matrix Registers: -// - 8 Tile Registers (tr0-tr7): For input matrices A and B -// Each tile register has MLEN bits of state -// - 8 Accumulation Registers (acc0-acc7): For output/accumulation matrix C -// Each accumulation register has MLEN × AMUL bits of state -// -// AMUL (Accumulation MULtiplier): -// - Can be fractional (1/8, 1/4, 1/2) or integer (1, 2, 4, 8) -// - Determines the width ratio between acc and tr registers -// - For mmi8i32 (int8→int32 quad-widen), AMUL ≥ 4 +// Reference: Vendor-Specific RISC-V Matrix Extension Specifications // // Data Flow: // Memory → tr (via mlae/mlbe) → acc (via mma/mwma/mqma) → Memory (via msce) @@ -41,77 +30,65 @@ let Namespace = "RISCV" in { -//===----------------------------------------------------------------------===// -// AME Tile Registers (tr0-tr7) -// Used for input matrices A and B -// Size: MLEN bits per register (hardware-defined) -//===----------------------------------------------------------------------===// - -// Base class for Tile Registers -class AMETileReg Enc, string n> : Register { - let HWEncoding{2-0} = Enc; - let HWEncoding{4-3} = 0b00; // Distinguish from accumulation registers -} - -// Define 8 Tile Registers: tr0-tr7 -def TR0 : AMETileReg<0, "tr0">; -def TR1 : AMETileReg<1, "tr1">; -def TR2 : AMETileReg<2, "tr2">; -def TR3 : AMETileReg<3, "tr3">; -def TR4 : AMETileReg<4, "tr4">; -def TR5 : AMETileReg<5, "tr5">; -def TR6 : AMETileReg<6, "tr6">; -def TR7 : AMETileReg<7, "tr7">; - -//===----------------------------------------------------------------------===// -// AME Accumulation Registers (acc0-acc7) -// Used for output/accumulation matrix C -// Size: MLEN × AMUL bits per register (hardware-defined) -// -// Note: AMUL can be: -// - Fractional (1/8, 1/4, 1/2): For C = A × Bᵀ mode with large K -// - Integer (1, 2, 4, 8): For widening operations -// * AMUL=4: Required for mmi8i32 (int8→int32 quad-widen) -// * AMUL=2: Required for mmi16i32 (int16→int32 double-widen) -// * AMUL=8: Required for mmi4i32 (int4→int32 oct-widen) -//===----------------------------------------------------------------------===// - -// Base class for Accumulation Registers -class AMEAccReg Enc, string n> : Register { - let HWEncoding{2-0} = Enc; - let HWEncoding{4-3} = 0b01; // Distinguish from tile registers -} - -// Define 8 Accumulation Registers: acc0-acc7 -def ACC0 : AMEAccReg<0, "acc0">; -def ACC1 : AMEAccReg<1, "acc1">; -def ACC2 : AMEAccReg<2, "acc2">; -def ACC3 : AMEAccReg<3, "acc3">; -def ACC4 : AMEAccReg<4, "acc4">; -def ACC5 : AMEAccReg<5, "acc5">; -def ACC6 : AMEAccReg<6, "acc6">; -def ACC7 : AMEAccReg<7, "acc7">; - -//===----------------------------------------------------------------------===// -// XuanTie AME Matrix Registers (m0-m7) -//===----------------------------------------------------------------------===// -// -// Upstream RISCVRegisterInfo.td already defines M0-M7 as mask registers. Keep -// the TableGen def names distinct while preserving the XTAME assembly names. - -class AMEMatrixReg Enc, string n> : Register { - let HWEncoding{2-0} = Enc; - let HWEncoding{4-3} = 0b10; -} - -def AMEM0 : AMEMatrixReg<0, "amem0">; -def AMEM1 : AMEMatrixReg<1, "amem1">; -def AMEM2 : AMEMatrixReg<2, "amem2">; -def AMEM3 : AMEMatrixReg<3, "amem3">; -def AMEM4 : AMEMatrixReg<4, "amem4">; -def AMEM5 : AMEMatrixReg<5, "amem5">; -def AMEM6 : AMEMatrixReg<6, "amem6">; -def AMEM7 : AMEMatrixReg<7, "amem7">; + // Base class for BOSCAME Tile Registers (tr0-7) + // Used for input matrices A and B + // Size: MLEN bits per register (hardware-defined) + class BOSCAMETileReg Enc, string n> : Register { + let HWEncoding{2 - 0} = Enc; + let HWEncoding{4 - 3} = 0b00; // Distinguish from accumulation registers + } + + // Define 8 BOSCAME Tile Registers: tr0-tr7 + def BOSCAMETR0 : BOSCAMETileReg<0, "tr0">; + def BOSCAMETR1 : BOSCAMETileReg<1, "tr1">; + def BOSCAMETR2 : BOSCAMETileReg<2, "tr2">; + def BOSCAMETR3 : BOSCAMETileReg<3, "tr3">; + def BOSCAMETR4 : BOSCAMETileReg<4, "tr4">; + def BOSCAMETR5 : BOSCAMETileReg<5, "tr5">; + def BOSCAMETR6 : BOSCAMETileReg<6, "tr6">; + def BOSCAMETR7 : BOSCAMETileReg<7, "tr7">; + + // Base class for BOSCAME Accumulation Registers (acc0-acc7) + // Used for output/accumulation matrix C + // Size: MLEN × AMUL bits per register (hardware-defined) + // Note: AMUL can be: + // - Fractional (1/8, 1/4, 1/2): For C = A × Bᵀ mode with large K + // - Integer (1, 2, 4, 8): For widening operations + // * AMUL=4: Required for mmi8i32 (int8→int32 quad-widen) + // * AMUL=2: Required for mmi16i32 (int16→int32 double-widen) + // * AMUL=8: Required for mmi4i32 (int4→int32 oct-widen) + class BOSCAMEAccReg Enc, string n> : Register { + let HWEncoding{2 - 0} = Enc; + let HWEncoding{4 - 3} = 0b01; // Distinguish from tile registers + } + + // Define 8 BOSCAME Accumulation Registers: acc0-acc7 + def BOSCAMEACC0 : BOSCAMEAccReg<0, "acc0">; + def BOSCAMEACC1 : BOSCAMEAccReg<1, "acc1">; + def BOSCAMEACC2 : BOSCAMEAccReg<2, "acc2">; + def BOSCAMEACC3 : BOSCAMEAccReg<3, "acc3">; + def BOSCAMEACC4 : BOSCAMEAccReg<4, "acc4">; + def BOSCAMEACC5 : BOSCAMEAccReg<5, "acc5">; + def BOSCAMEACC6 : BOSCAMEAccReg<6, "acc6">; + def BOSCAMEACC7 : BOSCAMEAccReg<7, "acc7">; + + // Base class for XuanTie AME Matrix Registers (m0-m7) + class THeadAMEMatrixReg Enc, string n> : Register { + let HWEncoding{2 - 0} = Enc; + let HWEncoding{4 - 3} = 0b10; + } + + // Define 8 XuanTie AME Matrix Registers: m0-m7 + // Upstream RISCVRegisterInfo.td already defines M0-M7 as mask registers. Keep + // the TableGen def names distinct while preserving the XTAME assembly names. + def THeadAMEM0 : THeadAMEMatrixReg<0, "amem0">; + def THeadAMEM1 : THeadAMEMatrixReg<1, "amem1">; + def THeadAMEM2 : THeadAMEMatrixReg<2, "amem2">; + def THeadAMEM3 : THeadAMEMatrixReg<3, "amem3">; + def THeadAMEM4 : THeadAMEMatrixReg<4, "amem4">; + def THeadAMEM5 : THeadAMEMatrixReg<5, "amem5">; + def THeadAMEM6 : THeadAMEMatrixReg<6, "amem6">; + def THeadAMEM7 : THeadAMEMatrixReg<7, "amem7">; } // End Namespace = "RISCV" @@ -119,36 +96,36 @@ def AMEM7 : AMEMatrixReg<7, "amem7">; // AME Register Classes //===----------------------------------------------------------------------===// // These register classes define the operand types for AME instructions -// -// Usage in instructions: -// - TileReg: For ms1, ms2 (source operands in multiplication) -// - AccReg: For md (destination/accumulator in multiplication) -// - TileReg: For load/store of input matrices (A, B) -// - AccReg: For load/store of output/accumulator (C) //===----------------------------------------------------------------------===// // Tile Register class (tr0-tr7) -// Used for input operands in matrix multiplication -// Note: Size is set to 256 as a placeholder; actual size depends on MLEN -def TileReg : RegisterClass<"RISCV", [untyped], 256, - (add TR0, TR1, TR2, TR3, TR4, TR5, TR6, TR7)> { - let Size = 256; // Placeholder: actual MLEN is hardware-defined +// Used for input operands in matrix multiplication and load/store of input +// matrices Note: Size is set to 256 as a placeholder; actual size depends on +// MLEN +def BOSCAMETileReg + : RegisterClass<"RISCV", [untyped], 256, + (add BOSCAMETR0, BOSCAMETR1, BOSCAMETR2, BOSCAMETR3, + BOSCAMETR4, BOSCAMETR5, BOSCAMETR6, BOSCAMETR7)> { + let Size = 256; // Placeholder: actual MLEN is hardware-defined } // Accumulation Register class (acc0-acc7) -// Used for output/accumulator in matrix multiplication -// Note: Size can be 256×AMUL where AMUL ∈ {1/8, 1/4, 1/2, 1, 2, 4, 8} -// We use 1024 as a reasonable upper bound (256 × 4 for int8→int32) -def AccReg : RegisterClass<"RISCV", [untyped], 1024, - (add ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7)> { - let Size = 1024; // Placeholder: actual MLEN×AMUL is hardware-defined +// Used for output/accumulator in matrix multiplication and load/store of +// output/accumulator Note: Size can be 256×AMUL where AMUL ∈ {1/8, 1/4, 1/2, 1, +// 2, 4, 8} We use 1024 as a reasonable upper bound (256 × 4 for int8→int32) +def BOSCAMEAccReg + : RegisterClass<"RISCV", [untyped], 1024, + (add BOSCAMEACC0, BOSCAMEACC1, BOSCAMEACC2, BOSCAMEACC3, + BOSCAMEACC4, BOSCAMEACC5, BOSCAMEACC6, BOSCAMEACC7)> { + let Size = 1024; // Placeholder: actual MLEN×AMUL is hardware-defined } // XuanTie AME matrix register class. -def MatrixReg : RegisterClass<"RISCV", [untyped], 1024, - (add AMEM0, AMEM1, AMEM2, AMEM3, - AMEM4, AMEM5, AMEM6, AMEM7)> { - let Size = 1024; // Placeholder: actual MLEN is hardware-defined +def THeadAMEMatrixReg + : RegisterClass<"RISCV", [untyped], 1024, + (add THeadAMEM0, THeadAMEM1, THeadAMEM2, THeadAMEM3, + THeadAMEM4, THeadAMEM5, THeadAMEM6, THeadAMEM7)> { + let Size = 1024; // Placeholder: actual MLEN is hardware-defined } include "RISCVInstrInfoXBOSCAME.td" From 139edff2f12bb7d2454edede9cd27119c98e2ec8 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Wed, 15 Jul 2026 19:57:30 +0000 Subject: [PATCH 03/10] [RISCV: Feat] Add AME(Ztt) instruction defs and encodings --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 28 +- .../RISCV/Disassembler/RISCVDisassembler.cpp | 45 +- .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 19 +- .../RISCV/MCTargetDesc/RISCVInstPrinter.h | 4 +- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 34 +- llvm/lib/Target/RISCV/RISCVFeatures.td | 7 + llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 390 ++++++++++++++++++ llvm/lib/Target/RISCV/RISCVMatrixExt.td | 98 +++-- 8 files changed, 532 insertions(+), 93 deletions(-) create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 0d77f5f32995e..a859acd23ee45 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -221,7 +221,7 @@ class RISCVAsmParser : public MCTargetAsmParser { ParseStatus parseJALOffset(OperandVector &Operands); ParseStatus parseVTypeI(OperandVector &Operands); ParseStatus parseMaskReg(OperandVector &Operands); - ParseStatus parseMatrixReg(OperandVector &Operands); + ParseStatus parseTHeadAMEMatrixReg(OperandVector &Operands); ParseStatus parseVScaleReg(OperandVector &Operands); ParseStatus parseTileLambda(OperandVector &Operands); ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands); @@ -494,9 +494,9 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isV0Reg() const { return Kind == KindTy::Register && Reg.Reg == RISCV::V0; } - bool isMatrixReg() const { - return Kind == KindTy::Register && Reg.Reg >= RISCV::AMEM0 && - Reg.Reg <= RISCV::AMEM7; + bool isTHeadAMEMatrixReg() const { + return Kind == KindTy::Register && Reg.Reg >= RISCV::THeadAMEM0 && + Reg.Reg <= RISCV::THeadAMEM7; } bool isAnyReg() const { return Kind == KindTy::Register && @@ -1277,7 +1277,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { } static std::unique_ptr createRegList(unsigned RlistEncode, - SMLoc S) { + SMLoc S) { auto Op = std::make_unique(KindTy::RegList); Op->RegList.Encoding = RlistEncode; Op->StartLoc = S; @@ -1294,7 +1294,8 @@ struct RISCVOperand final : public MCParsedAsmOperand { return Op; } - static std::unique_ptr createStackAdj(unsigned StackAdj, SMLoc S) { + static std::unique_ptr createStackAdj(unsigned StackAdj, + SMLoc S) { auto Op = std::make_unique(KindTy::StackAdj); Op->StackAdj.Val = StackAdj; Op->StartLoc = S; @@ -2271,8 +2272,8 @@ ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) { if (IsNegative) RealVal.changeSign(); - Operands.push_back(RISCVOperand::createFPImm( - RealVal.bitcastToAPInt().getZExtValue(), S)); + Operands.push_back( + RISCVOperand::createFPImm(RealVal.bitcastToAPInt().getZExtValue(), S)); Lex(); // Eat the token. @@ -2654,7 +2655,7 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) { return ParseStatus::Success; } -ParseStatus RISCVAsmParser::parseMatrixReg(OperandVector &Operands) { +ParseStatus RISCVAsmParser::parseTHeadAMEMatrixReg(OperandVector &Operands) { if (getLexer().isNot(AsmToken::Identifier)) return ParseStatus::NoMatch; @@ -2666,7 +2667,7 @@ ParseStatus RISCVAsmParser::parseMatrixReg(OperandVector &Operands) { SMLoc E = getTok().getEndLoc(); getLexer().Lex(); Operands.push_back( - RISCVOperand::createReg(RISCV::AMEM0 + (Name[1] - '0'), S, E)); + RISCVOperand::createReg(RISCV::THeadAMEM0 + (Name[1] - '0'), S, E)); return ParseStatus::Success; } @@ -3399,9 +3400,10 @@ bool RISCVAsmParser::parseDirectiveOption() { std::string Buffer; raw_string_ostream OutputErrMsg(Buffer); - handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { - OutputErrMsg << ErrMsg.getMessage(); - }); + handleAllErrors(ParseResult.takeError(), + [&](llvm::StringError &ErrMsg) { + OutputErrMsg << ErrMsg.getMessage(); + }); return Error(Loc, OutputErrMsg.str()); } diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index db9cc6686e579..b590dfe2ed90a 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Endian.h" +#include using namespace llvm; using namespace llvm::MCD; @@ -96,28 +97,44 @@ static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, uint32_t RegNo, constexpr auto DecodeGPRRegisterClass = DecodeSimpleRegisterClass; -static DecodeStatus DecodeTileRegRegisterClass(MCInst &Inst, uint32_t RegNo, - uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeSimpleRegisterClass(Inst, RegNo, Address, - Decoder); +static DecodeStatus +DecodeBOSCAMETileRegRegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + return DecodeSimpleRegisterClass(Inst, RegNo, Address, + Decoder); } -static DecodeStatus DecodeAccRegRegisterClass(MCInst &Inst, uint32_t RegNo, - uint64_t Address, - const MCDisassembler *Decoder) { +static DecodeStatus +DecodeBOSCAMEAccRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, + const MCDisassembler *Decoder) { if (RegNo < 8 || RegNo > 15) return MCDisassembler::Fail; - Inst.addOperand(MCOperand::createReg(RISCV::ACC0 + (RegNo - 8))); + Inst.addOperand(MCOperand::createReg(RISCV::BOSCAMEACC0 + (RegNo - 8))); return MCDisassembler::Success; } -static DecodeStatus DecodeMatrixRegRegisterClass( - MCInst &Inst, uint32_t RegNo, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeSimpleRegisterClass(Inst, RegNo, Address, - Decoder); +static DecodeStatus +DecodeTHeadAMEMatrixRegRegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + return DecodeSimpleRegisterClass(Inst, RegNo, Address, + Decoder); +} + +static DecodeStatus +DecodeAMEAccRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, + const MCDisassembler *Decoder) { + return DecodeSimpleRegisterClass(Inst, RegNo, Address, + Decoder); +} + +static DecodeStatus +DecodeAMEMatrixRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, + const MCDisassembler *Decoder) { + return DecodeSimpleRegisterClass(Inst, RegNo, Address, + Decoder); } static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp index b1a8595464fc3..2b632fab2d526 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -13,6 +13,7 @@ #include "RISCVInstPrinter.h" #include "RISCVBaseInfo.h" #include "RISCVMCAsmInfo.h" +#include "RISCVMCTargetDesc.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -148,7 +149,7 @@ void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { unsigned FenceArg = MI->getOperand(OpNo).getImm(); - assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); + assert(((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); if ((FenceArg & RISCVFenceField::I) != 0) O << 'i'; @@ -259,7 +260,8 @@ void RISCVInstPrinter::printXSfmmVType(const MCInst *MI, unsigned OpNo, // than ABI register names, we need to print "{x1, x8-x9, x18-x27}" for all // registers. Otherwise, we print "{ra, s0-s11}". void RISCVInstPrinter::printRegList(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { unsigned Imm = MI->getOperand(OpNo).getImm(); assert(Imm >= RISCVZC::RLISTENCODE::RA && @@ -346,15 +348,16 @@ void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo, O << ".t"; } -void RISCVInstPrinter::printMatrixReg(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, - raw_ostream &O) { +void RISCVInstPrinter::printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { const MCOperand &MO = MI->getOperand(OpNo); - assert(MO.isReg() && "printMatrixReg can only print register operands"); - assert(MO.getReg() >= RISCV::AMEM0 && MO.getReg() <= RISCV::AMEM7 && + assert(MO.isReg() && + "printTHeadAMEMatrixReg can only print register operands"); + assert(MO.getReg() >= RISCV::THeadAMEM0 && MO.getReg() <= RISCV::THeadAMEM7 && "unexpected matrix register"); - O << "m" << (MO.getReg() - RISCV::AMEM0); + O << "m" << (MO.getReg() - RISCV::THeadAMEM0); } void RISCVInstPrinter::printVScaleReg(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h index 63492a70f7dea..454abdb71afb3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -54,8 +54,8 @@ class RISCVInstPrinter : public MCInstPrinter { const MCSubtargetInfo &STI, raw_ostream &O); void printVMaskReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); - void printMatrixReg(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, raw_ostream &O); + void printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printVScaleReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printTileLambda(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index f19e064359441..2757b57bf2883 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/RISCVELFStreamer.h" #include "MCTargetDesc/RISCVInstPrinter.h" #include "MCTargetDesc/RISCVMCAsmInfo.h" +#include "MCTargetDesc/RISCVMCTargetDesc.h" #include "MCTargetDesc/RISCVMatInt.h" #include "MCTargetDesc/RISCVTargetStreamer.h" #include "RISCV.h" @@ -379,26 +380,29 @@ void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, Hint); } -static unsigned getAMETileReg(unsigned Index) { - static const unsigned Regs[] = {RISCV::TR0, RISCV::TR1, RISCV::TR2, - RISCV::TR3, RISCV::TR4, RISCV::TR5, - RISCV::TR6, RISCV::TR7}; +static unsigned getBOSCAMETileReg(unsigned Index) { + static const unsigned Regs[] = {RISCV::BOSCAMETR0, RISCV::BOSCAMETR1, + RISCV::BOSCAMETR2, RISCV::BOSCAMETR3, + RISCV::BOSCAMETR4, RISCV::BOSCAMETR5, + RISCV::BOSCAMETR4, RISCV::BOSCAMETR7}; assert(Index < 8 && "invalid AME tile register index"); return Regs[Index]; } -static unsigned getAMEAccReg(unsigned Index) { - static const unsigned Regs[] = {RISCV::ACC0, RISCV::ACC1, RISCV::ACC2, - RISCV::ACC3, RISCV::ACC4, RISCV::ACC5, - RISCV::ACC6, RISCV::ACC7}; +static unsigned getBOSCAMEAccReg(unsigned Index) { + static const unsigned Regs[] = {RISCV::BOSCAMEACC0, RISCV::BOSCAMEACC1, + RISCV::BOSCAMEACC2, RISCV::BOSCAMEACC3, + RISCV::BOSCAMEACC4, RISCV::BOSCAMEACC5, + RISCV::BOSCAMEACC6, RISCV::BOSCAMEACC7}; assert(Index < 8 && "invalid AME accumulator register index"); return Regs[Index]; } -static unsigned getAMEMatrixReg(unsigned Index) { - static const unsigned Regs[] = {RISCV::AMEM0, RISCV::AMEM1, RISCV::AMEM2, - RISCV::AMEM3, RISCV::AMEM4, RISCV::AMEM5, - RISCV::AMEM6, RISCV::AMEM7}; +static unsigned getTHeadAMEMatrixReg(unsigned Index) { + static const unsigned Regs[] = {RISCV::THeadAMEM0, RISCV::THeadAMEM1, + RISCV::THeadAMEM2, RISCV::THeadAMEM3, + RISCV::THeadAMEM4, RISCV::THeadAMEM5, + RISCV::THeadAMEM6, RISCV::THeadAMEM7}; assert(Index < 8 && "invalid AME matrix register index"); return Regs[Index]; } @@ -419,15 +423,15 @@ bool RISCVAsmPrinter::lowerMatrixExtPseudo(const MachineInstr *MI, auto AddTileIndex = [&](unsigned OpNo) { Inst.addOperand( - MCOperand::createReg(getAMETileReg(MI->getOperand(OpNo).getImm()))); + MCOperand::createReg(getBOSCAMETileReg(MI->getOperand(OpNo).getImm()))); }; auto AddAccIndex = [&](unsigned OpNo) { Inst.addOperand( - MCOperand::createReg(getAMEAccReg(MI->getOperand(OpNo).getImm()))); + MCOperand::createReg(getBOSCAMEAccReg(MI->getOperand(OpNo).getImm()))); }; auto AddMatrixIndex = [&](unsigned OpNo) { Inst.addOperand(MCOperand::createReg( - getAMEMatrixReg(MI->getOperand(OpNo).getImm()))); + getTHeadAMEMatrixReg(MI->getOperand(OpNo).getImm()))); }; switch (MI->getOpcode()) { diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index dc1533bf6a213..088c375ee83e9 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -957,6 +957,13 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">, AssemblerPredicate<(all_of FeatureStdExtZvvmttls), "'Zvvmttls' (Transposing Matrix Tile Load/Store)">; +// Attached Matrix Extension +def FeatureStdExtZtt + : RISCVExtension<0, 1, "Attached Matrix Extension">; +def HasStdExtZtt : Predicate<"Subtarget->hasStdExtZtt()">, + AssemblerPredicate<(all_of FeatureStdExtZtt), + "'Ztt' (Attached Matrix Extension)">; + // Zvbdota family of batched dot-product extensions def FeatureStdExtZvqwbdota8i : RISCVExperimentalExtension<0, 2, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td new file mode 100644 index 0000000000000..adedf5ba20734 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -0,0 +1,390 @@ +//===- RISCVInstrInfoZtt.td - 'Ztt' ----------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard 'Ztt' +// extension, providing Attached Matrix Extension instructions. +// This version is still experimental as the 'Ztt' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +// AME (Ztt) 32-bit instruction template +class RVInstAME32 funct7, dag outs, dag ins, string opcodestr, + string argstr> + : RVInst { + let Inst{31 - 25} = funct7; + let Inst{6 - 0} = 0b0101011; // RISC-V custom-1 opcode space +} + +// Base class for single matrix input, matrix output instructions (op md, ms1). +// Input and output are matrix registers +class AME_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> + : RVInstAME32 { + bits<5> ms1; + bits<5> md; + + // unused here; other instructions use this slot to encode ms2/xs1 + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = ms1; + let Inst{14 - 12} = funct3; + let Inst{11 - 7} = md; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + def AME_MABS_EW : AME_UNARYELEMENTWISE<0b0000000, 0b001, "mabs.ew">; + def AME_MCOLUNZIP_EW : AME_UNARYELEMENTWISE<0b0000100, 0b001, "mcolunzip.ew">; + def AME_MCOLZIP_EW : AME_UNARYELEMENTWISE<0b0000011, 0b001, "mcolzip.ew">; + def AME_MCONV_EW : AME_UNARYELEMENTWISE<0b0000000, 0b101, "mconv.ew">; + def AME_MEXP2_EW : AME_UNARYELEMENTWISE<0b0000001, 0b001, "mexp2.ew">; + def AME_MLOG2_EW : AME_UNARYELEMENTWISE<0b0000010, 0b001, "mlog2.ew">; + def AME_MPREFIXADD_COL : AME_UNARYELEMENTWISE<0b0001100, 0b001, "mprefixadd.col">; + def AME_MPREFIXADD_ROW : AME_UNARYELEMENTWISE<0b0001000, 0b001, "mprefixadd.row">; + def AME_MPREFIXMAX_COL : AME_UNARYELEMENTWISE<0b0001101, 0b001, "mprefixmax.col">; + def AME_MPREFIXMAX_ROW : AME_UNARYELEMENTWISE<0b0001001, 0b001, "mprefixmax.row">; + def AME_MREDUCEADD_COL : AME_UNARYELEMENTWISE<0b0001010, 0b001, "mreduceadd.col">; + def AME_MREDUCEADD_ROW : AME_UNARYELEMENTWISE<0b0000110, 0b001, "mreduceadd.row">; + def AME_MREDUCEMAX_COL : AME_UNARYELEMENTWISE<0b0001011, 0b001, "mreducemax.col">; + def AME_MREDUCEMAX_ROW : AME_UNARYELEMENTWISE<0b0000111, 0b001, "mreducemax.row">; + def AME_MROWUNZIP_EW : AME_UNARYELEMENTWISE<0b0000101, 0b001, "mrowunzip.ew">; +} + +// Base class for binary matrix input, matrix output instructions +// (op md, ms1, ms2). +class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> + : RVInstAME32 { + bits<5> ms1; + bits<5> ms2; + bits<5> md; + + let Inst{24 - 20} = ms2; + let Inst{19 - 15} = ms1; + let Inst{14 - 12} = funct3; + let Inst{11 - 7} = md; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + def AME_MABSDIFF_EW : AME_BINARYELEMENTWISE<0b0000100, 0b000, "mabsdiff.ew">; + def AME_MADD_EW : AME_BINARYELEMENTWISE<0b0000000, 0b000, "madd.ew">; + def AME_MAND_EW : AME_BINARYELEMENTWISE<0b0000111, 0b000, "mand.ew">; + def AME_MANDNOT_EW : AME_BINARYELEMENTWISE<0b0001000, 0b000, "mandnot.ew">; + def AME_MCMOVGE_EW : AME_BINARYELEMENTWISE<0b0010000, 0b000, "mcmovge.ew">; + def AME_MCMOVLT_EW : AME_BINARYELEMENTWISE<0b0010001, 0b000, "mcmovlt.ew">; + def AME_MCMPGE_EW : AME_BINARYELEMENTWISE<0b0001100, 0b000, "mcmpge.ew">; + def AME_MCMPLT_EW : AME_BINARYELEMENTWISE<0b0001101, 0b000, "mcmplt.ew">; + def AME_MGATHER_EW : AME_BINARYELEMENTWISE<0b0011000, 0b000, "mgather.ew">; + def AME_MHDIFF_EW : AME_BINARYELEMENTWISE<0b0000011, 0b000, "mhdiff.ew">; + def AME_MLDEXP_EW : AME_BINARYELEMENTWISE<0b0010010, 0b000, "mldexp.ew">; + def AME_MLDEXPACC_EW : AME_BINARYELEMENTWISE<0b0010011, 0b000, "mldexpacc.ew">; + def AME_MLOG2SUB_EW : AME_BINARYELEMENTWISE<0b0010110, 0b000, "mlog2sub.ew">; + def AME_MMAX_EW : AME_BINARYELEMENTWISE<0b0000101, 0b000, "mmax.ew">; + def AME_MMEAN_EW : AME_BINARYELEMENTWISE<0b0000010, 0b000, "mmean.ew">; + def AME_MMIN_EW : AME_BINARYELEMENTWISE<0b0000110, 0b000, "mmin.ew">; + def AME_MMUL_EW : AME_BINARYELEMENTWISE<0b0011100, 0b000, "mmul.ew">; + def AME_MMULACC_EW : AME_BINARYELEMENTWISE<0b0011101, 0b000, "mmulacc.ew">; + def AME_MMULACCNEG_EW : AME_BINARYELEMENTWISE<0b0100000, 0b000, "mmulaccneg.ew">; + def AME_MMULADD_EW : AME_BINARYELEMENTWISE<0b0011110, 0b000, "mmuladd.ew">; + def AME_MMULNEG_EW : AME_BINARYELEMENTWISE<0b0100001, 0b000, "mmulneg.ew">; + def AME_MMULSUB_EW : AME_BINARYELEMENTWISE<0b0011111, 0b000, "mmulsub.ew">; + def AME_MOR_EW : AME_BINARYELEMENTWISE<0b0001001, 0b000, "mor.ew">; + def AME_MORNOT_EW : AME_BINARYELEMENTWISE<0b0001010, 0b000, "mornot.ew">; + def AME_MRDEXP_EW : AME_BINARYELEMENTWISE<0b0010100, 0b000, "mrdexp.ew">; + def AME_MRDEXPACC_EW : AME_BINARYELEMENTWISE<0b0010101, 0b000, "mrdexpacc.ew">; + def AME_MROWZIP_EW : AME_BINARYELEMENTWISE<0b0011011, 0b000, "mrowzip.ew">; + def AME_MSCATADD_COL : AME_BINARYELEMENTWISE<0b0100010, 0b000, "mscatadd.col">; + def AME_MSCATADD_ROW : AME_BINARYELEMENTWISE<0b0011001, 0b000, "mscatadd.row">; + def AME_MSCATMAX_COL : AME_BINARYELEMENTWISE<0b0100011, 0b000, "mscatmax.col">; + def AME_MSCATMAX_ROW : AME_BINARYELEMENTWISE<0b0011010, 0b000, "mscatmax.row">; + def AME_MSELGE_EW : AME_BINARYELEMENTWISE<0b0001110, 0b000, "mselge.ew">; + def AME_MSELLT_EW : AME_BINARYELEMENTWISE<0b0001111, 0b000, "msellt.ew">; + def AME_MSUB_EW : AME_BINARYELEMENTWISE<0b0000001, 0b000, "msub.ew">; + def AME_MSUBLOG2_EW : AME_BINARYELEMENTWISE<0b0010111, 0b000, "msublog2.ew">; + def AME_MXOR_EW : AME_BINARYELEMENTWISE<0b0001011, 0b000, "mxor.ew">; +} + +// Base class for binary matrix input, matrix output instructions where the +// second source is a scalar GPR instead of a matrix register +// (op md, xs1, ms2). Scalar type is inferred from Md[ms2]. +class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> + : RVInstAME32 { + bits<5> xs1; + bits<5> ms2; + bits<5> md; + + let Inst{24 - 20} = ms2; + let Inst{19 - 15} = xs1; + let Inst{14 - 12} = funct3; + let Inst{11 - 7} = md; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + def AME_MABSDIFF_EW_X : AME_BINARYELEMENTWISE_X<0b0000101, 0b010, "mabsdiff.ew.x">; + def AME_MADD_EW_X : AME_BINARYELEMENTWISE_X<0b0000000, 0b010, "madd.ew.x">; + def AME_MAND_EW_X : AME_BINARYELEMENTWISE_X<0b0000111, 0b010, "mand.ew.x">; + def AME_MANDNOT_EW_X : AME_BINARYELEMENTWISE_X<0b0001000, 0b010, "mandnot.ew.x">; + def AME_MCMPGE_EW_X : AME_BINARYELEMENTWISE_X<0b0001100, 0b010, "mcmpge.ew.x">; + def AME_MCMPLT_EW_X : AME_BINARYELEMENTWISE_X<0b0001101, 0b010, "mcmplt.ew.x">; + def AME_MHDIFF_EW_X : AME_BINARYELEMENTWISE_X<0b0000110, 0b010, "mhdiff.ew.x">; + def AME_MLDEXP_EW_X : AME_BINARYELEMENTWISE_X<0b0010000, 0b010, "mldexp.ew.x">; + def AME_MLDEXPACC_EW_X : AME_BINARYELEMENTWISE_X<0b0010001, 0b010, "mldexpacc.ew.x">; + def AME_MLOG2SUB_EW_X : AME_BINARYELEMENTWISE_X<0b0001110, 0b010, "mlog2sub.ew.x">; + def AME_MMAX_EW_X : AME_BINARYELEMENTWISE_X<0b0000011, 0b010, "mmax.ew.x">; + def AME_MMEAN_EW_X : AME_BINARYELEMENTWISE_X<0b0000100, 0b010, "mmean.ew.x">; + def AME_MMIN_EW_X : AME_BINARYELEMENTWISE_X<0b0000010, 0b010, "mmin.ew.x">; + def AME_MMUL_EW_X : AME_BINARYELEMENTWISE_X<0b0010010, 0b010, "mmul.ew.x">; + def AME_MMULACC_EW_X : AME_BINARYELEMENTWISE_X<0b0010011, 0b010, "mmulacc.ew.x">; + def AME_MMULACCNEG_EW_X : AME_BINARYELEMENTWISE_X<0b0010110, 0b010, "mmulaccneg.ew.x">; + def AME_MMULADD_EW_X : AME_BINARYELEMENTWISE_X<0b0010100, 0b010, "mmuladd.ew.x">; + def AME_MMULNEG_EW_X : AME_BINARYELEMENTWISE_X<0b0010111, 0b010, "mmulneg.ew.x">; + def AME_MMULSUB_EW_X : AME_BINARYELEMENTWISE_X<0b0010101, 0b010, "mmulsub.ew.x">; + def AME_MOR_EW_X : AME_BINARYELEMENTWISE_X<0b0001001, 0b010, "mor.ew.x">; + def AME_MORNOT_EW_X : AME_BINARYELEMENTWISE_X<0b0001010, 0b010, "mornot.ew.x">; + def AME_MSUB_EW_X : AME_BINARYELEMENTWISE_X<0b0000001, 0b010, "msub.ew.x">; + def AME_MSUBLOG2_EW_X : AME_BINARYELEMENTWISE_X<0b0001111, 0b010, "msublog2.ew.x">; + def AME_MXOR_EW_X : AME_BINARYELEMENTWISE_X<0b0001011, 0b010, "mxor.ew.x">; +} + +// Base class for 2D matrix multiply instructions (op acc, ms1, ms2). +// acc is only 2 bits, freeing bits 14-10. +class AME_MATMUL2D funct7, string opcodestr> + : RVInstAME32 { + bits<5> ms1; + bits<5> ms2; + bits<2> acc; + + let Inst{24 - 20} = ms2; + let Inst{19 - 15} = ms1; + let Inst{14 - 10} = 0b01000; + let Inst{9 - 8} = acc; + let Inst{7} = 0b0; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + def AME_MMUL_2D : AME_MATMUL2D<0b0000000, "mmul.2d">; + def AME_MMULACC_2D : AME_MATMUL2D<0b0000001, "mmulacc.2d">; + def AME_MMULACCNEG_2D : AME_MATMUL2D<0b0000011, "mmulaccneg.2d">; + def AME_MMULAT_2D : AME_MATMUL2D<0b0000100, "mmulat.2d">; + def AME_MMULATACC_2D : AME_MATMUL2D<0b0000101, "mmulatacc.2d">; + def AME_MMULBT_2D : AME_MATMUL2D<0b0000110, "mmulbt.2d">; + def AME_MMULBTACC_2D : AME_MATMUL2D<0b0000111, "mmulbtacc.2d">; + def AME_MMULNEG_2D : AME_MATMUL2D<0b0000010, "mmulneg.2d">; +} + +// Base class for the interoperability load instructions (mls, mls.cm, +// mls.rm). +class AME_LOAD funct7, string opcodestr> + : RVInstAME32 { + bits<5> xs1; + bits<5> md; + + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = xs1; + let Inst{14 - 12} = 0b011; + let Inst{11 - 7} = md; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 1, + mayStore = 0 in { + def AME_MLS : AME_LOAD<0b0000010, "mls">; + def AME_MLS_CM : AME_LOAD<0b0000001, "mls.cm">; + def AME_MLS_RM : AME_LOAD<0b0000000, "mls.rm">; +} + +// Base class for the interoperability store instructions (mss, mss.cm, +// mss.rm). +class AME_STORE funct7, string opcodestr> + : RVInstAME32 { + bits<5> xs1; + bits<5> ms1; + + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = xs1; + let Inst{14 - 12} = 0b011; + let Inst{11 - 7} = ms1; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 1 in { + def AME_MSS : AME_STORE<0b0000101, "mss">; + def AME_MSS_CM : AME_STORE<0b0000100, "mss.cm">; + def AME_MSS_RM : AME_STORE<0b0000011, "mss.rm">; +} + +let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, + mayStore = 0 in { + // mzero.2d - clears an accumulator. + def AME_MZERO_2D : RVInstAME32<0b0001000, (outs AMEAccReg + : $acc), + (ins), "mzero.2d", "$acc"> { + bits<2> acc; + + let Inst{24 - 10} = 0b000000000010001; + let Inst{9 - 8} = acc; + let Inst{7} = 0b0; + } + + // mmov.a.m - copy an Acc register into an M register. + def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs AMEMatrixReg + : $md), + (ins AMEAccReg + : $acc), + "mmov.a.m", "$md, $acc"> { + bits<2> acc; + bits<5> md; + + let Inst{24 - 22} = 0b000; + let Inst{21 - 20} = acc; + let Inst{19 - 12} = 0b00000100; + let Inst{11 - 7} = md; + } + + // mmov.m.m - copy one M register into another. + def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs AMEMatrixReg + : $md), + (ins AMEMatrixReg + : $ms), + "mmov.m.m", "$md, $ms"> { + bits<5> ms; + bits<5> md; + + let Inst{24 - 20} = ms; + let Inst{19 - 12} = 0b00000100; + let Inst{11 - 7} = md; + } + + // mgettyp - read an M register's dtype tag into a GPR. + def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR + : $xd), + (ins AMEMatrixReg + : $ms1), + "mgettyp", "$xd, $ms1"> { + bits<5> ms1; + bits<5> xd; + + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = ms1; + let Inst{14 - 12} = 0b101; + let Inst{11 - 7} = xd; + } + + // agettyp - read an Acc register's dtype tag into a GPR. + def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR + : $xd), + (ins AMEAccReg + : $ad), + "agettyp", "$xd, $ad"> { + bits<2> ad; + bits<5> xd; + + let Inst{24 - 17} = 0b00000000; + let Inst{16 - 15} = ad; + let Inst{14 - 12} = 0b101; + let Inst{11 - 7} = xd; + } + + // msettyp - write a GPR value as an M register's dtype tag. + def AME_MSETTYP : RVInstAME32<0b0000001, (outs AMEMatrixReg + : $md), + (ins GPR + : $xs1), + "msettyp", "$md, $xs1"> { + bits<5> xs1; + bits<5> md; + + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = xs1; + let Inst{14 - 12} = 0b101; + let Inst{11 - 7} = md; + } + + // asettyp - write a GPR value as an Acc register's dtype tag. + def AME_ASETTYP : RVInstAME32<0b0000011, (outs AMEAccReg + : $ad), + (ins GPR + : $xs1), + "asettyp", "$ad, $xs1"> { + bits<5> xs1; + bits<2> ad; + + let Inst{19 - 15} = xs1; + let Inst{14 - 10} = 0b10100; + let Inst{9 - 8} = ad; + let Inst{7} = 0b0; + } + + // mbcast.x - broadcast a GPR scalar to every element of an M register. + def AME_MBCAST_X : RVInstAME32<0b0000000, (outs AMEMatrixReg + : $md), + (ins GPR + : $xs1), + "mbcast.x", "$md, $xs1"> { + bits<5> xs1; + bits<5> md; + + let Inst{24 - 20} = 0b00000; + let Inst{19 - 15} = xs1; + let Inst{14 - 12} = 0b100; + let Inst{11 - 7} = md; + } + + // mshift.ew - md[i,j] = ms1[i, j+imm], or 0 if j+imm is out of bounds + def AME_MSHIFT_EW : RVInst<(outs AMEMatrixReg:$md), + (ins AMEMatrixReg:$ms1, i64imm:$imm), + "mshift.ew", "$md, $ms1, $imm", [], InstFormatOther> { + bits<5> ms1; + bits<7> imm; + bits<5> md; + + let Inst{31 - 27} = 0b00000; + let Inst{26 - 20} = imm; + let Inst{19 - 15} = ms1; + let Inst{14 - 12} = 0b110; + let Inst{11 - 7} = md; + let Inst{6 - 0} = 0b0101011; + } +} + +// TODO: +// Define mpack.ew.x / munpack.ew.x +// +// As currently drafted in the spec, both encode to funct7=0000001, funct3=101, identical field +// positions. The spec gives no way to distinguish them. diff --git a/llvm/lib/Target/RISCV/RISCVMatrixExt.td b/llvm/lib/Target/RISCV/RISCVMatrixExt.td index a2939a319e857..c695870827da1 100644 --- a/llvm/lib/Target/RISCV/RISCVMatrixExt.td +++ b/llvm/lib/Target/RISCV/RISCVMatrixExt.td @@ -19,6 +19,35 @@ // //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// Standard AME (RISC-V Matrix Extension, Ztt) Register Definitions +//===----------------------------------------------------------------------===// +// Reference: RISC-V Attached Matrix Extension (Ztt) draft specification +//===----------------------------------------------------------------------===// + +let Namespace = "RISCV" in { + // Base class for AME Matrix Registers (m0-m31) + // AME_NUM_M_REGS is an implementation parameter that defines the number of + // general-purpose matrix registers (one of [16, 32]). + class AMEMatrixReg Enc, string n> : Register { + let HWEncoding{4 - 0} = Enc; + } + + // Define 32 AME Matrix Registers + foreach i = 0 - 31 in { def AMEM #i : AMEMatrixReg; } + + // Base class for AME Accumulator Registers (acc0-acc3) + // AME_NUM_ACC_REGS is an implementation parameter that defines the number of + // accumulator registers (one of [1, 2, 4]). + class AMEAccReg Enc, string n> : Register { + let HWEncoding{1 - 0} = Enc; + } + + // Define 4 AME Accumulator Registers + foreach i = 0 - 3 in{def AMEAcc #i: AMEAccReg; +} +} + //===----------------------------------------------------------------------===// // Vendor-Specific AME (RISC-V Matrix Extension) Register Definitions //===----------------------------------------------------------------------===// @@ -29,7 +58,6 @@ //===----------------------------------------------------------------------===// let Namespace = "RISCV" in { - // Base class for BOSCAME Tile Registers (tr0-7) // Used for input matrices A and B // Size: MLEN bits per register (hardware-defined) @@ -39,14 +67,7 @@ let Namespace = "RISCV" in { } // Define 8 BOSCAME Tile Registers: tr0-tr7 - def BOSCAMETR0 : BOSCAMETileReg<0, "tr0">; - def BOSCAMETR1 : BOSCAMETileReg<1, "tr1">; - def BOSCAMETR2 : BOSCAMETileReg<2, "tr2">; - def BOSCAMETR3 : BOSCAMETileReg<3, "tr3">; - def BOSCAMETR4 : BOSCAMETileReg<4, "tr4">; - def BOSCAMETR5 : BOSCAMETileReg<5, "tr5">; - def BOSCAMETR6 : BOSCAMETileReg<6, "tr6">; - def BOSCAMETR7 : BOSCAMETileReg<7, "tr7">; + foreach i = 0 - 7 in { def BOSCAMETR #i : BOSCAMETileReg; } // Base class for BOSCAME Accumulation Registers (acc0-acc7) // Used for output/accumulation matrix C @@ -63,14 +84,7 @@ let Namespace = "RISCV" in { } // Define 8 BOSCAME Accumulation Registers: acc0-acc7 - def BOSCAMEACC0 : BOSCAMEAccReg<0, "acc0">; - def BOSCAMEACC1 : BOSCAMEAccReg<1, "acc1">; - def BOSCAMEACC2 : BOSCAMEAccReg<2, "acc2">; - def BOSCAMEACC3 : BOSCAMEAccReg<3, "acc3">; - def BOSCAMEACC4 : BOSCAMEAccReg<4, "acc4">; - def BOSCAMEACC5 : BOSCAMEAccReg<5, "acc5">; - def BOSCAMEACC6 : BOSCAMEAccReg<6, "acc6">; - def BOSCAMEACC7 : BOSCAMEAccReg<7, "acc7">; + foreach i = 0 - 7 in { def BOSCAMEACC #i : BOSCAMEAccReg; } // Base class for XuanTie AME Matrix Registers (m0-m7) class THeadAMEMatrixReg Enc, string n> : Register { @@ -81,15 +95,8 @@ let Namespace = "RISCV" in { // Define 8 XuanTie AME Matrix Registers: m0-m7 // Upstream RISCVRegisterInfo.td already defines M0-M7 as mask registers. Keep // the TableGen def names distinct while preserving the XTAME assembly names. - def THeadAMEM0 : THeadAMEMatrixReg<0, "amem0">; - def THeadAMEM1 : THeadAMEMatrixReg<1, "amem1">; - def THeadAMEM2 : THeadAMEMatrixReg<2, "amem2">; - def THeadAMEM3 : THeadAMEMatrixReg<3, "amem3">; - def THeadAMEM4 : THeadAMEMatrixReg<4, "amem4">; - def THeadAMEM5 : THeadAMEMatrixReg<5, "amem5">; - def THeadAMEM6 : THeadAMEMatrixReg<6, "amem6">; - def THeadAMEM7 : THeadAMEMatrixReg<7, "amem7">; - + foreach i = 0 - 7 in{def THeadAMEM #i: THeadAMEMatrixReg; +} } // End Namespace = "RISCV" //===----------------------------------------------------------------------===// @@ -100,33 +107,42 @@ let Namespace = "RISCV" in { // Tile Register class (tr0-tr7) // Used for input operands in matrix multiplication and load/store of input -// matrices Note: Size is set to 256 as a placeholder; actual size depends on +// matrices +// Note: Size is set to 256 as a placeholder; actual size depends on // MLEN -def BOSCAMETileReg - : RegisterClass<"RISCV", [untyped], 256, - (add BOSCAMETR0, BOSCAMETR1, BOSCAMETR2, BOSCAMETR3, - BOSCAMETR4, BOSCAMETR5, BOSCAMETR6, BOSCAMETR7)> { +def BOSCAMETileReg : RegisterClass<"RISCV", [untyped], 256, + (add(sequence "BOSCAMETR%u", 0, 7))> { let Size = 256; // Placeholder: actual MLEN is hardware-defined } // Accumulation Register class (acc0-acc7) // Used for output/accumulator in matrix multiplication and load/store of -// output/accumulator Note: Size can be 256×AMUL where AMUL ∈ {1/8, 1/4, 1/2, 1, +// output/accumulator +// Note: Size can be 256×AMUL where AMUL ∈ {1/8, 1/4, 1/2, 1, // 2, 4, 8} We use 1024 as a reasonable upper bound (256 × 4 for int8→int32) -def BOSCAMEAccReg - : RegisterClass<"RISCV", [untyped], 1024, - (add BOSCAMEACC0, BOSCAMEACC1, BOSCAMEACC2, BOSCAMEACC3, - BOSCAMEACC4, BOSCAMEACC5, BOSCAMEACC6, BOSCAMEACC7)> { +def BOSCAMEAccReg : RegisterClass<"RISCV", [untyped], 1024, + (add(sequence "BOSCAMEACC%u", 0, 7))> { let Size = 1024; // Placeholder: actual MLEN×AMUL is hardware-defined } -// XuanTie AME matrix register class. -def THeadAMEMatrixReg - : RegisterClass<"RISCV", [untyped], 1024, - (add THeadAMEM0, THeadAMEM1, THeadAMEM2, THeadAMEM3, - THeadAMEM4, THeadAMEM5, THeadAMEM6, THeadAMEM7)> { +// XuanTie AME Matrix Register class. +def THeadAMEMatrixReg : RegisterClass<"RISCV", [untyped], 1024, + (add(sequence "THeadAMEM%u", 0, 7))> { let Size = 1024; // Placeholder: actual MLEN is hardware-defined } +// Standard AME (Ztt) Matrix Register class +def AMEMatrixReg + : RegisterClass<"RISCV", [untyped], 1024, (add(sequence "AMEM%u", 0, 31))> { + let Size = 1024; // Placeholder: actual size is hardware-defined +} + +// Standard AME (Ztt) Accumulator Register class +def AMEAccReg : RegisterClass<"RISCV", [untyped], 4096, + (add(sequence "AMEAcc%u", 0, 3))> { + let Size = 4096; // Placeholder: actual size is hardware-defined +} + include "RISCVInstrInfoXBOSCAME.td" include "RISCVInstrInfoXTHeadAME.td" +include "RISCVInstrInfoZtt.td" From b5fc567947b6349c74f1a2ba382b7ab6bb18e7e4 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Thu, 16 Jul 2026 01:07:55 +0000 Subject: [PATCH 04/10] [RISCV: Refactor] Remove AME(Ztt) register definitions and replace with immediates --- .../RISCV/Disassembler/RISCVDisassembler.cpp | 14 -- llvm/lib/Target/RISCV/RISCVFeatures.td | 27 +++- llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 136 +++++++++++------- llvm/lib/Target/RISCV/RISCVMatrixExt.td | 41 ------ 4 files changed, 111 insertions(+), 107 deletions(-) diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index b590dfe2ed90a..a2459df0cfa65 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -123,20 +123,6 @@ DecodeTHeadAMEMatrixRegRegisterClass(MCInst &Inst, uint32_t RegNo, Decoder); } -static DecodeStatus -DecodeAMEAccRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeSimpleRegisterClass(Inst, RegNo, Address, - Decoder); -} - -static DecodeStatus -DecodeAMEMatrixRegRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, - const MCDisassembler *Decoder) { - return DecodeSimpleRegisterClass(Inst, RegNo, Address, - Decoder); -} - static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 088c375ee83e9..523eb70f5e7e2 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -958,8 +958,31 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">, "'Zvvmttls' (Transposing Matrix Tile Load/Store)">; // Attached Matrix Extension -def FeatureStdExtZtt - : RISCVExtension<0, 1, "Attached Matrix Extension">; +def FeatureAMEMatrixRegs16 + : SubtargetFeature<"ame-mregs-16", "HasAMEMatrixRegs16", "true", + "Target supports 16 AME matrix registers">; + +def FeatureAMEMatrixRegs32 + : SubtargetFeature<"ame-mregs-32", "HasAMEMatrixRegs32", "true", + "Target supports 32 AME matrix registers">; + +def FeatureAMEAccRegs1 + : SubtargetFeature<"ame-accregs-1", "HasAMEAccRegs1", "true", + "Target supports 1 AME accumulator register">; + +def FeatureAMEAccRegs2 + : SubtargetFeature<"ame-accregs-2", "HasAMEAccRegs2", "true", + "Target supports 2 AME accumulator registers">; + +def FeatureAMEAccRegs4 + : SubtargetFeature<"ame-accregs-4", "HasAMEAccRegs4", "true", + "Target supports 4 AME accumulator registers">; + +def FeatureStdExtZtt // By default, enabling "+ztt" implies 16 Matrix Regs and 4 Accumulators. + : RISCVExtension<0, 1, "Attached Matrix Extension", + [FeatureAMEMatrixRegs32, + FeatureAMEAccRegs4]>; + def HasStdExtZtt : Predicate<"Subtarget->hasStdExtZtt()">, AssemblerPredicate<(all_of FeatureStdExtZtt), "'Ztt' (Attached Matrix Extension)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td index adedf5ba20734..01819095243e0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -13,6 +13,45 @@ // //===----------------------------------------------------------------------===// +// These operand types allow intrinsics to pass immediate indices +// for matrix (0-16/0-32) and accumulator (0/0-1/0-3) registers. +// hardcodes "acc" and "m" prefixes so that indices 0-7 are printed as +// acc0-acc7 and tr0-tr7 respectively, without modifying LLVM submodule. + +// AsmOperandClass for matrix register index (0-16 or 0-32 depending on implementation) +def AMEMatrixRegIndexAsmOperand : AsmOperandClass { + let Name = "AMEMatrixRegIndex"; + let RenderMethod = "addImmOperands"; + let PredicateMethod = "isAMETileIndex"; + let DiagnosticType = "InvalidAMETileIndex"; +} + +// AsmOperandClass for matrix register index (0, 0-1, 0-3 depending on implementation) +def AMEAccRegIndexAsmOperand : AsmOperandClass { + let Name = "AMEAccRegIndex"; + let RenderMethod = "addImmOperands"; + let PredicateMethod = "isAMEAccIndex"; + let DiagnosticType = "InvalidAMEAccIndex"; +} + +// Operand type for AMEMatrixRegIndex (0-16 or 0-32) +def AMEMatrixRegIndex : RISCVOp { + let ParserMatchClass = AMEMatrixRegIndexAsmOperand; + let DecoderMethod = "decodeUImmOperand<5>"; + let OperandType = "OPERAND_UIMM5"; +} + +// Operand type for AMEAccRegIndex (0, 0-1 or 0-3) +def AMEAccRegIndex : RISCVOp { + let ParserMatchClass = AMEAccRegIndexAsmOperand; + let DecoderMethod = "decodeUImmOperand<2>"; + let OperandType = "OPERAND_UIMM2"; +} + +//===----------------------------------------------------------------------===// +// AME (Ztt) 32-bit real/concrete instructions +//===----------------------------------------------------------------------===// + // AME (Ztt) 32-bit instruction template class RVInstAME32 funct7, dag outs, dag ins, string opcodestr, string argstr> @@ -25,10 +64,8 @@ class RVInstAME32 funct7, dag outs, dag ins, string opcodestr, // Input and output are matrix registers class AME_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> md; @@ -40,7 +77,7 @@ class AME_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> let Inst{11 - 7} = md; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { def AME_MABS_EW : AME_UNARYELEMENTWISE<0b0000000, 0b001, "mabs.ew">; def AME_MCOLUNZIP_EW : AME_UNARYELEMENTWISE<0b0000100, 0b001, "mcolunzip.ew">; @@ -63,10 +100,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // (op md, ms1, ms2). class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> ms1; @@ -79,7 +115,7 @@ class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> let Inst{11 - 7} = md; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { def AME_MABSDIFF_EW : AME_BINARYELEMENTWISE<0b0000100, 0b000, "mabsdiff.ew">; def AME_MADD_EW : AME_BINARYELEMENTWISE<0b0000000, 0b000, "madd.ew">; @@ -124,10 +160,10 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // (op md, xs1, ms2). Scalar type is inferred from Md[ms2]. class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> xs1; @@ -140,7 +176,7 @@ class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> let Inst{11 - 7} = md; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { def AME_MABSDIFF_EW_X : AME_BINARYELEMENTWISE_X<0b0000101, 0b010, "mabsdiff.ew.x">; def AME_MADD_EW_X : AME_BINARYELEMENTWISE_X<0b0000000, 0b010, "madd.ew.x">; @@ -172,10 +208,10 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // acc is only 2 bits, freeing bits 14-10. class AME_MATMUL2D funct7, string opcodestr> : RVInstAME32 { bits<5> ms1; @@ -189,7 +225,7 @@ class AME_MATMUL2D funct7, string opcodestr> let Inst{7} = 0b0; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { def AME_MMUL_2D : AME_MATMUL2D<0b0000000, "mmul.2d">; def AME_MMULACC_2D : AME_MATMUL2D<0b0000001, "mmulacc.2d">; @@ -204,9 +240,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // Base class for the interoperability load instructions (mls, mls.cm, // mls.rm). class AME_LOAD funct7, string opcodestr> - : RVInstAME32 { bits<5> xs1; @@ -218,7 +254,7 @@ class AME_LOAD funct7, string opcodestr> let Inst{11 - 7} = md; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 1, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 1, mayStore = 0 in { def AME_MLS : AME_LOAD<0b0000010, "mls">; def AME_MLS_CM : AME_LOAD<0b0000001, "mls.cm">; @@ -229,7 +265,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 1, // mss.rm). class AME_STORE funct7, string opcodestr> : RVInstAME32 { @@ -242,19 +278,19 @@ class AME_STORE funct7, string opcodestr> let Inst{11 - 7} = ms1; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 1 in { def AME_MSS : AME_STORE<0b0000101, "mss">; def AME_MSS_CM : AME_STORE<0b0000100, "mss.cm">; def AME_MSS_RM : AME_STORE<0b0000011, "mss.rm">; } -let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { // mzero.2d - clears an accumulator. - def AME_MZERO_2D : RVInstAME32<0b0001000, (outs AMEAccReg - : $acc), - (ins), "mzero.2d", "$acc"> { + def AME_MZERO_2D : RVInstAME32<0b0001000, (outs ), + (ins AMEAccRegIndex + : $acc), "mzero.2d", "$acc"> { bits<2> acc; let Inst{24 - 10} = 0b000000000010001; @@ -263,9 +299,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // mmov.a.m - copy an Acc register into an M register. - def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs AMEMatrixReg - : $md), - (ins AMEAccReg + def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs ), + (ins AMEMatrixRegIndex + : $md, AMEAccRegIndex : $acc), "mmov.a.m", "$md, $acc"> { bits<2> acc; @@ -278,9 +314,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // mmov.m.m - copy one M register into another. - def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs AMEMatrixReg - : $md), - (ins AMEMatrixReg + def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs ), + (ins AMEMatrixRegIndex + : $md, AMEMatrixRegIndex : $ms), "mmov.m.m", "$md, $ms"> { bits<5> ms; @@ -294,7 +330,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // mgettyp - read an M register's dtype tag into a GPR. def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR : $xd), - (ins AMEMatrixReg + (ins AMEMatrixRegIndex : $ms1), "mgettyp", "$xd, $ms1"> { bits<5> ms1; @@ -309,7 +345,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, // agettyp - read an Acc register's dtype tag into a GPR. def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR : $xd), - (ins AMEAccReg + (ins AMEAccRegIndex : $ad), "agettyp", "$xd, $ad"> { bits<2> ad; @@ -322,9 +358,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // msettyp - write a GPR value as an M register's dtype tag. - def AME_MSETTYP : RVInstAME32<0b0000001, (outs AMEMatrixReg - : $md), - (ins GPR + def AME_MSETTYP : RVInstAME32<0b0000001, (outs ), + (ins AMEMatrixRegIndex + : $md, GPR : $xs1), "msettyp", "$md, $xs1"> { bits<5> xs1; @@ -337,9 +373,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // asettyp - write a GPR value as an Acc register's dtype tag. - def AME_ASETTYP : RVInstAME32<0b0000011, (outs AMEAccReg - : $ad), - (ins GPR + def AME_ASETTYP : RVInstAME32<0b0000011, (outs ), + (ins AMEAccRegIndex + : $ad, GPR : $xs1), "asettyp", "$ad, $xs1"> { bits<5> xs1; @@ -352,9 +388,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // mbcast.x - broadcast a GPR scalar to every element of an M register. - def AME_MBCAST_X : RVInstAME32<0b0000000, (outs AMEMatrixReg - : $md), - (ins GPR + def AME_MBCAST_X : RVInstAME32<0b0000000, (outs ), + (ins AMEMatrixRegIndex + : $md, GPR : $xs1), "mbcast.x", "$md, $xs1"> { bits<5> xs1; @@ -367,8 +403,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // mshift.ew - md[i,j] = ms1[i, j+imm], or 0 if j+imm is out of bounds - def AME_MSHIFT_EW : RVInst<(outs AMEMatrixReg:$md), - (ins AMEMatrixReg:$ms1, i64imm:$imm), + def AME_MSHIFT_EW : RVInst<(outs ), + (ins AMEMatrixRegIndex:$md, AMEMatrixRegIndex:$ms1, i64imm:$imm), "mshift.ew", "$md, $ms1, $imm", [], InstFormatOther> { bits<5> ms1; bits<7> imm; @@ -384,7 +420,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 0, mayLoad = 0, } // TODO: -// Define mpack.ew.x / munpack.ew.x +// Define mpack.ew.x / munpack.ew.x real and pseudo instructions, and intrinsics -> pseudo instructions isel patterns. // // As currently drafted in the spec, both encode to funct7=0000001, funct3=101, identical field // positions. The spec gives no way to distinguish them. diff --git a/llvm/lib/Target/RISCV/RISCVMatrixExt.td b/llvm/lib/Target/RISCV/RISCVMatrixExt.td index c695870827da1..0f4838fd5ed7b 100644 --- a/llvm/lib/Target/RISCV/RISCVMatrixExt.td +++ b/llvm/lib/Target/RISCV/RISCVMatrixExt.td @@ -19,35 +19,6 @@ // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// Standard AME (RISC-V Matrix Extension, Ztt) Register Definitions -//===----------------------------------------------------------------------===// -// Reference: RISC-V Attached Matrix Extension (Ztt) draft specification -//===----------------------------------------------------------------------===// - -let Namespace = "RISCV" in { - // Base class for AME Matrix Registers (m0-m31) - // AME_NUM_M_REGS is an implementation parameter that defines the number of - // general-purpose matrix registers (one of [16, 32]). - class AMEMatrixReg Enc, string n> : Register { - let HWEncoding{4 - 0} = Enc; - } - - // Define 32 AME Matrix Registers - foreach i = 0 - 31 in { def AMEM #i : AMEMatrixReg; } - - // Base class for AME Accumulator Registers (acc0-acc3) - // AME_NUM_ACC_REGS is an implementation parameter that defines the number of - // accumulator registers (one of [1, 2, 4]). - class AMEAccReg Enc, string n> : Register { - let HWEncoding{1 - 0} = Enc; - } - - // Define 4 AME Accumulator Registers - foreach i = 0 - 3 in{def AMEAcc #i: AMEAccReg; -} -} - //===----------------------------------------------------------------------===// // Vendor-Specific AME (RISC-V Matrix Extension) Register Definitions //===----------------------------------------------------------------------===// @@ -131,18 +102,6 @@ def THeadAMEMatrixReg : RegisterClass<"RISCV", [untyped], 1024, let Size = 1024; // Placeholder: actual MLEN is hardware-defined } -// Standard AME (Ztt) Matrix Register class -def AMEMatrixReg - : RegisterClass<"RISCV", [untyped], 1024, (add(sequence "AMEM%u", 0, 31))> { - let Size = 1024; // Placeholder: actual size is hardware-defined -} - -// Standard AME (Ztt) Accumulator Register class -def AMEAccReg : RegisterClass<"RISCV", [untyped], 4096, - (add(sequence "AMEAcc%u", 0, 3))> { - let Size = 4096; // Placeholder: actual size is hardware-defined -} - include "RISCVInstrInfoXBOSCAME.td" include "RISCVInstrInfoXTHeadAME.td" include "RISCVInstrInfoZtt.td" From 72334480752477ea1eca49350aec3b83a81be2cf Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Thu, 16 Jul 2026 01:39:27 +0000 Subject: [PATCH 05/10] [RISCV: Feat] Add ISel pattern matching for LLVM IR -> MachineInstrs --- llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td | 39 +-- llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 224 ++++++++++++++---- llvm/lib/Target/RISCV/RISCVMatrixExt.td | 3 +- 3 files changed, 202 insertions(+), 64 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td index c1d817e54371d..67962ca31d9f8 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td @@ -27,14 +27,14 @@ // Signature: i32 (dtype_reg_index: i32) class AME_DataType_Get_Intr : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], - [IntrNoMem, IntrHasSideEffects, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>]>; // Base class for "set datatype" instrinsics: writes a GPR value into the dtype // of an M/Acc register and zeroes that M/Acc register's contents. // Signature: void (dtype_reg_index: i32, dtype_value: i32) class AME_DataType_Set_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], - [IntrNoMem, IntrHasSideEffects, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>]>; let TargetPrefix = "riscv" in { // agettype - get the dtype of an Acc register @@ -57,7 +57,7 @@ let TargetPrefix = "riscv" in { // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) class AME_Elementwise_Arithmetic_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -65,13 +65,13 @@ class AME_Elementwise_Arithmetic_Intr // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) class AME_Elementwise_Arithmetic_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mabs.ew - md[i] = |ms1[i]| // Signature: void (md_reg_index: i32, ms1_reg_index: i32) def int_riscv_ame_mabs_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg> + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg> ]>; // mabsdiff.ew - md[i] = |ms1[i] - ms2[i]| @@ -160,7 +160,7 @@ let TargetPrefix = "riscv" in { // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) class AME_Bitwise_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -168,7 +168,7 @@ class AME_Bitwise_Intr // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) class AME_Bitwise_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mand.ew - md[i] = ms1[i] & ms2[i] @@ -210,7 +210,7 @@ let TargetPrefix = "riscv" in { // (md). Signature: void (md_reg_index: i32, scalar: i32) def int_riscv_ame_mbcast_x : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>]>; } //===----------------------------------------------------------------------===// @@ -221,7 +221,7 @@ let TargetPrefix = "riscv" in { // src1_reg_index: i32) class AME_Comp_Pred_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -229,7 +229,7 @@ class AME_Comp_Pred_Intr // Signature: void (md_reg_index: i32, scalar: i32, src1_reg_index: i32) class AME_Comp_Pred_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mcmovge.ew - md[i] = src1[i] if pred[i] >= 0, else md[i] unchanged. @@ -264,6 +264,7 @@ let TargetPrefix = "riscv" in { // Signature: void (md_reg_index: i32, ms1_reg_index: i32) class AME_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, + IntrNoMem, ImmArg>, ImmArg>, ]>; @@ -271,7 +272,7 @@ class AME_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ // Base class for 3-operand permutation intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) class AME_Perm3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -348,6 +349,7 @@ let TargetPrefix = "riscv" in { class AME_PackUnpack_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, + IntrNoMem, ImmArg>, ImmArg>, ]>; @@ -359,7 +361,7 @@ let TargetPrefix = "riscv" in { // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid // operands here. def int_riscv_ame_mconv_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg> + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg> ]>; // mpack.ew.x - pack the square from the ms1 register (unpacked, @@ -385,6 +387,7 @@ let TargetPrefix = "riscv" in { // Signature: void (md_reg_index: i32, ms1_reg_index: i32) class AME_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, + IntrNoMem, ImmArg>, ImmArg>, ]>; @@ -393,7 +396,7 @@ class AME_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) class AME_Log2Exp2_3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -401,7 +404,7 @@ class AME_Log2Exp2_3_Intr // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) class AME_Log2Exp2_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mexp2.ew - md[i] = 2^ms1[i] @@ -482,7 +485,7 @@ let TargetPrefix = "riscv" in { // registers Signature: void (dest_reg_index: i32, src_reg_index: i32) class AME_Move_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mmov.a.m - copy an Acc register to an M register group; dtypes must @@ -496,7 +499,7 @@ let TargetPrefix = "riscv" in { // mzero.2d - zero every element of an Acc register. // Signature: void (acc_reg_index: i32) def int_riscv_ame_mzero_2d - : Intrinsic<[], [llvm_i64_ty], [IntrHasSideEffects, ImmArg>]>; + : Intrinsic<[], [llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>]>; } //===----------------------------------------------------------------------===// @@ -505,7 +508,7 @@ let TargetPrefix = "riscv" in { // Base class for matrix multiply intrinsics // Signature: void (acc_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) class AME_MatMul_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ - IntrHasSideEffects, ImmArg>, ImmArg>, + IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; @@ -542,7 +545,7 @@ let TargetPrefix = "riscv" in { // Signature: void (md_reg_index: i32, ms1_reg_index: i32) class AME_Reduction_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], - [IntrHasSideEffects, ImmArg>, ImmArg>]>; + [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mprefixadd.col - md[i, j] = sum over k <= i of ms1[k, j] diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td index 01819095243e0..77c30a21560af 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -101,9 +101,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> ms2; @@ -160,11 +160,10 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // (op md, xs1, ms2). Scalar type is inferred from Md[ms2]. class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> xs1; bits<5> ms2; @@ -209,10 +208,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, class AME_MATMUL2D funct7, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> ms2; @@ -241,9 +239,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mls.rm). class AME_LOAD funct7, string opcodestr> : RVInstAME32 { bits<5> xs1; bits<5> md; @@ -265,9 +262,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 1, // mss.rm). class AME_STORE funct7, string opcodestr> : RVInstAME32 { bits<5> xs1; bits<5> ms1; @@ -288,9 +284,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { // mzero.2d - clears an accumulator. - def AME_MZERO_2D : RVInstAME32<0b0001000, (outs ), - (ins AMEAccRegIndex - : $acc), "mzero.2d", "$acc"> { + def AME_MZERO_2D : RVInstAME32<0b0001000, (outs), + (ins AMEAccRegIndex: $acc), "mzero.2d", "$acc"> { bits<2> acc; let Inst{24 - 10} = 0b000000000010001; @@ -300,9 +295,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mmov.a.m - copy an Acc register into an M register. def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs ), - (ins AMEMatrixRegIndex - : $md, AMEAccRegIndex - : $acc), + (ins AMEMatrixRegIndex: $md, + AMEAccRegIndex: $acc), "mmov.a.m", "$md, $acc"> { bits<2> acc; bits<5> md; @@ -315,9 +309,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mmov.m.m - copy one M register into another. def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs ), - (ins AMEMatrixRegIndex - : $md, AMEMatrixRegIndex - : $ms), + (ins AMEMatrixRegIndex: $md, + AMEMatrixRegIndex: $ms), "mmov.m.m", "$md, $ms"> { bits<5> ms; bits<5> md; @@ -328,10 +321,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // mgettyp - read an M register's dtype tag into a GPR. - def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR - : $xd), - (ins AMEMatrixRegIndex - : $ms1), + def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR: $xd), + (ins AMEMatrixRegIndex: $ms1), "mgettyp", "$xd, $ms1"> { bits<5> ms1; bits<5> xd; @@ -343,10 +334,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // agettyp - read an Acc register's dtype tag into a GPR. - def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR - : $xd), - (ins AMEAccRegIndex - : $ad), + def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR: $xd), + (ins AMEAccRegIndex: $ad), "agettyp", "$xd, $ad"> { bits<2> ad; bits<5> xd; @@ -359,9 +348,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // msettyp - write a GPR value as an M register's dtype tag. def AME_MSETTYP : RVInstAME32<0b0000001, (outs ), - (ins AMEMatrixRegIndex - : $md, GPR - : $xs1), + (ins AMEMatrixRegIndex: $md, + GPR: $xs1), "msettyp", "$md, $xs1"> { bits<5> xs1; bits<5> md; @@ -374,9 +362,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // asettyp - write a GPR value as an Acc register's dtype tag. def AME_ASETTYP : RVInstAME32<0b0000011, (outs ), - (ins AMEAccRegIndex - : $ad, GPR - : $xs1), + (ins AMEAccRegIndex: $ad, + GPR: $xs1), "asettyp", "$ad, $xs1"> { bits<5> xs1; bits<2> ad; @@ -389,9 +376,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mbcast.x - broadcast a GPR scalar to every element of an M register. def AME_MBCAST_X : RVInstAME32<0b0000000, (outs ), - (ins AMEMatrixRegIndex - : $md, GPR - : $xs1), + (ins AMEMatrixRegIndex: $md, + GPR: $xs1), "mbcast.x", "$md, $xs1"> { bits<5> xs1; bits<5> md; @@ -419,8 +405,156 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } } +//===-----------------------------------------------------------------------------------===// +// Pattern Matching: LLVM IR Intrinsics -> AME (Ztt) 32-bit real/concrete instructions +//===-----------------------------------------------------------------------------------===// + +// Base pattern helper for AME unary operations +class AMEUnaryPat + : Pat<(intr timm:$md, timm:$ms1), + (inst timm:$md, timm:$ms1)>; + +let Predicates = [HasStdExtZtt] in { + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; +} + +// Base pattern helper for matrix-matrix binary operations +class AMEBinMatPat + : Pat<(intr timm:$md, timm:$ms1, timm:$ms2), + (inst timm:$md, timm:$ms1, timm:$ms2)>; + +let Predicates = [HasStdExtZtt] in { + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; +} + +// Base pattern helper for matrix-scalar operations. +// The second argument in the intrinsic is the scalar. +class AMEBinScalarPat + : Pat<(intr timm:$md, i64:$xs1, timm:$ms2), + (inst timm:$md, GPR:$xs1, timm:$ms2)>; + +let Predicates = [HasStdExtZtt] in { + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; +} + +// Base class helper for matrix multiplication operations. +// These instructions write to accumulator registers. +class AMEMatMulPat + : Pat<(intr timm:$acc, timm:$ms1, timm:$ms2), + (inst timm:$acc, timm:$ms1, timm:$ms2)>; + +let Predicates = [HasStdExtZtt] in { + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; +} + +// Miscellaneous instructions +let Predicates = [HasStdExtZtt] in { + // Load/Store Patterns (Memory addresses are handled as ptr_ty -> GPR) + def : Pat<(int_riscv_ame_mls timm:$md, iPTR:$xs1), (AME_MLS timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mls_cm timm:$md, iPTR:$xs1), (AME_MLS_CM timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mls_rm timm:$md, iPTR:$xs1), (AME_MLS_RM timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mss timm:$ms1, iPTR:$xs1), (AME_MSS timm:$ms1, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mss_cm timm:$ms1, iPTR:$xs1), (AME_MSS_CM timm:$ms1, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mss_rm timm:$ms1, iPTR:$xs1), (AME_MSS_RM timm:$ms1, GPR:$xs1)>; + + // Broadcast & Zero + def : Pat<(int_riscv_ame_mbcast_x timm:$md, i64:$xs1), (AME_MBCAST_X timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_mzero_2d timm:$acc), (AME_MZERO_2D timm:$acc)>; + + // Type operations + def : Pat<(int_riscv_ame_mgettype timm:$ms1), (AME_MGETTYP timm:$ms1)>; + def : Pat<(int_riscv_ame_agettyp timm:$ad), (AME_AGETTYP timm:$ad)>; + def : Pat<(int_riscv_ame_msettype timm:$md, i64:$xs1), (AME_MSETTYP timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_asettyp timm:$ad, i64:$xs1), (AME_ASETTYP timm:$ad, GPR:$xs1)>; + + // Moves + def : Pat<(int_riscv_ame_mmov_a_m timm:$md, timm:$acc), (AME_MMOV_A_M timm:$md, timm:$acc)>; + def : Pat<(int_riscv_ame_mmov_m_m timm:$md, timm:$ms), (AME_MMOV_M_M timm:$md, timm:$ms)>; + def : Pat<(int_riscv_ame_mshift_ew timm:$md, timm:$ms1, timm:$imm), + (AME_MSHIFT_EW timm:$md, timm:$ms1, timm:$imm)>; +} + // TODO: -// Define mpack.ew.x / munpack.ew.x real and pseudo instructions, and intrinsics -> pseudo instructions isel patterns. +// Define mpack.ew.x / munpack.ew.x (instruction defintiion/encoding and LLVM IR intrinsics -> MachineInstruction/MCInst isel patterns). // // As currently drafted in the spec, both encode to funct7=0000001, funct3=101, identical field // positions. The spec gives no way to distinguish them. diff --git a/llvm/lib/Target/RISCV/RISCVMatrixExt.td b/llvm/lib/Target/RISCV/RISCVMatrixExt.td index 0f4838fd5ed7b..6218c337befd3 100644 --- a/llvm/lib/Target/RISCV/RISCVMatrixExt.td +++ b/llvm/lib/Target/RISCV/RISCVMatrixExt.td @@ -90,7 +90,8 @@ def BOSCAMETileReg : RegisterClass<"RISCV", [untyped], 256, // Used for output/accumulator in matrix multiplication and load/store of // output/accumulator // Note: Size can be 256×AMUL where AMUL ∈ {1/8, 1/4, 1/2, 1, -// 2, 4, 8} We use 1024 as a reasonable upper bound (256 × 4 for int8→int32) +// 2, 4, 8}. +// We use 1024 as a reasonable upper bound (256 × 4 for int8→int32) def BOSCAMEAccReg : RegisterClass<"RISCV", [untyped], 1024, (add(sequence "BOSCAMEACC%u", 0, 7))> { let Size = 1024; // Placeholder: actual MLEN×AMUL is hardware-defined From eed5adde77fbaf0d8d22f9e9a45761d0c30fe280 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Thu, 16 Jul 2026 04:17:19 +0000 Subject: [PATCH 06/10] [RISCV: Feat] Constraint AME Matrix and Acc Reg Indices --- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 26 +++++------------ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 29 +++++++++++++++++++ llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 8 ++--- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index e54d57d9f4451..07db7ad22fe79 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -146,6 +146,9 @@ enum OperandType : unsigned { OPERAND_VMASK, OPERAND_SMTVType, OPERAND_SMTI8, + + OPERAND_AME_MATRIX_REG, + OPERAND_AME_ACC_REG, }; } // namespace RISCVOp @@ -301,13 +304,9 @@ static inline bool isTiedPseudo(uint64_t TSFlags) { return TSFlags & IsTiedPseudoMask; } /// \returns true if there is a SEW operand for the instruction. -static inline bool hasSEWOp(uint64_t TSFlags) { - return TSFlags & HasSEWOpMask; -} +static inline bool hasSEWOp(uint64_t TSFlags) { return TSFlags & HasSEWOpMask; } /// \returns true if there is a VL operand for the instruction. -static inline bool hasVLOp(uint64_t TSFlags) { - return TSFlags & HasVLOpMask; -} +static inline bool hasVLOp(uint64_t TSFlags) { return TSFlags & HasVLOpMask; } /// \returns true if there is a vector policy operand for this instruction. static inline bool hasVecPolicyOp(uint64_t TSFlags) { return TSFlags & HasVecPolicyOpMask; @@ -493,12 +492,7 @@ enum { // Describes the predecessor/successor bits used in the FENCE instruction. namespace RISCVFenceField { -enum FenceField { - I = 8, - O = 4, - R = 2, - W = 1 -}; +enum FenceField { I = 8, O = 4, R = 2, W = 1 }; } // Describes the supported floating point rounding mode encodings. @@ -597,13 +591,7 @@ inline static bool isValidSMTVTypeMode(unsigned Mode) { } // namespace XSMTVTypeMode namespace RISCVVXRndMode { -enum RoundingMode { - RNU = 0, - RNE = 1, - RDN = 2, - ROD = 3, - Invalid -}; +enum RoundingMode { RNU = 0, RNE = 1, RDN = 2, ROD = 3, Invalid }; inline static StringRef roundingModeToString(RoundingMode RndMode) { switch (RndMode) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 50f548857a97b..1bdefddd4970b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -3247,7 +3247,36 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, return false; } break; + case RISCVOp::OPERAND_AME_MATRIX_REG: { + if (!MO.isImm()) { + ErrInfo = "Expected an immediate operand."; + return false; + } + int64_t Val = MO.getImm(); + const auto &Features = STI.getFeatureBits(); + if ((Features[RISCV::FeatureAMEMatrixRegs32] && (Val < 0 || Val >= 32)) || + (Features[RISCV::FeatureAMEMatrixRegs16] && (Val < 0 || Val >= 16))) { + ErrInfo = "matrix register index out of range for current subtarget"; + return false; + } + break; } + + case RISCVOp::OPERAND_AME_ACC_REG: { + if (!MO.isImm()) { + ErrInfo = "Expected an immediate operand."; + return false; + } + int64_t Val = MO.getImm(); + const auto &Features = STI.getFeatureBits(); + if ((Features[RISCV::FeatureAMEAccRegs4] && (Val < 0 || Val >= 4)) || + (Features[RISCV::FeatureAMEAccRegs2] && (Val < 0 || Val >= 2)) || + (Features[RISCV::FeatureAMEAccRegs1] && Val != 0)) { + ErrInfo = "accumulator index out of range for current subtarget"; + return false; + } + break; + }} } const uint64_t TSFlags = Desc.TSFlags; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td index 77c30a21560af..aec255440c5ab 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -22,7 +22,7 @@ def AMEMatrixRegIndexAsmOperand : AsmOperandClass { let Name = "AMEMatrixRegIndex"; let RenderMethod = "addImmOperands"; - let PredicateMethod = "isAMETileIndex"; + let PredicateMethod = "isUImm5"; let DiagnosticType = "InvalidAMETileIndex"; } @@ -30,7 +30,7 @@ def AMEMatrixRegIndexAsmOperand : AsmOperandClass { def AMEAccRegIndexAsmOperand : AsmOperandClass { let Name = "AMEAccRegIndex"; let RenderMethod = "addImmOperands"; - let PredicateMethod = "isAMEAccIndex"; + let PredicateMethod = "isUImm2"; let DiagnosticType = "InvalidAMEAccIndex"; } @@ -38,14 +38,14 @@ def AMEAccRegIndexAsmOperand : AsmOperandClass { def AMEMatrixRegIndex : RISCVOp { let ParserMatchClass = AMEMatrixRegIndexAsmOperand; let DecoderMethod = "decodeUImmOperand<5>"; - let OperandType = "OPERAND_UIMM5"; + let OperandType = "OPERAND_AME_MATRIX_REG"; } // Operand type for AMEAccRegIndex (0, 0-1 or 0-3) def AMEAccRegIndex : RISCVOp { let ParserMatchClass = AMEAccRegIndexAsmOperand; let DecoderMethod = "decodeUImmOperand<2>"; - let OperandType = "OPERAND_UIMM2"; + let OperandType = "OPERAND_AME_ACC_REG"; } //===----------------------------------------------------------------------===// From eb0d93177227cd736f5643965cf68219cda54d11 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Sat, 18 Jul 2026 00:45:14 +0000 Subject: [PATCH 07/10] [RISCV: Fix] feature support --- .../Driver/print-supported-extensions-riscv.c | 1 + llvm/lib/Target/RISCV/RISCVFeatures.td | 18 +++---- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 53 +++++++++++-------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 2f616857572e7..3ad603d594dae 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -286,6 +286,7 @@ // CHECK-NEXT: zibi 0.1 'Zibi' (Branch with Immediate) // CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad) // CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack) +// CHECK-NEXT: ztt 0.1 'Ztt' (Attached Matrix Extension) // CHECK-NEXT: zvabd 0.7 'Zvabd' (Vector Absolute Difference) // CHECK-NEXT: zvbc32e 0.7 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements) // CHECK-NEXT: zvdot4a8i 0.1 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers) diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 523eb70f5e7e2..eacc5b92a80b3 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -958,30 +958,30 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">, "'Zvvmttls' (Transposing Matrix Tile Load/Store)">; // Attached Matrix Extension -def FeatureAMEMatrixRegs16 +def FeatureStdExtZttMatrixRegs16 : SubtargetFeature<"ame-mregs-16", "HasAMEMatrixRegs16", "true", "Target supports 16 AME matrix registers">; -def FeatureAMEMatrixRegs32 +def FeatureStdExtZttMatrixRegs32 : SubtargetFeature<"ame-mregs-32", "HasAMEMatrixRegs32", "true", "Target supports 32 AME matrix registers">; -def FeatureAMEAccRegs1 +def FeatureStdExtZttAccRegs1 : SubtargetFeature<"ame-accregs-1", "HasAMEAccRegs1", "true", "Target supports 1 AME accumulator register">; -def FeatureAMEAccRegs2 +def FeatureStdExtZttAccRegs2 : SubtargetFeature<"ame-accregs-2", "HasAMEAccRegs2", "true", "Target supports 2 AME accumulator registers">; -def FeatureAMEAccRegs4 +def FeatureStdExtZttAccRegs4 : SubtargetFeature<"ame-accregs-4", "HasAMEAccRegs4", "true", "Target supports 4 AME accumulator registers">; -def FeatureStdExtZtt // By default, enabling "+ztt" implies 16 Matrix Regs and 4 Accumulators. - : RISCVExtension<0, 1, "Attached Matrix Extension", - [FeatureAMEMatrixRegs32, - FeatureAMEAccRegs4]>; +let Implies = [FeatureStdExtZttMatrixRegs32, FeatureStdExtZttAccRegs4] in { + def FeatureStdExtZtt // By default, enabling "+ztt" implies 32 Matrix Regs and 4 Accumulators. + : RISCVExperimentalExtension<0, 1, "Attached Matrix Extension">; +} def HasStdExtZtt : Predicate<"Subtarget->hasStdExtZtt()">, AssemblerPredicate<(all_of FeatureStdExtZtt), diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 1bdefddd4970b..e97a0e3e7bbc9 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -12,6 +12,7 @@ #include "RISCVInstrInfo.h" #include "MCTargetDesc/RISCVBaseInfo.h" +#include "MCTargetDesc/RISCVMCTargetDesc.h" #include "MCTargetDesc/RISCVMatInt.h" #include "RISCV.h" #include "RISCVMachineFunctionInfo.h" @@ -238,8 +239,7 @@ Register RISCVInstrInfo::isStoreToStackSlot(const MachineInstr &MI, return 0; } -bool RISCVInstrInfo::isReMaterializableImpl( - const MachineInstr &MI) const { +bool RISCVInstrInfo::isReMaterializableImpl(const MachineInstr &MI) const { switch (RISCV::getRVVMCOpcode(MI.getOpcode())) { case RISCV::VMV_V_X: case RISCV::VFMV_V_F: @@ -486,11 +486,11 @@ void RISCVInstrInfo::copyPhysRegVector( MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc)); if (UseVMV) { const MCInstrDesc &Desc = DefMBBI->getDesc(); - MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL + MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL unsigned Log2SEW = DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm(); - MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW - MIB.addImm(0); // tu, mu + MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW + MIB.addImm(0); // tu, mu MIB.addReg(RISCV::VL, RegState::Implicit); MIB.addReg(RISCV::VTYPE, RegState::Implicit); } @@ -3120,7 +3120,8 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, Ok = Ok && Imm != 0; break; case RISCVOp::OPERAND_CLUI_IMM: - Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff); + Ok = (isUInt<5>(Imm) && Imm != 0) || + (Imm >= 0xfffe0 && Imm <= 0xfffff); break; case RISCVOp::OPERAND_RVKRNUM: Ok = Imm >= 0 && Imm <= 10; @@ -3162,8 +3163,8 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, Ok = isValidAtomicOrdering(Imm); break; case RISCVOp::OPERAND_VEC_POLICY: - Ok = (Imm & (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == - Imm; + Ok = (Imm & + (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == Imm; break; case RISCVOp::OPERAND_SEW: Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm)); @@ -3254,8 +3255,10 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, } int64_t Val = MO.getImm(); const auto &Features = STI.getFeatureBits(); - if ((Features[RISCV::FeatureAMEMatrixRegs32] && (Val < 0 || Val >= 32)) || - (Features[RISCV::FeatureAMEMatrixRegs16] && (Val < 0 || Val >= 16))) { + if ((Features[RISCV::FeatureStdExtZttMatrixRegs32] && + (Val < 0 || Val >= 32)) || + (Features[RISCV::FeatureStdExtZttMatrixRegs16] && + (Val < 0 || Val >= 16))) { ErrInfo = "matrix register index out of range for current subtarget"; return false; } @@ -3269,25 +3272,29 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, } int64_t Val = MO.getImm(); const auto &Features = STI.getFeatureBits(); - if ((Features[RISCV::FeatureAMEAccRegs4] && (Val < 0 || Val >= 4)) || - (Features[RISCV::FeatureAMEAccRegs2] && (Val < 0 || Val >= 2)) || - (Features[RISCV::FeatureAMEAccRegs1] && Val != 0)) { + if ((Features[RISCV::FeatureStdExtZttAccRegs4] && + (Val < 0 || Val >= 4)) || + (Features[RISCV::FeatureStdExtZttAccRegs2] && + (Val < 0 || Val >= 2)) || + (Features[RISCV::FeatureStdExtZttAccRegs1] && Val != 0)) { ErrInfo = "accumulator index out of range for current subtarget"; return false; } break; - }} + } + } } const uint64_t TSFlags = Desc.TSFlags; if (RISCVII::hasVLOp(TSFlags)) { const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc)); - if (!Op.isImm() && !Op.isReg()) { + if (!Op.isImm() && !Op.isReg()) { ErrInfo = "Invalid operand type for VL operand"; return false; } if (Op.isReg() && Op.getReg().isValid()) { - const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); + const MachineRegisterInfo &MRI = + MI.getParent()->getParent()->getRegInfo(); auto *RC = MRI.getRegClass(Op.getReg()); if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) { ErrInfo = "Invalid register class for VL operand"; @@ -3940,9 +3947,9 @@ void RISCVInstrInfo::buildOutlinedFrame( // Add in a return instruction to the end of the outlined frame. MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR)) - .addReg(RISCV::X0, RegState::Define) - .addReg(RISCV::X5) - .addImm(0)); + .addReg(RISCV::X0, RegState::Define) + .addReg(RISCV::X5) + .addImm(0)); } MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall( @@ -4512,8 +4519,8 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI, assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index"); unsigned Opc; switch (MI.getOpcode()) { - default: - llvm_unreachable("Unexpected opcode"); + default: + llvm_unreachable("Unexpected opcode"); CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD) CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC) CASE_VFMA_CHANGE_OPCODE_SPLATS(FMSAC, FMSUB) @@ -4551,8 +4558,8 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI, if (OpIdx1 == 3 || OpIdx2 == 3) { unsigned Opc; switch (MI.getOpcode()) { - default: - llvm_unreachable("Unexpected opcode"); + default: + llvm_unreachable("Unexpected opcode"); CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC) CASE_VFMA_CHANGE_OPCODE_VV(FMSUB, FMSAC) CASE_VFMA_CHANGE_OPCODE_VV(FNMADD, FNMACC) From 6dfef7cf526baa775e348b47f18e8e90c2890e96 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Sun, 19 Jul 2026 15:28:45 +0000 Subject: [PATCH 08/10] [RISCV: Feat] Fix operand naming, tests etc. --- llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td | 14 +- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 138 +++- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 4 +- .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 19 + .../RISCV/MCTargetDesc/RISCVInstPrinter.h | 4 + llvm/lib/Target/RISCV/RISCVFeatures.td | 20 +- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 7 +- llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 113 ++-- llvm/test/CodeGen/RISCV/attributes.ll | 4 + llvm/test/CodeGen/RISCV/features-info.ll | 6 + llvm/test/CodeGen/RISCV/ztt-intrinsics.ll | 595 ++++++++++++++++++ llvm/test/MC/RISCV/ztt-invalid.s | 68 ++ llvm/test/MC/RISCV/ztt-valid.s | 408 ++++++++++++ 13 files changed, 1301 insertions(+), 99 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/ztt-intrinsics.ll create mode 100644 llvm/test/MC/RISCV/ztt-invalid.s create mode 100644 llvm/test/MC/RISCV/ztt-valid.s diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td index 67962ca31d9f8..09f1394cbab5b 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td @@ -37,17 +37,17 @@ class AME_DataType_Set_Intr [IntrHasSideEffects, IntrNoMem, ImmArg>]>; let TargetPrefix = "riscv" in { - // agettype - get the dtype of an Acc register + // agettyp - get the dtype of an Acc register def int_riscv_ame_agettyp : AME_DataType_Get_Intr; - // asettype - set the dtype of an Acc register; zeroes the Acc register + // asettyp - set the dtype of an Acc register; zeroes the Acc register def int_riscv_ame_asettyp : AME_DataType_Set_Intr; - // mgettype - get the dtype of a M (matrix) register - def int_riscv_ame_mgettype : AME_DataType_Get_Intr; + // mgettyp - get the dtype of a M (matrix) register + def int_riscv_ame_mgettyp : AME_DataType_Get_Intr; - // sgettype - set the dtype of a M (matrix) register; zeroes the M register - def int_riscv_ame_msettype : AME_DataType_Set_Intr; + // sgettyp - set the dtype of a M (matrix) register; zeroes the M register + def int_riscv_ame_msettyp : AME_DataType_Set_Intr; } //===----------------------------------------------------------------------===// @@ -144,7 +144,7 @@ let TargetPrefix = "riscv" in { def int_riscv_ame_mmulneg_ew : AME_Elementwise_Arithmetic_Intr; // mmulneg.ew.x - md[i] = -(scalar * ms2[i]) - def int_riscv_ame_mmulneg_ew_X : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ame_mmulneg_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; // mmulsub.ew - md[i] = ms1[i] - ms2[i] * md[i] def int_riscv_ame_mmulsub_ew : AME_Elementwise_Arithmetic_Intr; diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index a859acd23ee45..20f0bb25739c9 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -222,6 +222,8 @@ class RISCVAsmParser : public MCTargetAsmParser { ParseStatus parseVTypeI(OperandVector &Operands); ParseStatus parseMaskReg(OperandVector &Operands); ParseStatus parseTHeadAMEMatrixReg(OperandVector &Operands); + ParseStatus parseZttMatrixRegIndex(OperandVector &Operands); + ParseStatus parseZttAccRegIndex(OperandVector &Operands); ParseStatus parseVScaleReg(OperandVector &Operands); ParseStatus parseTileLambda(OperandVector &Operands); ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands); @@ -2671,6 +2673,74 @@ ParseStatus RISCVAsmParser::parseTHeadAMEMatrixReg(OperandVector &Operands) { return ParseStatus::Success; } +ParseStatus RISCVAsmParser::parseZttMatrixRegIndex(OperandVector &Operands) { + if (getLexer().isNot(AsmToken::Identifier)) + return ParseStatus::NoMatch; + + StringRef Name = getLexer().getTok().getIdentifier(); + if (!Name.consume_front("m")) + return ParseStatus::NoMatch; + + unsigned Index; + if (Name.getAsInteger(10, Index)) + return ParseStatus::NoMatch; + + unsigned MaxIndex; + const auto &Features = STI->getFeatureBits(); + if (Features[RISCV::FeatureStdExtZttMatrixRegs32]) + MaxIndex = 31; + else if (Features[RISCV::FeatureStdExtZttMatrixRegs16]) + MaxIndex = 15; + else + return Error(getLoc(), + "no ztt (AME) matrix register count feature enabled"); + + if (Index > MaxIndex) + return generateImmOutOfRangeError(getLoc(), 0, MaxIndex); + + SMLoc S = getLoc(); + SMLoc E = getTok().getEndLoc(); + getLexer().Lex(); + Operands.push_back(RISCVOperand::createExpr( + MCConstantExpr::create(Index, getContext()), S, E, isRV64())); + return ParseStatus::Success; +} + +ParseStatus RISCVAsmParser::parseZttAccRegIndex(OperandVector &Operands) { + if (getLexer().isNot(AsmToken::Identifier)) + return ParseStatus::NoMatch; + + StringRef Name = getLexer().getTok().getIdentifier(); + if (!Name.consume_front("acc")) + return ParseStatus::NoMatch; + + unsigned Index; + if (Name.getAsInteger(10, Index)) + return ParseStatus::NoMatch; + + unsigned MaxIndex; + const auto &Features = STI->getFeatureBits(); + if (Features[RISCV::FeatureStdExtZttAccRegs4]) + MaxIndex = 3; + else if (Features[RISCV::FeatureStdExtZttAccRegs2]) + MaxIndex = 1; + else if (Features[RISCV::FeatureStdExtZttAccRegs1]) + MaxIndex = 0; + else + return Error(getLoc(), + "no ztt (AME) accumulator register count feature enabled"); + + if (Index > MaxIndex) + return generateImmOutOfRangeError(getLoc(), 0, MaxIndex); + + SMLoc S = getLoc(); + SMLoc E = getTok().getEndLoc(); + getLexer().Lex(); + Operands.push_back(RISCVOperand::createExpr( + MCConstantExpr::create(Index, getContext()), S, E, isRV64())); + return ParseStatus::Success; +} + ParseStatus RISCVAsmParser::parseVScaleReg(OperandVector &Operands) { if (getLexer().isNot(AsmToken::Identifier)) return ParseStatus::NoMatch; @@ -2754,8 +2824,8 @@ ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(OperandVector &Operands) { return ParseStatus::NoMatch; if ((Reg - RISCV::X0) & 1) { - // Only report the even register error if we have at least Zfinx so we know - // some FP is enabled. We already checked F earlier. + // Only report the even register error if we have at least Zfinx so we + // know some FP is enabled. We already checked F earlier. if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx)) return TokError("double precision floating point operands must use even " "numbered X register"); @@ -2784,8 +2854,8 @@ ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands, // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on // RV64 as it will prevent matching the RV64 version of the same instruction // that doesn't use a GPRPair. - // If this is an RV64 GPRPair instruction, there is no RV32 version so we can - // still parse as a pair. + // If this is an RV64 GPRPair instruction, there is no RV32 version so we + // can still parse as a pair. if (!IsRV64Inst && isRV64()) return ParseStatus::NoMatch; @@ -2930,24 +3000,24 @@ ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { } ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { - // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" - // as one of their register operands, such as `(a0)`. This just denotes that - // the register (in this case `a0`) contains a memory address. + // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory + // operand" as one of their register operands, such as `(a0)`. This just + // denotes that the register (in this case `a0`) contains a memory address. // // Normally, we would be able to parse these by putting the parens into the // instruction string. However, GNU as also accepts a zero-offset memory - // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed - // with parseExpression followed by parseMemOpBaseReg, but these instructions - // do not accept an immediate operand, and we do not want to add a "dummy" - // operand that is silently dropped. + // operand (such as `0(a0)`), and ignores the 0. Normally this would be + // parsed with parseExpression followed by parseMemOpBaseReg, but these + // instructions do not accept an immediate operand, and we do not want to + // add a "dummy" operand that is silently dropped. // // Instead, we use this custom parser. This will: allow (and discard) an // offset if it is zero; require (and discard) parentheses; and add only the // parsed register operand to `Operands`. // // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp, - // which will only print the register surrounded by parentheses (which GNU as - // also uses as its canonical representation for these operands). + // which will only print the register surrounded by parentheses (which GNU + // as also uses as its canonical representation for these operands). std::unique_ptr OptionalImmOp; if (getLexer().isNot(AsmToken::LParen)) { @@ -2979,7 +3049,8 @@ ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { if (parseToken(AsmToken::RParen, "expected ')'")) return ParseStatus::Failure; - // Deferred Handling of non-zero offsets. This makes the error messages nicer. + // Deferred Handling of non-zero offsets. This makes the error messages + // nicer. if (OptionalImmOp && !OptionalImmOp->isImmZero()) return Error( OptionalImmOp->getStartLoc(), "optional integer offset must be 0", @@ -3160,13 +3231,13 @@ ParseStatus RISCVAsmParser::parseZcmpStackAdj(OperandVector &Operands, } /// Looks at a token type and creates the relevant operand from this -/// information, adding to Operands. If operand was parsed, returns false, else -/// true. +/// information, adding to Operands. If operand was parsed, returns false, +/// else true. bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { - // Check if the current operand has a custom associated parser, if so, try to - // custom parse the operand, or fallback to the general approach. - ParseStatus Result = - MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); + // Check if the current operand has a custom associated parser, if so, try + // to custom parse the operand, or fallback to the general approach. + ParseStatus Result = MatchOperandParserImpl(Operands, Mnemonic, + /*ParseForAllFeatures=*/true); if (Result.isSuccess()) return false; if (Result.isFailure()) @@ -3193,8 +3264,8 @@ bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { // Apply mnemonic aliases because the destination mnemonic may have require - // custom operand parsing. The generic tblgen'erated code does this later, at - // the start of MatchInstructionImpl(), but that's too late for custom + // custom operand parsing. The generic tblgen'erated code does this later, + // at the start of MatchInstructionImpl(), but that's too late for custom // operand parsing. const FeatureBitset &AvailableFeatures = getAvailableFeatures(); applyMnemonicAliases(Name, AvailableFeatures, 0); @@ -3648,13 +3719,13 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { } // We only derive a length from the encoding for 16- and 32-bit - // instructions, as the encodings for longer instructions are not frozen in - // the spec. + // instructions, as the encodings for longer instructions are not frozen + // in the spec. int64_t EncodingDerivedLength = ((Value & 0b11) == 0b11) ? 4 : 2; if (Length) { - // Only check the length against the encoding if the length is present and - // could match + // Only check the length against the encoding if the length is present + // and could match if ((*Length <= 4) && (*Length != EncodingDerivedLength)) return Error(ErrorLoc, "instruction length does not match the encoding"); @@ -4362,8 +4433,8 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst, } if (MCID.TSFlags & RISCVII::SMTConstraintMask) { - // smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must not - // overlap with any of vd, vs1, or vs2. + // smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must + // not overlap with any of vd, vs1, or vs2. int VMaskIdx = RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vmask); MCRegister MaskReg = Inst.getOperand(VMaskIdx).getReg(); @@ -4490,7 +4561,8 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); return false; case RISCV::PseudoLD_RV32: - emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, /*HasTmpReg=*/false); + emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, + /*HasTmpReg=*/false); return false; case RISCV::PseudoFLH: emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); @@ -4593,8 +4665,8 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, return false; case RISCV::PseudoVMSGE_VI: case RISCV::PseudoVMSLT_VI: { - // These instructions are signed and so is immediate so we can subtract one - // and change the opcode. + // These instructions are signed and so is immediate so we can subtract + // one and change the opcode. int64_t Imm = Inst.getOperand(2).getImm(); unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI : RISCV::VMSLE_VI; @@ -4610,8 +4682,8 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case RISCV::PseudoVMSLTU_VI: { int64_t Imm = Inst.getOperand(2).getImm(); // Unsigned comparisons are tricky because the immediate is signed. If the - // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always - // false, but vmsle.vi v0, v1, -1 is always true. Instead we use + // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is + // always false, but vmsle.vi v0, v1, -1 is always true. Instead we use // vmsne v0, v1, v1 which is always false. if (Imm == 0) { unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 07db7ad22fe79..f9655934826ec 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -147,8 +147,8 @@ enum OperandType : unsigned { OPERAND_SMTVType, OPERAND_SMTI8, - OPERAND_AME_MATRIX_REG, - OPERAND_AME_ACC_REG, + OPERAND_ZTT_MATRIX_REG, + OPERAND_ZTT_ACC_REG, }; } // namespace RISCVOp diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp index 2b632fab2d526..56dc59e152630 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -360,6 +360,25 @@ void RISCVInstPrinter::printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo, O << "m" << (MO.getReg() - RISCV::THeadAMEM0); } +void RISCVInstPrinter::printZttMatrixRegIndex(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + assert(MO.isImm() && + "printZttMatrixRegIndex can only print immediate operands"); + O << "m" << MO.getImm(); +} + +void RISCVInstPrinter::printZttAccRegIndex(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + assert(MO.isImm() && "printZttAccRegIndex can only print immediate operands"); + O << "acc" << MO.getImm(); +} + void RISCVInstPrinter::printVScaleReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h index 454abdb71afb3..ca5e1dbd17b32 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -56,6 +56,10 @@ class RISCVInstPrinter : public MCInstPrinter { const MCSubtargetInfo &STI, raw_ostream &O); void printTHeadAMEMatrixReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printZttMatrixRegIndex(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); + void printZttAccRegIndex(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printVScaleReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printTileLambda(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index eacc5b92a80b3..01c41c6ec0402 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -959,24 +959,24 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">, // Attached Matrix Extension def FeatureStdExtZttMatrixRegs16 - : SubtargetFeature<"ame-mregs-16", "HasAMEMatrixRegs16", "true", - "Target supports 16 AME matrix registers">; + : SubtargetFeature<"experimental-ztt-ame-mregs-16", "HasAMEMatrixRegs16", "true", + "Enable support for 16 AME matrix registers">; def FeatureStdExtZttMatrixRegs32 - : SubtargetFeature<"ame-mregs-32", "HasAMEMatrixRegs32", "true", - "Target supports 32 AME matrix registers">; + : SubtargetFeature<"experimental-ztt-ame-mregs-32", "HasAMEMatrixRegs32", "true", + "Enable support for 32 AME matrix registers">; def FeatureStdExtZttAccRegs1 - : SubtargetFeature<"ame-accregs-1", "HasAMEAccRegs1", "true", - "Target supports 1 AME accumulator register">; + : SubtargetFeature<"experimental-ztt-ame-accregs-1", "HasAMEAccRegs1", "true", + "Enable support for AME accumulator register">; def FeatureStdExtZttAccRegs2 - : SubtargetFeature<"ame-accregs-2", "HasAMEAccRegs2", "true", - "Target supports 2 AME accumulator registers">; + : SubtargetFeature<"experimental-ztt-ame-accregs-2", "HasAMEAccRegs2", "true", + "Enable support for 2 AME accumulator registers">; def FeatureStdExtZttAccRegs4 - : SubtargetFeature<"ame-accregs-4", "HasAMEAccRegs4", "true", - "Target supports 4 AME accumulator registers">; + : SubtargetFeature<"experimental-ztt-ame-accregs-4", "HasAMEAccRegs4", "true", + "Enable support for 4 AME accumulator registers">; let Implies = [FeatureStdExtZttMatrixRegs32, FeatureStdExtZttAccRegs4] in { def FeatureStdExtZtt // By default, enabling "+ztt" implies 32 Matrix Regs and 4 Accumulators. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index e97a0e3e7bbc9..b4b67b80a64cb 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -3248,7 +3248,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, return false; } break; - case RISCVOp::OPERAND_AME_MATRIX_REG: { + case RISCVOp::OPERAND_ZTT_MATRIX_REG: { if (!MO.isImm()) { ErrInfo = "Expected an immediate operand."; return false; @@ -3265,7 +3265,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, break; } - case RISCVOp::OPERAND_AME_ACC_REG: { + case RISCVOp::OPERAND_ZTT_ACC_REG: { if (!MO.isImm()) { ErrInfo = "Expected an immediate operand."; return false; @@ -3277,7 +3277,8 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, (Features[RISCV::FeatureStdExtZttAccRegs2] && (Val < 0 || Val >= 2)) || (Features[RISCV::FeatureStdExtZttAccRegs1] && Val != 0)) { - ErrInfo = "accumulator index out of range for current subtarget"; + ErrInfo = + "accumulator register index out of range for current subtarget"; return false; } break; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td index aec255440c5ab..64ca419a609c3 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -18,34 +18,42 @@ // hardcodes "acc" and "m" prefixes so that indices 0-7 are printed as // acc0-acc7 and tr0-tr7 respectively, without modifying LLVM submodule. -// AsmOperandClass for matrix register index (0-16 or 0-32 depending on implementation) -def AMEMatrixRegIndexAsmOperand : AsmOperandClass { - let Name = "AMEMatrixRegIndex"; +// AsmOperandClass for matrix register index (m0-m16 or m0-m32 depending on implementation) +def ZttMatrixRegIndexAsmOperand : AsmOperandClass { + let Name = "ZttMatrixRegIndex"; + let ParserMethod = "parseZttMatrixRegIndex"; let RenderMethod = "addImmOperands"; let PredicateMethod = "isUImm5"; - let DiagnosticType = "InvalidAMETileIndex"; + let DiagnosticType = "InvalidZttMatrixRegIndex"; } -// AsmOperandClass for matrix register index (0, 0-1, 0-3 depending on implementation) -def AMEAccRegIndexAsmOperand : AsmOperandClass { - let Name = "AMEAccRegIndex"; +// AsmOperandClass for matrix register index (acc0, acc0-acc1, acc0-acc3 depending on implementation) +def ZttAccRegIndexAsmOperand : AsmOperandClass { + let Name = "ZttAccRegIndex"; + let ParserMethod = "parseZttAccRegIndex"; let RenderMethod = "addImmOperands"; let PredicateMethod = "isUImm2"; - let DiagnosticType = "InvalidAMEAccIndex"; + let DiagnosticType = "InvalidZttAccRegIndex"; } -// Operand type for AMEMatrixRegIndex (0-16 or 0-32) -def AMEMatrixRegIndex : RISCVOp { - let ParserMatchClass = AMEMatrixRegIndexAsmOperand; +// Operand type for ZttMatrixRegIndex (0-16 or 0-32) +def ZttMatrixRegIndex : RISCVOp { + let ParserMatchClass = ZttMatrixRegIndexAsmOperand; + // TODO: implement register index numeric range checks + // against enabled mregs/accregs subfeature in decoder method. let DecoderMethod = "decodeUImmOperand<5>"; - let OperandType = "OPERAND_AME_MATRIX_REG"; + let OperandType = "OPERAND_ZTT_MATRIX_REG"; + let PrintMethod = "printZttMatrixRegIndex"; } -// Operand type for AMEAccRegIndex (0, 0-1 or 0-3) -def AMEAccRegIndex : RISCVOp { - let ParserMatchClass = AMEAccRegIndexAsmOperand; +// Operand type for ZttAccRegIndex (0, 0-1 or 0-3) +def ZttAccRegIndex : RISCVOp { + let ParserMatchClass = ZttAccRegIndexAsmOperand; + // TODO: implement register index numeric range checks + // against enabled mregs/accregs subfeature in decoder method. let DecoderMethod = "decodeUImmOperand<2>"; - let OperandType = "OPERAND_AME_ACC_REG"; + let OperandType = "OPERAND_ZTT_ACC_REG"; + let PrintMethod = "printZttAccRegIndex"; } //===----------------------------------------------------------------------===// @@ -65,7 +73,7 @@ class RVInstAME32 funct7, dag outs, dag ins, string opcodestr, class AME_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> md; @@ -101,9 +109,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> ms2; @@ -161,9 +169,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> : RVInstAME32 { bits<5> xs1; bits<5> ms2; @@ -208,9 +216,9 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, class AME_MATMUL2D funct7, string opcodestr> : RVInstAME32 { bits<5> ms1; bits<5> ms2; @@ -239,7 +247,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mls.rm). class AME_LOAD funct7, string opcodestr> : RVInstAME32 { bits<5> xs1; @@ -262,7 +270,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 1, // mss.rm). class AME_STORE funct7, string opcodestr> : RVInstAME32 { bits<5> xs1; @@ -281,11 +289,20 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, def AME_MSS_RM : AME_STORE<0b0000011, "mss.rm">; } +def Simm7AsmOperand : SImmAsmOperand<7>; + +// 7-bit signed intermediate instr operand class (for AME_MSHIFT_EW) +def simm7 : Operand { + let ParserMatchClass = Simm7AsmOperand; + let DecoderMethod = "decodeSImmOperand<7>"; + let OperandType = "OPERAND_SIMM7"; +} + let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { // mzero.2d - clears an accumulator. def AME_MZERO_2D : RVInstAME32<0b0001000, (outs), - (ins AMEAccRegIndex: $acc), "mzero.2d", "$acc"> { + (ins ZttAccRegIndex: $acc), "mzero.2d", "$acc"> { bits<2> acc; let Inst{24 - 10} = 0b000000000010001; @@ -295,8 +312,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mmov.a.m - copy an Acc register into an M register. def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs ), - (ins AMEMatrixRegIndex: $md, - AMEAccRegIndex: $acc), + (ins ZttMatrixRegIndex: $md, + ZttAccRegIndex: $acc), "mmov.a.m", "$md, $acc"> { bits<2> acc; bits<5> md; @@ -309,8 +326,8 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mmov.m.m - copy one M register into another. def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs ), - (ins AMEMatrixRegIndex: $md, - AMEMatrixRegIndex: $ms), + (ins ZttMatrixRegIndex: $md, + ZttMatrixRegIndex: $ms), "mmov.m.m", "$md, $ms"> { bits<5> ms; bits<5> md; @@ -322,7 +339,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mgettyp - read an M register's dtype tag into a GPR. def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR: $xd), - (ins AMEMatrixRegIndex: $ms1), + (ins ZttMatrixRegIndex: $ms1), "mgettyp", "$xd, $ms1"> { bits<5> ms1; bits<5> xd; @@ -335,7 +352,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // agettyp - read an Acc register's dtype tag into a GPR. def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR: $xd), - (ins AMEAccRegIndex: $ad), + (ins ZttAccRegIndex: $ad), "agettyp", "$xd, $ad"> { bits<2> ad; bits<5> xd; @@ -348,7 +365,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // msettyp - write a GPR value as an M register's dtype tag. def AME_MSETTYP : RVInstAME32<0b0000001, (outs ), - (ins AMEMatrixRegIndex: $md, + (ins ZttMatrixRegIndex: $md, GPR: $xs1), "msettyp", "$md, $xs1"> { bits<5> xs1; @@ -362,7 +379,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // asettyp - write a GPR value as an Acc register's dtype tag. def AME_ASETTYP : RVInstAME32<0b0000011, (outs ), - (ins AMEAccRegIndex: $ad, + (ins ZttAccRegIndex: $ad, GPR: $xs1), "asettyp", "$ad, $xs1"> { bits<5> xs1; @@ -376,7 +393,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mbcast.x - broadcast a GPR scalar to every element of an M register. def AME_MBCAST_X : RVInstAME32<0b0000000, (outs ), - (ins AMEMatrixRegIndex: $md, + (ins ZttMatrixRegIndex: $md, GPR: $xs1), "mbcast.x", "$md, $xs1"> { bits<5> xs1; @@ -388,9 +405,10 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, let Inst{11 - 7} = md; } + // mshift.ew - md[i,j] = ms1[i, j+imm], or 0 if j+imm is out of bounds def AME_MSHIFT_EW : RVInst<(outs ), - (ins AMEMatrixRegIndex:$md, AMEMatrixRegIndex:$ms1, i64imm:$imm), + (ins ZttMatrixRegIndex:$md, ZttMatrixRegIndex:$ms1, simm7:$imm), "mshift.ew", "$md, $ms1, $imm", [], InstFormatOther> { bits<5> ms1; bits<7> imm; @@ -482,7 +500,7 @@ class AMEBinScalarPat : Pat<(intr timm:$md, i64:$xs1, timm:$ms2), (inst timm:$md, GPR:$xs1, timm:$ms2)>; -let Predicates = [HasStdExtZtt] in { +let Predicates = [HasStdExtZtt, IsRV64] in { def : AMEBinScalarPat; def : AMEBinScalarPat; def : AMEBinScalarPat; @@ -500,7 +518,7 @@ let Predicates = [HasStdExtZtt] in { def : AMEBinScalarPat; def : AMEBinScalarPat; def : AMEBinScalarPat; - def : AMEBinScalarPat; + def : AMEBinScalarPat; def : AMEBinScalarPat; def : AMEBinScalarPat; def : AMEBinScalarPat; @@ -537,14 +555,11 @@ let Predicates = [HasStdExtZtt] in { def : Pat<(int_riscv_ame_mss_rm timm:$ms1, iPTR:$xs1), (AME_MSS_RM timm:$ms1, GPR:$xs1)>; // Broadcast & Zero - def : Pat<(int_riscv_ame_mbcast_x timm:$md, i64:$xs1), (AME_MBCAST_X timm:$md, GPR:$xs1)>; def : Pat<(int_riscv_ame_mzero_2d timm:$acc), (AME_MZERO_2D timm:$acc)>; // Type operations - def : Pat<(int_riscv_ame_mgettype timm:$ms1), (AME_MGETTYP timm:$ms1)>; + def : Pat<(int_riscv_ame_mgettyp timm:$ms1), (AME_MGETTYP timm:$ms1)>; def : Pat<(int_riscv_ame_agettyp timm:$ad), (AME_AGETTYP timm:$ad)>; - def : Pat<(int_riscv_ame_msettype timm:$md, i64:$xs1), (AME_MSETTYP timm:$md, GPR:$xs1)>; - def : Pat<(int_riscv_ame_asettyp timm:$ad, i64:$xs1), (AME_ASETTYP timm:$ad, GPR:$xs1)>; // Moves def : Pat<(int_riscv_ame_mmov_a_m timm:$md, timm:$acc), (AME_MMOV_A_M timm:$md, timm:$acc)>; @@ -553,6 +568,16 @@ let Predicates = [HasStdExtZtt] in { (AME_MSHIFT_EW timm:$md, timm:$ms1, timm:$imm)>; } +// Miscellaneous instructions with scalar operands +let Predicates = [HasStdExtZtt, IsRV64] in { + // Broadcast & Zero + def : Pat<(int_riscv_ame_mbcast_x timm:$md, i64:$xs1), (AME_MBCAST_X timm:$md, GPR:$xs1)>; + + // Type operations + def : Pat<(int_riscv_ame_msettyp timm:$md, i64:$xs1), (AME_MSETTYP timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ame_asettyp timm:$ad, i64:$xs1), (AME_ASETTYP timm:$ad, GPR:$xs1)>; +} + // TODO: // Define mpack.ew.x / munpack.ew.x (instruction defintiion/encoding and LLVM IR intrinsics -> MachineInstruction/MCInst isel patterns). // diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 26ffd8bb4ec89..39c76cb500381 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -113,6 +113,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvdot4a8i %s -o - | FileCheck --check-prefix=RV32ZVDOT4A8I %s ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvzip %s -o - | FileCheck --check-prefix=RV32ZVZIP %s ; RUN: llc -mtriple=riscv32 -mattr=+zvfh %s -o - | FileCheck --check-prefix=RV32ZVFH %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-ztt %s -o - | FileCheck --check-prefix=RV32ZTT %s ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvabd %s -o - | FileCheck --check-prefix=RV32ZVABD %s ; RUN: llc -mtriple=riscv32 -mattr=+zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %s ; RUN: llc -mtriple=riscv32 -mattr=+zilsd %s -o - | FileCheck --check-prefix=RV32ZILSD %s @@ -281,6 +282,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+zve32f -mattr=+experimental-zvfqwdota8f %s -o - | FileCheck --check-prefix=RV64ZVFQWDOTA8F %s ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvzip %s -o - | FileCheck --check-prefix=RV64ZVZIP %s ; RUN: llc -mtriple=riscv64 -mattr=+zvfh %s -o - | FileCheck --check-prefix=RV64ZVFH %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-ztt %s -o - | FileCheck --check-prefix=RV64ZTT %s ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvabd %s -o - | FileCheck --check-prefix=RV64ZVABD %s ; RUN: llc -mtriple=riscv64 -mattr=+zicond %s -o - | FileCheck --check-prefix=RV64ZICOND %s ; RUN: llc -mtriple=riscv64 -mattr=+zimop %s -o - | FileCheck --check-prefix=RV64ZIMOP %s @@ -454,6 +456,7 @@ ; RV32ZVDOT4A8I: .attribute 5, "rv32i2p1_zicsr2p0_zvdot4a8i0p1_zve32x1p0_zvl32b1p0" ; RV32ZVZIP: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvzip0p1" ; RV32ZVFH: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0" +; RV32ZTT: .attribute 5, "rv32i2p1_ztt0p1" ; RV32ZVABD: .attribute 5, "rv32i2p1_zicsr2p0_zvabd0p7_zve32x1p0_zvl32b1p0" ; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0" ; RV32ZILSD: .attribute 5, "rv32i2p1_zilsd1p0" @@ -619,6 +622,7 @@ ; RV64ZVFQWDOTA8F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfqwdota8f0p2_zvl32b1p0" ; RV64ZVZIP: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvzip0p1" ; RV64ZVFH: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0" +; RV64ZTT: .attribute 5, "rv64i2p1_ztt0p1" ; RV64ZVABD: .attribute 5, "rv64i2p1_zicsr2p0_zvabd0p7_zve32x1p0_zvl32b1p0" ; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0" ; RV64ZIMOP: .attribute 5, "rv64i2p1_zimop1p0" diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll index 2fa78721a2cec..097e55c1b0cba 100644 --- a/llvm/test/CodeGen/RISCV/features-info.ll +++ b/llvm/test/CodeGen/RISCV/features-info.ll @@ -33,6 +33,12 @@ ; CHECK-NEXT: experimental-zibi - 'Zibi' (Branch with Immediate). ; CHECK-NEXT: experimental-zicfilp - 'Zicfilp' (Landing pad). ; CHECK-NEXT: experimental-zicfiss - 'Zicfiss' (Shadow stack). +; CHECK-NEXT: experimental-ztt - 'Ztt' (Attached Matrix Extension). +; CHECK-NEXT: experimental-ztt-ame-accregs-1 - Enable support for AME accumulator register. +; CHECK-NEXT: experimental-ztt-ame-accregs-2 - Enable support for 2 AME accumulator registers. +; CHECK-NEXT: experimental-ztt-ame-accregs-4 - Enable support for 4 AME accumulator registers. +; CHECK-NEXT: experimental-ztt-ame-mregs-16 - Enable support for 16 AME matrix registers. +; CHECK-NEXT: experimental-ztt-ame-mregs-32 - Enable support for 32 AME matrix registers. ; CHECK-NEXT: experimental-zvabd - 'Zvabd' (Vector Absolute Difference). ; CHECK-NEXT: experimental-zvbc32e - 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements). ; CHECK-NEXT: experimental-zvdot4a8i - 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers). diff --git a/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll b/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll new file mode 100644 index 0000000000000..92922f5c3cb6d --- /dev/null +++ b/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll @@ -0,0 +1,595 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+experimental-ztt -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64 + +define void @test_mabs_ew() { + call void @llvm.riscv.ame.mabs.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mabs.ew(i64, i64) + +define void @test_mcolunzip_ew() { + call void @llvm.riscv.ame.mcolunzip.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mcolunzip.ew(i64, i64) + +define void @test_mcolzip_ew() { + call void @llvm.riscv.ame.mcolzip.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mcolzip.ew(i64, i64) + +define void @test_mconv_ew() { + call void @llvm.riscv.ame.mconv.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mconv.ew(i64, i64) + +define void @test_mexp2_ew() { + call void @llvm.riscv.ame.mexp2.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mexp2.ew(i64, i64) + +define void @test_mlog2_ew() { + call void @llvm.riscv.ame.mlog2.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mlog2.ew(i64, i64) + +define void @test_mprefixadd_col() { + call void @llvm.riscv.ame.mprefixadd.col(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mprefixadd.col(i64, i64) + +define void @test_mprefixadd_row() { + call void @llvm.riscv.ame.mprefixadd.row(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mprefixadd.row(i64, i64) + +define void @test_mprefixmax_col() { + call void @llvm.riscv.ame.mprefixmax.col(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mprefixmax.col(i64, i64) + +define void @test_mprefixmax_row() { + call void @llvm.riscv.ame.mprefixmax.row(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mprefixmax.row(i64, i64) + +define void @test_mreduceadd_col() { + call void @llvm.riscv.ame.mreduceadd.col(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mreduceadd.col(i64, i64) + +define void @test_mreduceadd_row() { + call void @llvm.riscv.ame.mreduceadd.row(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mreduceadd.row(i64, i64) + +define void @test_mreducemax_col() { + call void @llvm.riscv.ame.mreducemax.col(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mreducemax.col(i64, i64) + +define void @test_mreducemax_row() { + call void @llvm.riscv.ame.mreducemax.row(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mreducemax.row(i64, i64) + +define void @test_mrowunzip_ew() { + call void @llvm.riscv.ame.mrowunzip.ew(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mrowunzip.ew(i64, i64) + +define void @test_mabsdiff_ew() { + call void @llvm.riscv.ame.mabsdiff.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mabsdiff.ew(i64, i64, i64) + +define void @test_madd_ew() { + call void @llvm.riscv.ame.madd.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.madd.ew(i64, i64, i64) + +define void @test_mand_ew() { + call void @llvm.riscv.ame.mand.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mand.ew(i64, i64, i64) + +define void @test_mandnot_ew() { + call void @llvm.riscv.ame.mandnot.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mandnot.ew(i64, i64, i64) + +define void @test_mcmovge_ew() { + call void @llvm.riscv.ame.mcmovge.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mcmovge.ew(i64, i64, i64) + +define void @test_mcmovlt_ew() { + call void @llvm.riscv.ame.mcmovlt.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mcmovlt.ew(i64, i64, i64) + +define void @test_mcmpge_ew() { + call void @llvm.riscv.ame.mcmpge.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mcmpge.ew(i64, i64, i64) + +define void @test_mcmplt_ew() { + call void @llvm.riscv.ame.mcmplt.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mcmplt.ew(i64, i64, i64) + +define void @test_mgather_ew() { + call void @llvm.riscv.ame.mgather.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mgather.ew(i64, i64, i64) + +define void @test_mhdiff_ew() { + call void @llvm.riscv.ame.mhdiff.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mhdiff.ew(i64, i64, i64) + +define void @test_mldexp_ew() { + call void @llvm.riscv.ame.mldexp.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mldexp.ew(i64, i64, i64) + +define void @test_mldexpacc_ew() { + call void @llvm.riscv.ame.mldexpacc.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mldexpacc.ew(i64, i64, i64) + +define void @test_mlog2sub_ew() { + call void @llvm.riscv.ame.mlog2sub.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mlog2sub.ew(i64, i64, i64) + +define void @test_mmax_ew() { + call void @llvm.riscv.ame.mmax.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmax.ew(i64, i64, i64) + +define void @test_mmean_ew() { + call void @llvm.riscv.ame.mmean.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmean.ew(i64, i64, i64) + +define void @test_mmin_ew() { + call void @llvm.riscv.ame.mmin.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmin.ew(i64, i64, i64) + +define void @test_mmul_ew() { + call void @llvm.riscv.ame.mmul.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmul.ew(i64, i64, i64) + +define void @test_mmulacc_ew() { + call void @llvm.riscv.ame.mmulacc.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulacc.ew(i64, i64, i64) + +define void @test_mmulaccneg_ew() { + call void @llvm.riscv.ame.mmulaccneg.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulaccneg.ew(i64, i64, i64) + +define void @test_mmuladd_ew() { + call void @llvm.riscv.ame.mmuladd.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmuladd.ew(i64, i64, i64) + +define void @test_mmulneg_ew() { + call void @llvm.riscv.ame.mmulneg.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulneg.ew(i64, i64, i64) + +define void @test_mmulsub_ew() { + call void @llvm.riscv.ame.mmulsub.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulsub.ew(i64, i64, i64) + +define void @test_mor_ew() { + call void @llvm.riscv.ame.mor.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mor.ew(i64, i64, i64) + +define void @test_mornot_ew() { + call void @llvm.riscv.ame.mornot.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mornot.ew(i64, i64, i64) + +define void @test_mrdexp_ew() { + call void @llvm.riscv.ame.mrdexp.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mrdexp.ew(i64, i64, i64) + +define void @test_mrdexpacc_ew() { + call void @llvm.riscv.ame.mrdexpacc.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mrdexpacc.ew(i64, i64, i64) + +define void @test_mrowzip_ew() { + call void @llvm.riscv.ame.mrowzip.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mrowzip.ew(i64, i64, i64) + +define void @test_mscatadd_col() { + call void @llvm.riscv.ame.mscatadd.col(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mscatadd.col(i64, i64, i64) + +define void @test_mscatadd_row() { + call void @llvm.riscv.ame.mscatadd.row(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mscatadd.row(i64, i64, i64) + +define void @test_mscatmax_col() { + call void @llvm.riscv.ame.mscatmax.col(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mscatmax.col(i64, i64, i64) + +define void @test_mscatmax_row() { + call void @llvm.riscv.ame.mscatmax.row(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mscatmax.row(i64, i64, i64) + +define void @test_mselge_ew() { + call void @llvm.riscv.ame.mselge.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mselge.ew(i64, i64, i64) + +define void @test_msellt_ew() { + call void @llvm.riscv.ame.msellt.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.msellt.ew(i64, i64, i64) + +define void @test_msub_ew() { + call void @llvm.riscv.ame.msub.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.msub.ew(i64, i64, i64) + +define void @test_msublog2_ew() { + call void @llvm.riscv.ame.msublog2.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.msublog2.ew(i64, i64, i64) + +define void @test_mxor_ew() { + call void @llvm.riscv.ame.mxor.ew(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mxor.ew(i64, i64, i64) + +define void @test_mabsdiff_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mabsdiff.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mabsdiff.ew.x(i64, i64, i64) + +define void @test_madd_ew_x(i64 %a1) { + call void @llvm.riscv.ame.madd.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.madd.ew.x(i64, i64, i64) + +define void @test_mand_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mand.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mand.ew.x(i64, i64, i64) + +define void @test_mandnot_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mandnot.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mandnot.ew.x(i64, i64, i64) + +define void @test_mcmpge_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mcmpge.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mcmpge.ew.x(i64, i64, i64) + +define void @test_mcmplt_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mcmplt.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mcmplt.ew.x(i64, i64, i64) + +define void @test_mhdiff_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mhdiff.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mhdiff.ew.x(i64, i64, i64) + +define void @test_mldexp_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mldexp.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mldexp.ew.x(i64, i64, i64) + +define void @test_mldexpacc_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mldexpacc.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mldexpacc.ew.x(i64, i64, i64) + +define void @test_mlog2sub_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mlog2sub.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mlog2sub.ew.x(i64, i64, i64) + +define void @test_mmax_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmax.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmax.ew.x(i64, i64, i64) + +define void @test_mmean_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmean.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmean.ew.x(i64, i64, i64) + +define void @test_mmin_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmin.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmin.ew.x(i64, i64, i64) + +define void @test_mmul_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmul.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmul.ew.x(i64, i64, i64) + +define void @test_mmulacc_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmulacc.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmulacc.ew.x(i64, i64, i64) + +define void @test_mmulaccneg_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmulaccneg.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmulaccneg.ew.x(i64, i64, i64) + +define void @test_mmuladd_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmuladd.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmuladd.ew.x(i64, i64, i64) + +define void @test_mmulneg_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmulneg.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmulneg.ew.x(i64, i64, i64) + +define void @test_mmulsub_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mmulsub.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmulsub.ew.x(i64, i64, i64) + +define void @test_mor_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mor.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mor.ew.x(i64, i64, i64) + +define void @test_mornot_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mornot.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mornot.ew.x(i64, i64, i64) + +define void @test_msub_ew_x(i64 %a1) { + call void @llvm.riscv.ame.msub.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.msub.ew.x(i64, i64, i64) + +define void @test_msublog2_ew_x(i64 %a1) { + call void @llvm.riscv.ame.msublog2.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.msublog2.ew.x(i64, i64, i64) + +define void @test_mxor_ew_x(i64 %a1) { + call void @llvm.riscv.ame.mxor.ew.x(i64 1, i64 %a1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mxor.ew.x(i64, i64, i64) + +define void @test_mmul_2d() { + call void @llvm.riscv.ame.mmul.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmul.2d(i64, i64, i64) + +define void @test_mmulacc_2d() { + call void @llvm.riscv.ame.mmulacc.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulacc.2d(i64, i64, i64) + +define void @test_mmulaccneg_2d() { + call void @llvm.riscv.ame.mmulaccneg.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulaccneg.2d(i64, i64, i64) + +define void @test_mmulat_2d() { + call void @llvm.riscv.ame.mmulat.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulat.2d(i64, i64, i64) + +define void @test_mmulatacc_2d() { + call void @llvm.riscv.ame.mmulatacc.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulatacc.2d(i64, i64, i64) + +define void @test_mmulbt_2d() { + call void @llvm.riscv.ame.mmulbt.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulbt.2d(i64, i64, i64) + +define void @test_mmulbtacc_2d() { + call void @llvm.riscv.ame.mmulbtacc.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulbtacc.2d(i64, i64, i64) + +define void @test_mmulneg_2d() { + call void @llvm.riscv.ame.mmulneg.2d(i64 1, i64 2, i64 3) + ret void +} +declare void @llvm.riscv.ame.mmulneg.2d(i64, i64, i64) + +define void @test_mls(ptr %addr) { + call void @llvm.riscv.ame.mls(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mls(i64, ptr) + +define void @test_mls_cm(ptr %addr) { + call void @llvm.riscv.ame.mls.cm(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mls.cm(i64, ptr) + +define void @test_mls_rm(ptr %addr) { + call void @llvm.riscv.ame.mls.rm(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mls.rm(i64, ptr) + +define void @test_mss(ptr %addr) { + call void @llvm.riscv.ame.mss(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mss(i64, ptr) + +define void @test_mss_cm(ptr %addr) { + call void @llvm.riscv.ame.mss.cm(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mss.cm(i64, ptr) + +define void @test_mss_rm(ptr %addr) { + call void @llvm.riscv.ame.mss.rm(i64 1, ptr %addr) + ret void +} +declare void @llvm.riscv.ame.mss.rm(i64, ptr) + +define void @test_mzero_2d() { + call void @llvm.riscv.ame.mzero.2d(i64 1) + ret void +} +declare void @llvm.riscv.ame.mzero.2d(i64) + +define void @test_mmov_a_m() { + call void @llvm.riscv.ame.mmov.a.m(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmov.a.m(i64, i64) + +define void @test_mmov_m_m() { + call void @llvm.riscv.ame.mmov.m.m(i64 1, i64 2) + ret void +} +declare void @llvm.riscv.ame.mmov.m.m(i64, i64) + +define i64 @test_mgettyp() { + %type = call i64 @llvm.riscv.ame.mgettyp(i64 1) + ret i64 %type +} +declare i64 @llvm.riscv.ame.mgettyp(i64) + +define i64 @test_agettyp() { + %type = call i64 @llvm.riscv.ame.agettyp(i64 1) + ret i64 %type +} +declare i64 @llvm.riscv.ame.agettyp(i64) + +define void @test_msettyp(i64 %a1) { + call void @llvm.riscv.ame.msettyp(i64 1, i64 %a1) + ret void +} +declare void @llvm.riscv.ame.msettyp(i64, i64) + +define void @test_asettyp(i64 %a1) { + call void @llvm.riscv.ame.asettyp(i64 1, i64 %a1) + ret void +} +declare void @llvm.riscv.ame.asettyp(i64, i64) + +define void @test_mbcast_x(i64 %a1) { + call void @llvm.riscv.ame.mbcast.x(i64 1, i64 %a1) + ret void +} +declare void @llvm.riscv.ame.mbcast.x(i64, i64) + +define void @test_mshift_ew_pos() { + call void @llvm.riscv.ame.mshift.ew(i64 1, i64 2, i64 5) + ret void +} + +define void @test_mshift_ew_neg() { + call void @llvm.riscv.ame.mshift.ew(i64 1, i64 2, i64 -3) + ret void +} +declare void @llvm.riscv.ame.mshift.ew(i64, i64, i64) diff --git a/llvm/test/MC/RISCV/ztt-invalid.s b/llvm/test/MC/RISCV/ztt-invalid.s new file mode 100644 index 0000000000000..815606ed5f924 --- /dev/null +++ b/llvm/test/MC/RISCV/ztt-invalid.s @@ -0,0 +1,68 @@ +# RUN: not llvm-mc -triple=riscv64 --mattr=-experimental-ztt-ame-mregs-16,-experimental-ztt-ame-mregs-32 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-NO-M-CONFIG +# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-ztt-ame-mregs-16,+experimental-ztt-ame-mregs-32 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-CONFLICT-M + +# CHECK-NO-M-CONFIG: error: AME subtarget extension requires a matrix register configuration width to be chosen +# CHECK-CONFLICT-M: error: Conflicting AME register bounds chosen: cannot enable both 16 and 32 matrix registers simultaneously + +# RUN: not llvm-mc -triple=riscv64 --mattr=-experimental-ztt-ame-accregs-1,-experimental-ztt-ame-accregs-2,-experimental-ztt-ame-accregs-4 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-NO-ACC-CONFIG +# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-ztt-ame-accregs-1,+experimental-ztt-ame-accregs-2 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-CONFLICT-ACC + +# CHECK-NO-ACC-CONFIG: error: AME subtarget extension requires an accumulator register configuration count to be chosen +# CHECK-CONFLICT-ACC: error: Conflicting AME accumulator bounds chosen: cannot enable multiple accumulator register configurations simultaneously + +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt %s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-64 +# RUN: not llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-ztt %s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-32 +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-mregs-16 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-M16 +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-1 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ACC1 +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-2 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ACC2 + +# Immediate underflow: Value falls below the 7-bit signed boundary +# CHECK: :[[@LINE+1]]:24: error: immediate must be an integer in the range [-64, 63] +mshift.ew m1, m2, -65 + +# Immediate overflow: Value exceeds the 7-bit signed boundary +# CHECK: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-64, 63] +mshift.ew m1, m2, 64 + +# Base register mismatch: Instruction expects matrix register class +# but gets scalar GPR. +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +mshift.ew x10, m2, 5 + +# Operand type mismatch: Instruction expects scalar register class but +# gets accumulator register. +# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction +msettyp m1, acc1 + +# Destination target mismatch: Broadcast instruction targets accumulator +# instead of matrix register. +# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +mbcast.x acc1, a0 + +# Syntax error: Operand count is lower than instruction signature requirements +# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +mshift.ew m1, m2 + +# Matrix register out of bounds: Attempting to access m16 when constraint +# drops limit down to 16. +# CHECK-M16: :[[@LINE+1]]:11: error: invalid operand for instruction +mabs.ew m16, m2 + +# Accumulator register out of bounds: Attempting to access acc1 when configuration +# limits context to 1 accumulator (acc0). +# CHECK-ACC1: :[[@LINE+1]]:14: error: invalid operand for instruction +agettyp a0, acc1 + +# Accumulator register out of bounds: Attempting to access acc2 when configuration +# limits context to 2 accumulators (acc0-acc1). +# CHECK-ACC2: :[[@LINE+1]]:14: error: invalid operand for instruction +agettyp a0, acc2 diff --git a/llvm/test/MC/RISCV/ztt-valid.s b/llvm/test/MC/RISCV/ztt-valid.s new file mode 100644 index 0000000000000..458749b84d7c2 --- /dev/null +++ b/llvm/test/MC/RISCV/ztt-valid.s @@ -0,0 +1,408 @@ +# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-ztt %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-ztt %s \ +# RUN: | llvm-objdump --no-print-imm-hex -d --mattr=+experimental-ztt - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST +# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+experimental-ztt %s \ +# RUN: | llvm-objdump --no-print-imm-hex -d --mattr=+experimental-ztt - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST + +mabs.ew m1, m2 +# CHECK-INST: mabs.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x00] + +mcolunzip.ew m1, m2 +# CHECK-INST: mcolunzip.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x08] + +mcolzip.ew m1, m2 +# CHECK-INST: mcolzip.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x06] + +mconv.ew m1, m2 +# CHECK-INST: mconv.ew m1, m2 +# CHECK-ENCODING: [0xab,0x50,0x01,0x00] + +mexp2.ew m1, m2 +# CHECK-INST: mexp2.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x02] + +mlog2.ew m1, m2 +# CHECK-INST: mlog2.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x04] + +mprefixadd.col m1, m2 +# CHECK-INST: mprefixadd.col m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x18] + +mprefixadd.row m1, m2 +# CHECK-INST: mprefixadd.row m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x10] + +mprefixmax.col m1, m2 +# CHECK-INST: mprefixmax.col m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x1a] + +mprefixmax.row m1, m2 +# CHECK-INST: mprefixmax.row m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x12] + +mreduceadd.col m1, m2 +# CHECK-INST: mreduceadd.col m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x14] + +mreduceadd.row m1, m2 +# CHECK-INST: mreduceadd.row m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x0c] + +mreducemax.col m1, m2 +# CHECK-INST: mreducemax.col m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x16] + +mreducemax.row m1, m2 +# CHECK-INST: mreducemax.row m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x0e] + +mrowunzip.ew m1, m2 +# CHECK-INST: mrowunzip.ew m1, m2 +# CHECK-ENCODING: [0xab,0x10,0x01,0x0a] + +mabsdiff.ew m1, m2, m3 +# CHECK-INST: mabsdiff.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x08] + +madd.ew m1, m2, m3 +# CHECK-INST: madd.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x00] + +mand.ew m1, m2, m3 +# CHECK-INST: mand.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x0e] + +mandnot.ew m1, m2, m3 +# CHECK-INST: mandnot.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x10] + +mcmovge.ew m1, m2, m3 +# CHECK-INST: mcmovge.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x20] + +mcmovlt.ew m1, m2, m3 +# CHECK-INST: mcmovlt.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x22] + +mcmpge.ew m1, m2, m3 +# CHECK-INST: mcmpge.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x18] + +mcmplt.ew m1, m2, m3 +# CHECK-INST: mcmplt.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x1a] + +mgather.ew m1, m2, m3 +# CHECK-INST: mgather.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x30] + +mhdiff.ew m1, m2, m3 +# CHECK-INST: mhdiff.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x06] + +mldexp.ew m1, m2, m3 +# CHECK-INST: mldexp.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x24] + +mldexpacc.ew m1, m2, m3 +# CHECK-INST: mldexpacc.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x26] + +mlog2sub.ew m1, m2, m3 +# CHECK-INST: mlog2sub.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x2c] + +mmax.ew m1, m2, m3 +# CHECK-INST: mmax.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x0a] + +mmean.ew m1, m2, m3 +# CHECK-INST: mmean.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x04] + +mmin.ew m1, m2, m3 +# CHECK-INST: mmin.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x0c] + +mmul.ew m1, m2, m3 +# CHECK-INST: mmul.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x38] + +mmulacc.ew m1, m2, m3 +# CHECK-INST: mmulacc.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x3a] + +mmulaccneg.ew m1, m2, m3 +# CHECK-INST: mmulaccneg.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x40] + +mmuladd.ew m1, m2, m3 +# CHECK-INST: mmuladd.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x3c] + +mmulneg.ew m1, m2, m3 +# CHECK-INST: mmulneg.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x42] + +mmulsub.ew m1, m2, m3 +# CHECK-INST: mmulsub.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x3e] + +mor.ew m1, m2, m3 +# CHECK-INST: mor.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x12] + +mornot.ew m1, m2, m3 +# CHECK-INST: mornot.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x14] + +mrdexp.ew m1, m2, m3 +# CHECK-INST: mrdexp.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x28] + +mrdexpacc.ew m1, m2, m3 +# CHECK-INST: mrdexpacc.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x2a] + +mrowzip.ew m1, m2, m3 +# CHECK-INST: mrowzip.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x36] + +mscatadd.col m1, m2, m3 +# CHECK-INST: mscatadd.col m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x44] + +mscatadd.row m1, m2, m3 +# CHECK-INST: mscatadd.row m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x32] + +mscatmax.col m1, m2, m3 +# CHECK-INST: mscatmax.col m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x46] + +mscatmax.row m1, m2, m3 +# CHECK-INST: mscatmax.row m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x34] + +mselge.ew m1, m2, m3 +# CHECK-INST: mselge.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x1c] + +msellt.ew m1, m2, m3 +# CHECK-INST: msellt.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x1e] + +msub.ew m1, m2, m3 +# CHECK-INST: msub.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x02] + +msublog2.ew m1, m2, m3 +# CHECK-INST: msublog2.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x2e] + +mxor.ew m1, m2, m3 +# CHECK-INST: mxor.ew m1, m2, m3 +# CHECK-ENCODING: [0xab,0x00,0x31,0x16] + +mabsdiff.ew.x m1, a0, m3 +# CHECK-INST: mabsdiff.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x0a] + +madd.ew.x m1, a0, m3 +# CHECK-INST: madd.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x00] + +mand.ew.x m1, a0, m3 +# CHECK-INST: mand.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x0e] + +mandnot.ew.x m1, a0, m3 +# CHECK-INST: mandnot.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x10] + +mcmpge.ew.x m1, a0, m3 +# CHECK-INST: mcmpge.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x18] + +mcmplt.ew.x m1, a0, m3 +# CHECK-INST: mcmplt.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x1a] + +mhdiff.ew.x m1, a0, m3 +# CHECK-INST: mhdiff.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x0c] + +mldexp.ew.x m1, a0, m3 +# CHECK-INST: mldexp.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x20] + +mldexpacc.ew.x m1, a0, m3 +# CHECK-INST: mldexpacc.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x22] + +mlog2sub.ew.x m1, a0, m3 +# CHECK-INST: mlog2sub.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x1c] + +mmax.ew.x m1, a0, m3 +# CHECK-INST: mmax.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x06] + +mmean.ew.x m1, a0, m3 +# CHECK-INST: mmean.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x08] + +mmin.ew.x m1, a0, m3 +# CHECK-INST: mmin.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x04] + +mmul.ew.x m1, a0, m3 +# CHECK-INST: mmul.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x24] + +mmulacc.ew.x m1, a0, m3 +# CHECK-INST: mmulacc.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x26] + +mmulaccneg.ew.x m1, a0, m3 +# CHECK-INST: mmulaccneg.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x2c] + +mmuladd.ew.x m1, a0, m3 +# CHECK-INST: mmuladd.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x28] + +mmulneg.ew.x m1, a0, m3 +# CHECK-INST: mmulneg.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x2e] + +mmulsub.ew.x m1, a0, m3 +# CHECK-INST: mmulsub.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x2a] + +mor.ew.x m1, a0, m3 +# CHECK-INST: mor.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x12] + +mornot.ew.x m1, a0, m3 +# CHECK-INST: mornot.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x14] + +msub.ew.x m1, a0, m3 +# CHECK-INST: msub.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x02] + +msublog2.ew.x m1, a0, m3 +# CHECK-INST: msublog2.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x1e] + +mxor.ew.x m1, a0, m3 +# CHECK-INST: mxor.ew.x m1, a0, m3 +# CHECK-ENCODING: [0xab,0x20,0x35,0x16] + +mmul.2d acc1, m2, m3 +# CHECK-INST: mmul.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x00] + +mmulacc.2d acc1, m2, m3 +# CHECK-INST: mmulacc.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x02] + +mmulaccneg.2d acc1, m2, m3 +# CHECK-INST: mmulaccneg.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x06] + +mmulat.2d acc1, m2, m3 +# CHECK-INST: mmulat.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x08] + +mmulatacc.2d acc1, m2, m3 +# CHECK-INST: mmulatacc.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x0a] + +mmulbt.2d acc1, m2, m3 +# CHECK-INST: mmulbt.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x0c] + +mmulbtacc.2d acc1, m2, m3 +# CHECK-INST: mmulbtacc.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x0e] + +mmulneg.2d acc1, m2, m3 +# CHECK-INST: mmulneg.2d acc1, m2, m3 +# CHECK-ENCODING: [0x2b,0x21,0x31,0x04] + +# Interoperability loads (md, xs1:address) +mls m1, a0 +# CHECK-INST: mls m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x04] + +mls.cm m1, a0 +# CHECK-INST: mls.cm m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x02] + +mls.rm m1, a0 +# CHECK-INST: mls.rm m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x00] + +# Interoperability stores (ms1, xs1:address) +mss m1, a0 +# CHECK-INST: mss m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x0a] + +mss.cm m1, a0 +# CHECK-INST: mss.cm m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x08] + +mss.rm m1, a0 +# CHECK-INST: mss.rm m1, a0 +# CHECK-ENCODING: [0xab,0x30,0x05,0x06] + +mzero.2d acc1 +# CHECK-INST: mzero.2d acc1 +# CHECK-ENCODING: [0x2b,0x45,0x00,0x10] + +mmov.a.m m1, acc2 +# CHECK-INST: mmov.a.m m1, acc2 +# CHECK-ENCODING: [0xab,0x40,0x20,0x06] + +mmov.m.m m1, m2 +# CHECK-INST: mmov.m.m m1, m2 +# CHECK-ENCODING: [0xab,0x40,0x20,0x04] + +mgettyp a0, m1 +# CHECK-INST: mgettyp a0, m1 +# CHECK-ENCODING: [0x2b,0xd5,0x00,0x04] + +agettyp a0, acc1 +# CHECK-INST: agettyp a0, acc1 +# CHECK-ENCODING: [0x2b,0xd5,0x00,0x08] + +msettyp m1, a0 +# CHECK-INST: msettyp m1, a0 +# CHECK-ENCODING: [0xab,0x50,0x05,0x02] + +asettyp acc1, a0 +# CHECK-INST: asettyp acc1, a0 +# CHECK-ENCODING: [0x2b,0x51,0x05,0x06] + +mbcast.x m1, a0 +# CHECK-INST: mbcast.x m1, a0 +# CHECK-ENCODING: [0xab,0x40,0x05,0x00] + +mshift.ew m1, m2, 5 +# CHECK-INST: mshift.ew m1, m2, 5 +# CHECK-ENCODING: [0xab,0x60,0x51,0x00] + +mshift.ew m1, m2, -3 +# CHECK-INST: mshift.ew m1, m2, -3 +# CHECK-ENCODING: [0xab,0x60,0xd1,0x07] From 66f04a5f54e649d163cb399b76d4af4841f7a653 Mon Sep 17 00:00:00 2001 From: Vismay Suramwar Date: Sun, 19 Jul 2026 15:54:11 +0000 Subject: [PATCH 09/10] [RISCV: Fix] Remove unnecessary changes --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 84 +++++++++---------- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 23 ++++- .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 5 +- llvm/lib/Target/RISCV/RISCVFeatures.td | 2 +- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 35 ++++---- 5 files changed, 79 insertions(+), 70 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 20f0bb25739c9..59868aac6f039 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1279,7 +1279,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { } static std::unique_ptr createRegList(unsigned RlistEncode, - SMLoc S) { + SMLoc S) { auto Op = std::make_unique(KindTy::RegList); Op->RegList.Encoding = RlistEncode; Op->StartLoc = S; @@ -1296,8 +1296,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { return Op; } - static std::unique_ptr createStackAdj(unsigned StackAdj, - SMLoc S) { + static std::unique_ptr createStackAdj(unsigned StackAdj, SMLoc S) { auto Op = std::make_unique(KindTy::StackAdj); Op->StackAdj.Val = StackAdj; Op->StartLoc = S; @@ -2274,8 +2273,8 @@ ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) { if (IsNegative) RealVal.changeSign(); - Operands.push_back( - RISCVOperand::createFPImm(RealVal.bitcastToAPInt().getZExtValue(), S)); + Operands.push_back(RISCVOperand::createFPImm( + RealVal.bitcastToAPInt().getZExtValue(), S)); Lex(); // Eat the token. @@ -2824,8 +2823,8 @@ ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(OperandVector &Operands) { return ParseStatus::NoMatch; if ((Reg - RISCV::X0) & 1) { - // Only report the even register error if we have at least Zfinx so we - // know some FP is enabled. We already checked F earlier. + // Only report the even register error if we have at least Zfinx so we know + // some FP is enabled. We already checked F earlier. if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx)) return TokError("double precision floating point operands must use even " "numbered X register"); @@ -2854,8 +2853,8 @@ ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands, // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on // RV64 as it will prevent matching the RV64 version of the same instruction // that doesn't use a GPRPair. - // If this is an RV64 GPRPair instruction, there is no RV32 version so we - // can still parse as a pair. + // If this is an RV64 GPRPair instruction, there is no RV32 version so we can + // still parse as a pair. if (!IsRV64Inst && isRV64()) return ParseStatus::NoMatch; @@ -3000,24 +2999,24 @@ ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { } ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { - // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory - // operand" as one of their register operands, such as `(a0)`. This just - // denotes that the register (in this case `a0`) contains a memory address. + // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" + // as one of their register operands, such as `(a0)`. This just denotes that + // the register (in this case `a0`) contains a memory address. // // Normally, we would be able to parse these by putting the parens into the // instruction string. However, GNU as also accepts a zero-offset memory - // operand (such as `0(a0)`), and ignores the 0. Normally this would be - // parsed with parseExpression followed by parseMemOpBaseReg, but these - // instructions do not accept an immediate operand, and we do not want to - // add a "dummy" operand that is silently dropped. + // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed + // with parseExpression followed by parseMemOpBaseReg, but these instructions + // do not accept an immediate operand, and we do not want to add a "dummy" + // operand that is silently dropped. // // Instead, we use this custom parser. This will: allow (and discard) an // offset if it is zero; require (and discard) parentheses; and add only the // parsed register operand to `Operands`. // // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp, - // which will only print the register surrounded by parentheses (which GNU - // as also uses as its canonical representation for these operands). + // which will only print the register surrounded by parentheses (which GNU as + // also uses as its canonical representation for these operands). std::unique_ptr OptionalImmOp; if (getLexer().isNot(AsmToken::LParen)) { @@ -3049,8 +3048,7 @@ ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { if (parseToken(AsmToken::RParen, "expected ')'")) return ParseStatus::Failure; - // Deferred Handling of non-zero offsets. This makes the error messages - // nicer. + // Deferred Handling of non-zero offsets. This makes the error messages nicer. if (OptionalImmOp && !OptionalImmOp->isImmZero()) return Error( OptionalImmOp->getStartLoc(), "optional integer offset must be 0", @@ -3231,13 +3229,13 @@ ParseStatus RISCVAsmParser::parseZcmpStackAdj(OperandVector &Operands, } /// Looks at a token type and creates the relevant operand from this -/// information, adding to Operands. If operand was parsed, returns false, -/// else true. +/// information, adding to Operands. If operand was parsed, returns false, else +/// true. bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { - // Check if the current operand has a custom associated parser, if so, try - // to custom parse the operand, or fallback to the general approach. - ParseStatus Result = MatchOperandParserImpl(Operands, Mnemonic, - /*ParseForAllFeatures=*/true); + // Check if the current operand has a custom associated parser, if so, try to + // custom parse the operand, or fallback to the general approach. + ParseStatus Result = + MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); if (Result.isSuccess()) return false; if (Result.isFailure()) @@ -3264,8 +3262,8 @@ bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { // Apply mnemonic aliases because the destination mnemonic may have require - // custom operand parsing. The generic tblgen'erated code does this later, - // at the start of MatchInstructionImpl(), but that's too late for custom + // custom operand parsing. The generic tblgen'erated code does this later, at + // the start of MatchInstructionImpl(), but that's too late for custom // operand parsing. const FeatureBitset &AvailableFeatures = getAvailableFeatures(); applyMnemonicAliases(Name, AvailableFeatures, 0); @@ -3471,10 +3469,9 @@ bool RISCVAsmParser::parseDirectiveOption() { std::string Buffer; raw_string_ostream OutputErrMsg(Buffer); - handleAllErrors(ParseResult.takeError(), - [&](llvm::StringError &ErrMsg) { - OutputErrMsg << ErrMsg.getMessage(); - }); + handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { + OutputErrMsg << ErrMsg.getMessage(); + }); return Error(Loc, OutputErrMsg.str()); } @@ -3719,13 +3716,13 @@ bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { } // We only derive a length from the encoding for 16- and 32-bit - // instructions, as the encodings for longer instructions are not frozen - // in the spec. + // instructions, as the encodings for longer instructions are not frozen in + // the spec. int64_t EncodingDerivedLength = ((Value & 0b11) == 0b11) ? 4 : 2; if (Length) { - // Only check the length against the encoding if the length is present - // and could match + // Only check the length against the encoding if the length is present and + // could match if ((*Length <= 4) && (*Length != EncodingDerivedLength)) return Error(ErrorLoc, "instruction length does not match the encoding"); @@ -4433,8 +4430,8 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst, } if (MCID.TSFlags & RISCVII::SMTConstraintMask) { - // smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must - // not overlap with any of vd, vs1, or vs2. + // smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must not + // overlap with any of vd, vs1, or vs2. int VMaskIdx = RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vmask); MCRegister MaskReg = Inst.getOperand(VMaskIdx).getReg(); @@ -4561,8 +4558,7 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); return false; case RISCV::PseudoLD_RV32: - emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, - /*HasTmpReg=*/false); + emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out, /*HasTmpReg=*/false); return false; case RISCV::PseudoFLH: emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); @@ -4665,8 +4661,8 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, return false; case RISCV::PseudoVMSGE_VI: case RISCV::PseudoVMSLT_VI: { - // These instructions are signed and so is immediate so we can subtract - // one and change the opcode. + // These instructions are signed and so is immediate so we can subtract one + // and change the opcode. int64_t Imm = Inst.getOperand(2).getImm(); unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI : RISCV::VMSLE_VI; @@ -4682,8 +4678,8 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, case RISCV::PseudoVMSLTU_VI: { int64_t Imm = Inst.getOperand(2).getImm(); // Unsigned comparisons are tricky because the immediate is signed. If the - // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is - // always false, but vmsle.vi v0, v1, -1 is always true. Instead we use + // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always + // false, but vmsle.vi v0, v1, -1 is always true. Instead we use // vmsne v0, v1, v1 which is always false. if (Imm == 0) { unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index f9655934826ec..61f7c8a138aef 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -304,9 +304,13 @@ static inline bool isTiedPseudo(uint64_t TSFlags) { return TSFlags & IsTiedPseudoMask; } /// \returns true if there is a SEW operand for the instruction. -static inline bool hasSEWOp(uint64_t TSFlags) { return TSFlags & HasSEWOpMask; } +static inline bool hasSEWOp(uint64_t TSFlags) { + return TSFlags & HasSEWOpMask; +} /// \returns true if there is a VL operand for the instruction. -static inline bool hasVLOp(uint64_t TSFlags) { return TSFlags & HasVLOpMask; } +static inline bool hasVLOp(uint64_t TSFlags) { + return TSFlags & HasVLOpMask; +} /// \returns true if there is a vector policy operand for this instruction. static inline bool hasVecPolicyOp(uint64_t TSFlags) { return TSFlags & HasVecPolicyOpMask; @@ -492,7 +496,12 @@ enum { // Describes the predecessor/successor bits used in the FENCE instruction. namespace RISCVFenceField { -enum FenceField { I = 8, O = 4, R = 2, W = 1 }; +enum FenceField { + I = 8, + O = 4, + R = 2, + W = 1 +}; } // Describes the supported floating point rounding mode encodings. @@ -591,7 +600,13 @@ inline static bool isValidSMTVTypeMode(unsigned Mode) { } // namespace XSMTVTypeMode namespace RISCVVXRndMode { -enum RoundingMode { RNU = 0, RNE = 1, RDN = 2, ROD = 3, Invalid }; +enum RoundingMode { + RNU = 0, + RNE = 1, + RDN = 2, + ROD = 3, + Invalid +}; inline static StringRef roundingModeToString(RoundingMode RndMode) { switch (RndMode) { diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp index 56dc59e152630..56f729673c699 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -149,7 +149,7 @@ void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { unsigned FenceArg = MI->getOperand(OpNo).getImm(); - assert(((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); + assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); if ((FenceArg & RISCVFenceField::I) != 0) O << 'i'; @@ -260,8 +260,7 @@ void RISCVInstPrinter::printXSfmmVType(const MCInst *MI, unsigned OpNo, // than ABI register names, we need to print "{x1, x8-x9, x18-x27}" for all // registers. Otherwise, we print "{ra, s0-s11}". void RISCVInstPrinter::printRegList(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Imm = MI->getOperand(OpNo).getImm(); assert(Imm >= RISCVZC::RLISTENCODE::RA && diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 01c41c6ec0402..cc62ed9712baf 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -979,7 +979,7 @@ def FeatureStdExtZttAccRegs4 "Enable support for 4 AME accumulator registers">; let Implies = [FeatureStdExtZttMatrixRegs32, FeatureStdExtZttAccRegs4] in { - def FeatureStdExtZtt // By default, enabling "+ztt" implies 32 Matrix Regs and 4 Accumulators. + def FeatureStdExtZtt // By default, enabling "+experimental-ztt" implies 32 Matrix Regs and 4 Accumulators. : RISCVExperimentalExtension<0, 1, "Attached Matrix Extension">; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index b4b67b80a64cb..931fc4ca1bd1a 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -239,7 +239,8 @@ Register RISCVInstrInfo::isStoreToStackSlot(const MachineInstr &MI, return 0; } -bool RISCVInstrInfo::isReMaterializableImpl(const MachineInstr &MI) const { +bool RISCVInstrInfo::isReMaterializableImpl( + const MachineInstr &MI) const { switch (RISCV::getRVVMCOpcode(MI.getOpcode())) { case RISCV::VMV_V_X: case RISCV::VFMV_V_F: @@ -486,11 +487,11 @@ void RISCVInstrInfo::copyPhysRegVector( MIB = MIB.addReg(ActualSrcReg, getKillRegState(KillSrc)); if (UseVMV) { const MCInstrDesc &Desc = DefMBBI->getDesc(); - MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL + MIB.add(DefMBBI->getOperand(RISCVII::getVLOpNum(Desc))); // AVL unsigned Log2SEW = DefMBBI->getOperand(RISCVII::getSEWOpNum(Desc)).getImm(); - MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW - MIB.addImm(0); // tu, mu + MIB.addImm(Log2SEW ? Log2SEW : 3); // SEW + MIB.addImm(0); // tu, mu MIB.addReg(RISCV::VL, RegState::Implicit); MIB.addReg(RISCV::VTYPE, RegState::Implicit); } @@ -3120,8 +3121,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, Ok = Ok && Imm != 0; break; case RISCVOp::OPERAND_CLUI_IMM: - Ok = (isUInt<5>(Imm) && Imm != 0) || - (Imm >= 0xfffe0 && Imm <= 0xfffff); + Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff); break; case RISCVOp::OPERAND_RVKRNUM: Ok = Imm >= 0 && Imm <= 10; @@ -3163,8 +3163,8 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, Ok = isValidAtomicOrdering(Imm); break; case RISCVOp::OPERAND_VEC_POLICY: - Ok = (Imm & - (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == Imm; + Ok = (Imm & (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == + Imm; break; case RISCVOp::OPERAND_SEW: Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm)); @@ -3289,13 +3289,12 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, const uint64_t TSFlags = Desc.TSFlags; if (RISCVII::hasVLOp(TSFlags)) { const MachineOperand &Op = MI.getOperand(RISCVII::getVLOpNum(Desc)); - if (!Op.isImm() && !Op.isReg()) { + if (!Op.isImm() && !Op.isReg()) { ErrInfo = "Invalid operand type for VL operand"; return false; } if (Op.isReg() && Op.getReg().isValid()) { - const MachineRegisterInfo &MRI = - MI.getParent()->getParent()->getRegInfo(); + const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); auto *RC = MRI.getRegClass(Op.getReg()); if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) { ErrInfo = "Invalid register class for VL operand"; @@ -3948,9 +3947,9 @@ void RISCVInstrInfo::buildOutlinedFrame( // Add in a return instruction to the end of the outlined frame. MBB.insert(MBB.end(), BuildMI(MF, DebugLoc(), get(RISCV::JALR)) - .addReg(RISCV::X0, RegState::Define) - .addReg(RISCV::X5) - .addImm(0)); + .addReg(RISCV::X0, RegState::Define) + .addReg(RISCV::X5) + .addImm(0)); } MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall( @@ -4520,8 +4519,8 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI, assert((OpIdx1 == 3 || OpIdx2 == 3) && "Unexpected opcode index"); unsigned Opc; switch (MI.getOpcode()) { - default: - llvm_unreachable("Unexpected opcode"); + default: + llvm_unreachable("Unexpected opcode"); CASE_VFMA_CHANGE_OPCODE_SPLATS(FMACC, FMADD) CASE_VFMA_CHANGE_OPCODE_SPLATS(FMADD, FMACC) CASE_VFMA_CHANGE_OPCODE_SPLATS(FMSAC, FMSUB) @@ -4559,8 +4558,8 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI, if (OpIdx1 == 3 || OpIdx2 == 3) { unsigned Opc; switch (MI.getOpcode()) { - default: - llvm_unreachable("Unexpected opcode"); + default: + llvm_unreachable("Unexpected opcode"); CASE_VFMA_CHANGE_OPCODE_VV(FMADD, FMACC) CASE_VFMA_CHANGE_OPCODE_VV(FMSUB, FMSAC) CASE_VFMA_CHANGE_OPCODE_VV(FNMADD, FNMACC) From 1cba266f7afd747c4908215d38fd780a08223dbb Mon Sep 17 00:00:00 2001 From: vismaysur Date: Sun, 19 Jul 2026 21:15:25 +0000 Subject: [PATCH 10/10] [RISCV: Feat] Added tests for subtarget misconfigs --- llvm/include/llvm/IR/IntrinsicsRISCV.td | 2 +- ...VAMEExt.td => IntrinsicsRISCVStdExtZtt.td} | 252 +++--- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 21 +- llvm/lib/Target/RISCV/RISCVFeatures.td | 10 +- llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td | 410 ++++----- llvm/test/CodeGen/RISCV/ztt-intrinsics.ll | 791 +++++++++++++----- llvm/test/MC/RISCV/ztt-invalid.s | 38 +- 7 files changed, 969 insertions(+), 555 deletions(-) rename llvm/include/llvm/IR/{IntrinsicsRISCVAMEExt.td => IntrinsicsRISCVStdExtZtt.td} (71%) diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 774cc58e7ac92..80a73671b4c99 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2141,6 +2141,6 @@ include "llvm/IR/IntrinsicsRISCVXCV.td" include "llvm/IR/IntrinsicsRISCVXAndes.td" include "llvm/IR/IntrinsicsRISCVXMIPS.td" include "llvm/IR/IntrinsicsRISCVExt.td" -include "llvm/IR/IntrinsicsRISCVAMEExt.td" +include "llvm/IR/IntrinsicsRISCVStdExtZtt.td" include "llvm/IR/IntrinsicsRISCVBOSCExt.td" include "llvm/IR/IntrinsicsRISCVBuckyballExt.td" diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td b/llvm/include/llvm/IR/IntrinsicsRISCVStdExtZtt.td similarity index 71% rename from llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td rename to llvm/include/llvm/IR/IntrinsicsRISCVStdExtZtt.td index 09f1394cbab5b..3484f552dbb50 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCVAMEExt.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCVStdExtZtt.td @@ -1,4 +1,4 @@ -//===- IntrinsicsRISCVAMEExt.td ------------------------------------------===// +//===- IntrinsicsRISCVZTTExt.td ------------------------------------------===// // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines the intrinsics for the AME (RISC-V Matrix Extension) +// This file defines the intrinsics for Ztt (RISC-V AME Matrix Extension) // extension. // //===----------------------------------------------------------------------===// @@ -25,29 +25,29 @@ // Base class for "get datatype" instrinsics: reads the dtype of an M/Acc // register into a GPR value. // Signature: i32 (dtype_reg_index: i32) -class AME_DataType_Get_Intr +class ZTT_DataType_Get_Intr : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>]>; // Base class for "set datatype" instrinsics: writes a GPR value into the dtype // of an M/Acc register and zeroes that M/Acc register's contents. // Signature: void (dtype_reg_index: i32, dtype_value: i32) -class AME_DataType_Set_Intr +class ZTT_DataType_Set_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>]>; let TargetPrefix = "riscv" in { // agettyp - get the dtype of an Acc register - def int_riscv_ame_agettyp : AME_DataType_Get_Intr; + def int_riscv_ztt_agettyp : ZTT_DataType_Get_Intr; // asettyp - set the dtype of an Acc register; zeroes the Acc register - def int_riscv_ame_asettyp : AME_DataType_Set_Intr; + def int_riscv_ztt_asettyp : ZTT_DataType_Set_Intr; // mgettyp - get the dtype of a M (matrix) register - def int_riscv_ame_mgettyp : AME_DataType_Get_Intr; + def int_riscv_ztt_mgettyp : ZTT_DataType_Get_Intr; // sgettyp - set the dtype of a M (matrix) register; zeroes the M register - def int_riscv_ame_msettyp : AME_DataType_Set_Intr; + def int_riscv_ztt_msettyp : ZTT_DataType_Set_Intr; } //===----------------------------------------------------------------------===// @@ -55,7 +55,7 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for matrix-matrix elementwise arithmetic intrinsics // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) -class AME_Elementwise_Arithmetic_Intr +class ZTT_Elementwise_Arithmetic_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> @@ -63,94 +63,94 @@ class AME_Elementwise_Arithmetic_Intr // Base class for matrix-scalar elementwise arithmetic intrinsics // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) -class AME_Elementwise_Arithmetic_Scalar_Intr +class ZTT_Elementwise_Arithmetic_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mabs.ew - md[i] = |ms1[i]| // Signature: void (md_reg_index: i32, ms1_reg_index: i32) - def int_riscv_ame_mabs_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + def int_riscv_ztt_mabs_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg> ]>; // mabsdiff.ew - md[i] = |ms1[i] - ms2[i]| - def int_riscv_ame_mabsdiff_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mabsdiff_ew : ZTT_Elementwise_Arithmetic_Intr; // mabsdiff.ew.x - md[i] = |scalar - ms2[i]| - def int_riscv_ame_mabsdiff_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mabsdiff_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // madd.ew - md[i] = ms1[i] + ms2[i] - def int_riscv_ame_madd_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_madd_ew : ZTT_Elementwise_Arithmetic_Intr; // madd.ew.x - md[i] = scalar + ms2[i] - def int_riscv_ame_madd_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_madd_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // msub.ew - md[i] = ms2[i] - ms1[i] - def int_riscv_ame_msub_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_msub_ew : ZTT_Elementwise_Arithmetic_Intr; // msub.ew.x - md[i] = scalar - ms2[i] - def int_riscv_ame_msub_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_msub_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mhdiff.ew - md[i] = (ms2[i] - ms1[i]) * 0.5 - def int_riscv_ame_mhdiff_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mhdiff_ew : ZTT_Elementwise_Arithmetic_Intr; // mhdiff.ew.x - md[i] = (scalar - ms2[i]) * 0.5 - def int_riscv_ame_mhdiff_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mhdiff_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmax.ew - md[i] = max(ms1[i], ms2[i]) - def int_riscv_ame_mmax_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmax_ew : ZTT_Elementwise_Arithmetic_Intr; // mmax.ew.x - md[i] = max(scalar, ms2[i]) - def int_riscv_ame_mmax_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmax_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmean.ew - md[i] = (ms1[i] + ms2[i]) * 0.5 - def int_riscv_ame_mmean_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmean_ew : ZTT_Elementwise_Arithmetic_Intr; // mmean.ew.x - md[i] = (scalar + ms2[i]) * 0.5 - def int_riscv_ame_mmean_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmean_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmin.ew - md[i] = min(ms1[i], ms2[i]) - def int_riscv_ame_mmin_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmin_ew : ZTT_Elementwise_Arithmetic_Intr; // mmin.ew.x - md[i] = min(scalar, ms2[i]) - def int_riscv_ame_mmin_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmin_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmul.ew - md[i] = ms1[i] * ms2[i] - def int_riscv_ame_mmul_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmul_ew : ZTT_Elementwise_Arithmetic_Intr; // mmul.ew.x - md[i] = scalar * ms2[i] - def int_riscv_ame_mmul_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmul_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmulacc.ew - md[i] = md[i] + ms1[i] * ms2[i] - def int_riscv_ame_mmulacc_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmulacc_ew : ZTT_Elementwise_Arithmetic_Intr; // mmulacc.ew.x - md[i] = md[i] + scalar * ms2[i] - def int_riscv_ame_mmulacc_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmulacc_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmulaccneg.ew - md[i] = md[i] - ms1[i] * ms2[i] - def int_riscv_ame_mmulaccneg_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmulaccneg_ew : ZTT_Elementwise_Arithmetic_Intr; // mmulaccneg.ew.x - md[i] = md[i] - scalar * ms2[i] - def int_riscv_ame_mmulaccneg_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmulaccneg_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmuladd.ew - md[i] = ms1[i] + ms2[i] * md[i] - def int_riscv_ame_mmuladd_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmuladd_ew : ZTT_Elementwise_Arithmetic_Intr; // mmuladd.ew.x - md[i] = scalar + ms2[i] * md[i] - def int_riscv_ame_mmuladd_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmuladd_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmulneg.ew - md[i] = -(ms1[i] * ms2[i]) - def int_riscv_ame_mmulneg_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmulneg_ew : ZTT_Elementwise_Arithmetic_Intr; // mmulneg.ew.x - md[i] = -(scalar * ms2[i]) - def int_riscv_ame_mmulneg_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmulneg_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; // mmulsub.ew - md[i] = ms1[i] - ms2[i] * md[i] - def int_riscv_ame_mmulsub_ew : AME_Elementwise_Arithmetic_Intr; + def int_riscv_ztt_mmulsub_ew : ZTT_Elementwise_Arithmetic_Intr; // mmulsub.ew.x - md[i] = scalar - ms2[i] * md[i] - def int_riscv_ame_mmulsub_ew_x : AME_Elementwise_Arithmetic_Scalar_Intr; + def int_riscv_ztt_mmulsub_ew_x : ZTT_Elementwise_Arithmetic_Scalar_Intr; } //===----------------------------------------------------------------------===// @@ -158,7 +158,7 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for matrix-matrix bitwise ops. // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) -class AME_Bitwise_Intr +class ZTT_Bitwise_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> @@ -166,40 +166,40 @@ class AME_Bitwise_Intr // Base class for matrix-scalar bitwise ops. // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) -class AME_Bitwise_Scalar_Intr +class ZTT_Bitwise_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mand.ew - md[i] = ms1[i] & ms2[i] - def int_riscv_ame_mand_ew : AME_Bitwise_Intr; + def int_riscv_ztt_mand_ew : ZTT_Bitwise_Intr; // mand.ew.x - md[i] = scalar & ms2[i] - def int_riscv_ame_mand_ew_x : AME_Bitwise_Scalar_Intr; + def int_riscv_ztt_mand_ew_x : ZTT_Bitwise_Scalar_Intr; // mandnot.ew - md[i] = ms1[i] & ~ms2[i] - def int_riscv_ame_mandnot_ew : AME_Bitwise_Intr; + def int_riscv_ztt_mandnot_ew : ZTT_Bitwise_Intr; // mandnot.ew.x - md[i] = scalar & ~ms2[i] - def int_riscv_ame_mandnot_ew_x : AME_Bitwise_Scalar_Intr; + def int_riscv_ztt_mandnot_ew_x : ZTT_Bitwise_Scalar_Intr; // mor.ew - md[i] = ms1[i] | ms2[i] - def int_riscv_ame_mor_ew : AME_Bitwise_Intr; + def int_riscv_ztt_mor_ew : ZTT_Bitwise_Intr; // mor.ew.x - md[i] = scalar | ms2[i] - def int_riscv_ame_mor_ew_x : AME_Bitwise_Scalar_Intr; + def int_riscv_ztt_mor_ew_x : ZTT_Bitwise_Scalar_Intr; // mornot.ew - md[i] = ms1[i] | ~ms2[i] - def int_riscv_ame_mornot_ew : AME_Bitwise_Intr; + def int_riscv_ztt_mornot_ew : ZTT_Bitwise_Intr; // mornot.ew.x - md[i] = scalar | ~ms2[i] - def int_riscv_ame_mornot_ew_x : AME_Bitwise_Scalar_Intr; + def int_riscv_ztt_mornot_ew_x : ZTT_Bitwise_Scalar_Intr; // mxor.ew - md[i] = ms1[i] ^ ms2[i] - def int_riscv_ame_mxor_ew : AME_Bitwise_Intr; + def int_riscv_ztt_mxor_ew : ZTT_Bitwise_Intr; // mxor.ew.x - md[i] = scalar ^ ms2[i] - def int_riscv_ame_mxor_ew_x : AME_Bitwise_Scalar_Intr; + def int_riscv_ztt_mxor_ew_x : ZTT_Bitwise_Scalar_Intr; } //===----------------------------------------------------------------------===// @@ -208,7 +208,7 @@ let TargetPrefix = "riscv" in { let TargetPrefix = "riscv" in { // mbcast.x - broadcast a GPR value to every element of a matrix register // (md). Signature: void (md_reg_index: i32, scalar: i32) - def int_riscv_ame_mbcast_x + def int_riscv_ztt_mbcast_x : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>]>; } @@ -219,7 +219,7 @@ let TargetPrefix = "riscv" in { // Base class for matrix-matrix compare/predicate ops. // Signature: void (md_reg_index: i32, pred_or_src0_reg_index: i32, // src1_reg_index: i32) -class AME_Comp_Pred_Intr +class ZTT_Comp_Pred_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> @@ -227,34 +227,34 @@ class AME_Comp_Pred_Intr // Base class for matrix-scalar compare ops. // Signature: void (md_reg_index: i32, scalar: i32, src1_reg_index: i32) -class AME_Comp_Pred_Scalar_Intr +class ZTT_Comp_Pred_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mcmovge.ew - md[i] = src1[i] if pred[i] >= 0, else md[i] unchanged. - def int_riscv_ame_mcmovge_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_mcmovge_ew : ZTT_Comp_Pred_Intr; // mcmovlt.ew - md[i] = src1[i] if pred[i] < 0, else md[i] unchanged. - def int_riscv_ame_mcmovlt_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_mcmovlt_ew : ZTT_Comp_Pred_Intr; // mcmpge.ew - md[i] = (src0[i] >= src1[i]) ? -1 : 0. - def int_riscv_ame_mcmpge_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_mcmpge_ew : ZTT_Comp_Pred_Intr; // mcmpge.ew.x - md[i] = (scalar >= src1[i]) ? -1 : 0. - def int_riscv_ame_mcmpge_ew_x : AME_Comp_Pred_Scalar_Intr; + def int_riscv_ztt_mcmpge_ew_x : ZTT_Comp_Pred_Scalar_Intr; // mcmplt.ew - md[i] = (src0[i] < src1[i]) ? -1 : 0. - def int_riscv_ame_mcmplt_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_mcmplt_ew : ZTT_Comp_Pred_Intr; // mcmplt.ew.x - md[i] = (scalar < src1[i]) ? -1 : 0. - def int_riscv_ame_mcmplt_ew_x : AME_Comp_Pred_Scalar_Intr; + def int_riscv_ztt_mcmplt_ew_x : ZTT_Comp_Pred_Scalar_Intr; // mselge.ew - md[i] = src1[i] if pred[i] >= 0, else md[i] = 0 - def int_riscv_ame_mselge_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_mselge_ew : ZTT_Comp_Pred_Intr; // msellt.ew - md[i] = src1[i] if pred[i] < 0, else md[i] = 0 - def int_riscv_ame_msellt_ew : AME_Comp_Pred_Intr; + def int_riscv_ztt_msellt_ew : ZTT_Comp_Pred_Intr; } //===----------------------------------------------------------------------===// @@ -262,7 +262,7 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for 2-operand permutation intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32) -class AME_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ +class ZTT_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, @@ -271,74 +271,74 @@ class AME_Perm2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ // Base class for 3-operand permutation intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) -class AME_Perm3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ +class ZTT_Perm3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; let TargetPrefix = "riscv" in { - // Note: N = sqrt(AME_NELEM) + // Note: N = sqrt(ZTT_NELEM) // mcolunzip.ew - elementwise column un-zip (de-interleave). // Given 0 <= i < N and 0 <= j < N/2 // md[i, j] = ms1[i, 2j] // md[i, j + N/2] = ms1[i, 2j + 1] - def int_riscv_ame_mcolunzip_ew : AME_Perm2_Intr; + def int_riscv_ztt_mcolunzip_ew : ZTT_Perm2_Intr; // mcolzip.ew - elementwise column zip (interleave). // Given 0 <= i < N and 0 <= j < N/2 // md[i, 2j] = ms1[i, j] // md[i, 2j + 1] = ms1[i, j + N/2] - def int_riscv_ame_mcolzip_ew : AME_Perm2_Intr; + def int_riscv_ztt_mcolzip_ew : ZTT_Perm2_Intr; // mgather.ew - elementwise gather // Given 0 <= i < N and 0 <= j < N // md[i, j] = ms1[i, ms2[i, j]] - def int_riscv_ame_mgather_ew : AME_Perm3_Intr; + def int_riscv_ztt_mgather_ew : ZTT_Perm3_Intr; // mrowunzip.ew - row un-zip (de-interleave rows) // Given 0 <= k < N, 0 <= j < N and that ms1 is treated as a conceptual 2N-row // matrix stored across (ms1, ms+1). // md[k, j] = ms1[2k, j] // md+1[k, j] = ms1[2k+1, j] - def int_riscv_ame_mrowunzip_ew : AME_Perm2_Intr; + def int_riscv_ztt_mrowunzip_ew : ZTT_Perm2_Intr; // mrowzip.ew - row zip (interleave rows from 2 inputs) // Given 0 <= k < 2N-1, 0 <= j < N and that md is treated as a conceptual // 2N-row matrix stord across (md, md+1). md[2k, j] = ms1[k, j] md[2k+1, j] = // ms2[k, j] - def int_riscv_ame_mrowzip_ew : AME_Perm3_Intr; + def int_riscv_ztt_mrowzip_ew : ZTT_Perm3_Intr; // mscatadd.col - elementwise column scatter-add // Given i <= 0 < N, 0 <= j < N // md[ms2[i, j], j] += ms1[i, j] - def int_riscv_ame_mscatadd_col : AME_Perm3_Intr; + def int_riscv_ztt_mscatadd_col : ZTT_Perm3_Intr; // mscatadd.row - elementwise scatter-add // Given i <= 0 < N, 0 <= j < N // md[i, ms2[i, j]] += ms1[i, j] - def int_riscv_ame_mscatadd_row : AME_Perm3_Intr; + def int_riscv_ztt_mscatadd_row : ZTT_Perm3_Intr; // mscatmax.col - elementwise column scatter-max // Given i <= 0 < N, 0 <= j < N // md[ms2[i, j], j] = max(md[ms2[i, j], j], ms1[i, j]) - def int_riscv_ame_mscatmax_col : AME_Perm3_Intr; + def int_riscv_ztt_mscatmax_col : ZTT_Perm3_Intr; // mscatmax.row - elementwise scatter-max // Given i <= 0 < N, 0 <= j < N // md[i, ms2[i, j]] = max(md[i, ms2[i, j]], ms1[i, j]) - def int_riscv_ame_mscatmax_row : AME_Perm3_Intr; + def int_riscv_ztt_mscatmax_row : ZTT_Perm3_Intr; // mshift.ew - elementwise row shift by constant offset // Given i <= 0 < N, 0 <= j < N // md[i, j] = md[i, j + imm] if 0 <= j + imm < N else md[i, j] = 0 - def int_riscv_ame_mshift_ew : AME_Perm3_Intr; + def int_riscv_ztt_mshift_ew : ZTT_Perm3_Intr; // mshift.m1 - alias for mshift.ew when imm = -1 - def int_riscv_ame_mshift_m1 : AME_Perm2_Intr; + def int_riscv_ztt_mshift_m1 : ZTT_Perm2_Intr; // mshift.p1 - alias for mshift.ew when imm = 1 - def int_riscv_ame_mshift_p1 : AME_Perm2_Intr; + def int_riscv_ztt_mshift_p1 : ZTT_Perm2_Intr; } //===----------------------------------------------------------------------===// @@ -346,7 +346,7 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for packing / unpacking intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32, scalar: i32) -class AME_PackUnpack_Intr +class ZTT_PackUnpack_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, @@ -360,7 +360,7 @@ let TargetPrefix = "riscv" in { // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid // operands here. - def int_riscv_ame_mconv_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ + def int_riscv_ztt_mconv_ew : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg> ]>; @@ -370,14 +370,14 @@ let TargetPrefix = "riscv" in { // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid // operands here. - def int_riscv_ame_mpack_ew_x : AME_PackUnpack_Intr; + def int_riscv_ztt_mpack_ew_x : ZTT_PackUnpack_Intr; // munpack.ew.x - extracts a square (selected by scalar index) from the ms1 // register (packed) into the unpacked md (matrix) register // NOTE: pseudocode in spec assumes non-packed side is unit-sized (1 // reg/square); unclear if "wide" non-packed dtypes (>1 reg/square) are valid // operands here. - def int_riscv_ame_munpack_ew_x : AME_PackUnpack_Intr; + def int_riscv_ztt_munpack_ew_x : ZTT_PackUnpack_Intr; } //===----------------------------------------------------------------------===// @@ -385,7 +385,7 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for 2-operand elementwise matrix-matrix log2/exp2 intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32) -class AME_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ +class ZTT_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, @@ -394,7 +394,7 @@ class AME_Log2Exp2_2_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [ // Base class for 3-operand elementwise matrix-matrix log2/exp2 intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) -class AME_Log2Exp2_3_Intr +class ZTT_Log2Exp2_3_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> @@ -402,80 +402,80 @@ class AME_Log2Exp2_3_Intr // Base class for elementwise matrix-scalar log2/exp2 intrinsics. // Signature: void (md_reg_index: i32, scalar: i32, ms2_reg_index: i32) -class AME_Log2Exp2_Scalar_Intr +class ZTT_Log2Exp2_Scalar_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mexp2.ew - md[i] = 2^ms1[i] - def int_riscv_ame_mexp2_ew : AME_Log2Exp2_2_Intr; + def int_riscv_ztt_mexp2_ew : ZTT_Log2Exp2_2_Intr; // mldexp.ew - md[i] = ms1[i] * 2^ms1[i] - def int_riscv_ame_mldexp_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_mldexp_ew : ZTT_Log2Exp2_3_Intr; // mldexp.ew.x - md[i] = ms2[i] * 2^scalar - def int_riscv_ame_mldexp_ew_x : AME_Log2Exp2_Scalar_Intr; + def int_riscv_ztt_mldexp_ew_x : ZTT_Log2Exp2_Scalar_Intr; // mldexpacc.ew - md[i] = md[i] + ms1[i] * 2^ms1[i] - def int_riscv_ame_mldexpacc_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_mldexpacc_ew : ZTT_Log2Exp2_3_Intr; // mldexpacc.ew.x - md[i] = md[i] + ms2[i] * 2^scalar - def int_riscv_ame_mldexpacc_ew_x : AME_Log2Exp2_Scalar_Intr; + def int_riscv_ztt_mldexpacc_ew_x : ZTT_Log2Exp2_Scalar_Intr; // mlog2.ew - md[i] = log2(ms1[i]) - def int_riscv_ame_mlog2_ew : AME_Log2Exp2_2_Intr; + def int_riscv_ztt_mlog2_ew : ZTT_Log2Exp2_2_Intr; // mlog2sub.ew - md[i] = log2(|ms1[i]|) - ms2[i] - def int_riscv_ame_mlog2sub_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_mlog2sub_ew : ZTT_Log2Exp2_3_Intr; // mlog2sub.ew.x - md[i] = log2(|ms2[i]|) - scalar - def int_riscv_ame_mlog2sub_ew_x : AME_Log2Exp2_Scalar_Intr; + def int_riscv_ztt_mlog2sub_ew_x : ZTT_Log2Exp2_Scalar_Intr; // mrdexp.ew - md[i] = ms1[i] * 2^(-ms2[i]) - def int_riscv_ame_mrdexp_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_mrdexp_ew : ZTT_Log2Exp2_3_Intr; // mrdexpacc.ew - md[i] = md[i] + ms1[i] * 2^(-ms2[i]) - def int_riscv_ame_mrdexpacc_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_mrdexpacc_ew : ZTT_Log2Exp2_3_Intr; // msublog2.ew - md[i] = ms2[i] - log2(|ms1[i]|) - def int_riscv_ame_msublog2_ew : AME_Log2Exp2_3_Intr; + def int_riscv_ztt_msublog2_ew : ZTT_Log2Exp2_3_Intr; // msublog2.ew.x - md[i] = scalar - log2(|ms2[i]|) - def int_riscv_ame_msublog2_ew_x : AME_Log2Exp2_Scalar_Intr; + def int_riscv_ztt_msublog2_ew_x : ZTT_Log2Exp2_Scalar_Intr; } //===----------------------------------------------------------------------===// // Load/store (memory) intrinsics //===----------------------------------------------------------------------===// -// Base class for square loads: loads AME_NELEM elements from memory at addr +// Base class for square loads: loads ZTT_NELEM elements from memory at addr // into the matrix register group (md). // Signature: void (md_reg_index: i32, addr: i32) -class AME_Load_Intr +class ZTT_Load_Intr : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty], [IntrReadMem, IntrHasSideEffects, ImmArg>]>; -// Base class for square stores: stores AME_NELEM elements from the matrix +// Base class for square stores: stores ZTT_NELEM elements from the matrix // register group (md) into memory at addr. // Signature: void (md_reg_index: i32, addr: i32) -class AME_Store_Intr +class ZTT_Store_Intr : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty], [IntrWriteMem, IntrHasSideEffects, ImmArg>]>; let TargetPrefix = "riscv" in { // mls - load using the implementation-defined layout (must match a pripr mss // to memory). - def int_riscv_ame_mls : AME_Load_Intr; + def int_riscv_ztt_mls : ZTT_Load_Intr; // mls.cm / mls.rm - load with an explicit column-major / row-major layout. - def int_riscv_ame_mls_cm : AME_Load_Intr; - def int_riscv_ame_mls_rm : AME_Load_Intr; + def int_riscv_ztt_mls_cm : ZTT_Load_Intr; + def int_riscv_ztt_mls_rm : ZTT_Load_Intr; // mss - store using the implementation-defined layout. - def int_riscv_ame_mss : AME_Store_Intr; + def int_riscv_ztt_mss : ZTT_Store_Intr; // mss.cm / mss.rm - store with an explicit column-major / row-major layout. - def int_riscv_ame_mss_cm : AME_Store_Intr; - def int_riscv_ame_mss_rm : AME_Store_Intr; + def int_riscv_ztt_mss_cm : ZTT_Store_Intr; + def int_riscv_ztt_mss_rm : ZTT_Store_Intr; } //===----------------------------------------------------------------------===// @@ -483,22 +483,22 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for register-to-register move intrinsics: both operands are M/Acc // registers Signature: void (dest_reg_index: i32, src_reg_index: i32) -class AME_Move_Intr +class ZTT_Move_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mmov.a.m - copy an Acc register to an M register group; dtypes must // match, else amestatus.UN is set and dest is left untouched - def int_riscv_ame_mmov_a_m : AME_Move_Intr; + def int_riscv_ztt_mmov_a_m : ZTT_Move_Intr; // mmov.m.m - copy one M register to another; dtypes must // match, else amestatus.UN is set and dest is left untouched - def int_riscv_ame_mmov_m_m : AME_Move_Intr; + def int_riscv_ztt_mmov_m_m : ZTT_Move_Intr; // mzero.2d - zero every element of an Acc register. // Signature: void (acc_reg_index: i32) - def int_riscv_ame_mzero_2d + def int_riscv_ztt_mzero_2d : Intrinsic<[], [llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>]>; } @@ -507,35 +507,35 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for matrix multiply intrinsics // Signature: void (acc_reg_index: i32, ms1_reg_index: i32, ms2_reg_index: i32) -class AME_MatMul_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ +class ZTT_MatMul_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [ IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>, ImmArg> ]>; let TargetPrefix = "riscv" in { // mmul.2d - acc[i, j] = sum over k of (ms1[i, k] * ms2[k, j] - def int_riscv_ame_mmul_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmul_2d : ZTT_MatMul_Intr; // mmulneg.2d - acc[i, j] = -(sum over k of (ms1[i, k] * ms2[k, j]) - def int_riscv_ame_mmulneg_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulneg_2d : ZTT_MatMul_Intr; // mmulacc.2d - acc[i, j] += sum over k of (ms1[i, k] * ms2[k, j] - def int_riscv_ame_mmulacc_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulacc_2d : ZTT_MatMul_Intr; // mmulaccneg.2d - acc[i, j] -= sum over k of (ms1[i, k] * ms2[k, j] - def int_riscv_ame_mmulaccneg_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulaccneg_2d : ZTT_MatMul_Intr; // mmulat.2d - acc[i, j] = sum over k of (ms1[k, i] * ms2[k, j] - def int_riscv_ame_mmulat_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulat_2d : ZTT_MatMul_Intr; // mmulatacc.2d - acc[i, j] += sum over k of (ms1[k, i] * ms2[k, j] - def int_riscv_ame_mmulatacc_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulatacc_2d : ZTT_MatMul_Intr; // mmulbt.2d - acc[i, j] = sum over k of (ms1[i, k] * ms2[j, k] - def int_riscv_ame_mmulbt_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulbt_2d : ZTT_MatMul_Intr; // mmulbtacc.2d - acc[i, j] += sum over k of (ms1[i, k] * ms2[j, k] - def int_riscv_ame_mmulbtacc_2d : AME_MatMul_Intr; + def int_riscv_ztt_mmulbtacc_2d : ZTT_MatMul_Intr; } //===----------------------------------------------------------------------===// @@ -543,32 +543,32 @@ let TargetPrefix = "riscv" in { //===----------------------------------------------------------------------===// // Base class for reduction intrinsics. // Signature: void (md_reg_index: i32, ms1_reg_index: i32) -class AME_Reduction_Intr +class ZTT_Reduction_Intr : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], [IntrHasSideEffects, IntrNoMem, ImmArg>, ImmArg>]>; let TargetPrefix = "riscv" in { // mprefixadd.col - md[i, j] = sum over k <= i of ms1[k, j] - def int_riscv_ame_mprefixadd_col : AME_Reduction_Intr; + def int_riscv_ztt_mprefixadd_col : ZTT_Reduction_Intr; // mprefixadd.row - md[i, j] = sum over k <= j of ms1[i, k] - def int_riscv_ame_mprefixadd_row : AME_Reduction_Intr; + def int_riscv_ztt_mprefixadd_row : ZTT_Reduction_Intr; // mprefixmax.col - md[i, j] = max over k <= i of ms1[k, j] - def int_riscv_ame_mprefixmax_col : AME_Reduction_Intr; + def int_riscv_ztt_mprefixmax_col : ZTT_Reduction_Intr; // mprefixmax.row - md[i, j] = max over k <= j of ms1[i, k] - def int_riscv_ame_mprefixmax_row : AME_Reduction_Intr; + def int_riscv_ztt_mprefixmax_row : ZTT_Reduction_Intr; // mreduceadd.col - md[i, j] = sum over k of ms1[k, j] - def int_riscv_ame_mreduceadd_col : AME_Reduction_Intr; + def int_riscv_ztt_mreduceadd_col : ZTT_Reduction_Intr; // mreduceadd.row - md[i, j] = sum over k of ms1[i, k] - def int_riscv_ame_mreduceadd_row : AME_Reduction_Intr; + def int_riscv_ztt_mreduceadd_row : ZTT_Reduction_Intr; // mreducemax.col - md[i, j] = max over k of ms1[k, j] - def int_riscv_ame_mreducemax_col : AME_Reduction_Intr; + def int_riscv_ztt_mreducemax_col : ZTT_Reduction_Intr; // mreducemax.row - md[i, j] = max over k of ms1[i, k] - def int_riscv_ame_mreducemax_row : AME_Reduction_Intr; + def int_riscv_ztt_mreducemax_row : ZTT_Reduction_Intr; } diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 59868aac6f039..8f8a8ae9efd82 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1057,6 +1057,8 @@ struct RISCVOperand final : public MCParsedAsmOperand { [](int64_t Imm) { return Imm != INT64_MIN && isInt<5>(Imm - 1); }); } + bool isSImm7() const { return isSImm<7>(); } + bool isSImm18() const { return isSImmPred([](int64_t Imm) { return isInt<18>(Imm); }); } @@ -2686,9 +2688,16 @@ ParseStatus RISCVAsmParser::parseZttMatrixRegIndex(OperandVector &Operands) { unsigned MaxIndex; const auto &Features = STI->getFeatureBits(); - if (Features[RISCV::FeatureStdExtZttMatrixRegs32]) + + bool HasZttMatrixRegs32 = Features[RISCV::FeatureStdExtZttMatrixRegs32]; + bool HasZttMatrixRegs16 = Features[RISCV::FeatureStdExtZttMatrixRegs16]; + if (HasZttMatrixRegs16 && HasZttMatrixRegs32) + return Error(getLoc(), + "conflicting ztt (AME) matrix register bounds chosen; cannot enable both 16 and 32 matrix registers simultaneously"); + + if (HasZttMatrixRegs32) MaxIndex = 31; - else if (Features[RISCV::FeatureStdExtZttMatrixRegs16]) + else if (HasZttMatrixRegs16) MaxIndex = 15; else return Error(getLoc(), @@ -2719,6 +2728,14 @@ ParseStatus RISCVAsmParser::parseZttAccRegIndex(OperandVector &Operands) { unsigned MaxIndex; const auto &Features = STI->getFeatureBits(); + + bool HasZttAccRegs4 = Features[RISCV::FeatureStdExtZttAccRegs4]; + bool HasZttAccRegs2 = Features[RISCV::FeatureStdExtZttAccRegs2]; + bool HasZttAccRegs1 = Features[RISCV::FeatureStdExtZttAccRegs1]; + if ((HasZttAccRegs4 + HasZttAccRegs2 + HasZttAccRegs1) > 1) + return Error(getLoc(), + "conflicting ztt (AME) accumulator register bounds chosen; cannot enable multiple accumulator register configurations simultaneously"); + if (Features[RISCV::FeatureStdExtZttAccRegs4]) MaxIndex = 3; else if (Features[RISCV::FeatureStdExtZttAccRegs2]) diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index cc62ed9712baf..73b4de09e253f 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -959,23 +959,23 @@ def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">, // Attached Matrix Extension def FeatureStdExtZttMatrixRegs16 - : SubtargetFeature<"experimental-ztt-ame-mregs-16", "HasAMEMatrixRegs16", "true", + : SubtargetFeature<"experimental-ztt-ame-mregs-16", "HasZttMatrixRegs16", "true", "Enable support for 16 AME matrix registers">; def FeatureStdExtZttMatrixRegs32 - : SubtargetFeature<"experimental-ztt-ame-mregs-32", "HasAMEMatrixRegs32", "true", + : SubtargetFeature<"experimental-ztt-ame-mregs-32", "HasZttMatrixRegs32", "true", "Enable support for 32 AME matrix registers">; def FeatureStdExtZttAccRegs1 - : SubtargetFeature<"experimental-ztt-ame-accregs-1", "HasAMEAccRegs1", "true", + : SubtargetFeature<"experimental-ztt-ame-accregs-1", "HasZttAccRegs1", "true", "Enable support for AME accumulator register">; def FeatureStdExtZttAccRegs2 - : SubtargetFeature<"experimental-ztt-ame-accregs-2", "HasAMEAccRegs2", "true", + : SubtargetFeature<"experimental-ztt-ame-accregs-2", "HasZttAccRegs2", "true", "Enable support for 2 AME accumulator registers">; def FeatureStdExtZttAccRegs4 - : SubtargetFeature<"experimental-ztt-ame-accregs-4", "HasAMEAccRegs4", "true", + : SubtargetFeature<"experimental-ztt-ame-accregs-4", "HasZttAccRegs4", "true", "Enable support for 4 AME accumulator registers">; let Implies = [FeatureStdExtZttMatrixRegs32, FeatureStdExtZttAccRegs4] in { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td index 64ca419a609c3..925122ef73669 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZtt.td @@ -70,7 +70,7 @@ class RVInstAME32 funct7, dag outs, dag ins, string opcodestr, // Base class for single matrix input, matrix output instructions (op md, ms1). // Input and output are matrix registers -class AME_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> +class ZTT_UNARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 funct7, bits<3> funct3, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { - def AME_MABS_EW : AME_UNARYELEMENTWISE<0b0000000, 0b001, "mabs.ew">; - def AME_MCOLUNZIP_EW : AME_UNARYELEMENTWISE<0b0000100, 0b001, "mcolunzip.ew">; - def AME_MCOLZIP_EW : AME_UNARYELEMENTWISE<0b0000011, 0b001, "mcolzip.ew">; - def AME_MCONV_EW : AME_UNARYELEMENTWISE<0b0000000, 0b101, "mconv.ew">; - def AME_MEXP2_EW : AME_UNARYELEMENTWISE<0b0000001, 0b001, "mexp2.ew">; - def AME_MLOG2_EW : AME_UNARYELEMENTWISE<0b0000010, 0b001, "mlog2.ew">; - def AME_MPREFIXADD_COL : AME_UNARYELEMENTWISE<0b0001100, 0b001, "mprefixadd.col">; - def AME_MPREFIXADD_ROW : AME_UNARYELEMENTWISE<0b0001000, 0b001, "mprefixadd.row">; - def AME_MPREFIXMAX_COL : AME_UNARYELEMENTWISE<0b0001101, 0b001, "mprefixmax.col">; - def AME_MPREFIXMAX_ROW : AME_UNARYELEMENTWISE<0b0001001, 0b001, "mprefixmax.row">; - def AME_MREDUCEADD_COL : AME_UNARYELEMENTWISE<0b0001010, 0b001, "mreduceadd.col">; - def AME_MREDUCEADD_ROW : AME_UNARYELEMENTWISE<0b0000110, 0b001, "mreduceadd.row">; - def AME_MREDUCEMAX_COL : AME_UNARYELEMENTWISE<0b0001011, 0b001, "mreducemax.col">; - def AME_MREDUCEMAX_ROW : AME_UNARYELEMENTWISE<0b0000111, 0b001, "mreducemax.row">; - def AME_MROWUNZIP_EW : AME_UNARYELEMENTWISE<0b0000101, 0b001, "mrowunzip.ew">; + def ZTT_MABS_EW : ZTT_UNARYELEMENTWISE<0b0000000, 0b001, "mabs.ew">; + def ZTT_MCOLUNZIP_EW : ZTT_UNARYELEMENTWISE<0b0000100, 0b001, "mcolunzip.ew">; + def ZTT_MCOLZIP_EW : ZTT_UNARYELEMENTWISE<0b0000011, 0b001, "mcolzip.ew">; + def ZTT_MCONV_EW : ZTT_UNARYELEMENTWISE<0b0000000, 0b101, "mconv.ew">; + def ZTT_MEXP2_EW : ZTT_UNARYELEMENTWISE<0b0000001, 0b001, "mexp2.ew">; + def ZTT_MLOG2_EW : ZTT_UNARYELEMENTWISE<0b0000010, 0b001, "mlog2.ew">; + def ZTT_MPREFIXADD_COL : ZTT_UNARYELEMENTWISE<0b0001100, 0b001, "mprefixadd.col">; + def ZTT_MPREFIXADD_ROW : ZTT_UNARYELEMENTWISE<0b0001000, 0b001, "mprefixadd.row">; + def ZTT_MPREFIXMAX_COL : ZTT_UNARYELEMENTWISE<0b0001101, 0b001, "mprefixmax.col">; + def ZTT_MPREFIXMAX_ROW : ZTT_UNARYELEMENTWISE<0b0001001, 0b001, "mprefixmax.row">; + def ZTT_MREDUCEADD_COL : ZTT_UNARYELEMENTWISE<0b0001010, 0b001, "mreduceadd.col">; + def ZTT_MREDUCEADD_ROW : ZTT_UNARYELEMENTWISE<0b0000110, 0b001, "mreduceadd.row">; + def ZTT_MREDUCEMAX_COL : ZTT_UNARYELEMENTWISE<0b0001011, 0b001, "mreducemax.col">; + def ZTT_MREDUCEMAX_ROW : ZTT_UNARYELEMENTWISE<0b0000111, 0b001, "mreducemax.row">; + def ZTT_MROWUNZIP_EW : ZTT_UNARYELEMENTWISE<0b0000101, 0b001, "mrowunzip.ew">; } // Base class for binary matrix input, matrix output instructions // (op md, ms1, ms2). -class AME_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> +class ZTT_BINARYELEMENTWISE funct7, bits<3> funct3, string opcodestr> : RVInstAME32 funct7, bits<3> funct3, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { - def AME_MABSDIFF_EW : AME_BINARYELEMENTWISE<0b0000100, 0b000, "mabsdiff.ew">; - def AME_MADD_EW : AME_BINARYELEMENTWISE<0b0000000, 0b000, "madd.ew">; - def AME_MAND_EW : AME_BINARYELEMENTWISE<0b0000111, 0b000, "mand.ew">; - def AME_MANDNOT_EW : AME_BINARYELEMENTWISE<0b0001000, 0b000, "mandnot.ew">; - def AME_MCMOVGE_EW : AME_BINARYELEMENTWISE<0b0010000, 0b000, "mcmovge.ew">; - def AME_MCMOVLT_EW : AME_BINARYELEMENTWISE<0b0010001, 0b000, "mcmovlt.ew">; - def AME_MCMPGE_EW : AME_BINARYELEMENTWISE<0b0001100, 0b000, "mcmpge.ew">; - def AME_MCMPLT_EW : AME_BINARYELEMENTWISE<0b0001101, 0b000, "mcmplt.ew">; - def AME_MGATHER_EW : AME_BINARYELEMENTWISE<0b0011000, 0b000, "mgather.ew">; - def AME_MHDIFF_EW : AME_BINARYELEMENTWISE<0b0000011, 0b000, "mhdiff.ew">; - def AME_MLDEXP_EW : AME_BINARYELEMENTWISE<0b0010010, 0b000, "mldexp.ew">; - def AME_MLDEXPACC_EW : AME_BINARYELEMENTWISE<0b0010011, 0b000, "mldexpacc.ew">; - def AME_MLOG2SUB_EW : AME_BINARYELEMENTWISE<0b0010110, 0b000, "mlog2sub.ew">; - def AME_MMAX_EW : AME_BINARYELEMENTWISE<0b0000101, 0b000, "mmax.ew">; - def AME_MMEAN_EW : AME_BINARYELEMENTWISE<0b0000010, 0b000, "mmean.ew">; - def AME_MMIN_EW : AME_BINARYELEMENTWISE<0b0000110, 0b000, "mmin.ew">; - def AME_MMUL_EW : AME_BINARYELEMENTWISE<0b0011100, 0b000, "mmul.ew">; - def AME_MMULACC_EW : AME_BINARYELEMENTWISE<0b0011101, 0b000, "mmulacc.ew">; - def AME_MMULACCNEG_EW : AME_BINARYELEMENTWISE<0b0100000, 0b000, "mmulaccneg.ew">; - def AME_MMULADD_EW : AME_BINARYELEMENTWISE<0b0011110, 0b000, "mmuladd.ew">; - def AME_MMULNEG_EW : AME_BINARYELEMENTWISE<0b0100001, 0b000, "mmulneg.ew">; - def AME_MMULSUB_EW : AME_BINARYELEMENTWISE<0b0011111, 0b000, "mmulsub.ew">; - def AME_MOR_EW : AME_BINARYELEMENTWISE<0b0001001, 0b000, "mor.ew">; - def AME_MORNOT_EW : AME_BINARYELEMENTWISE<0b0001010, 0b000, "mornot.ew">; - def AME_MRDEXP_EW : AME_BINARYELEMENTWISE<0b0010100, 0b000, "mrdexp.ew">; - def AME_MRDEXPACC_EW : AME_BINARYELEMENTWISE<0b0010101, 0b000, "mrdexpacc.ew">; - def AME_MROWZIP_EW : AME_BINARYELEMENTWISE<0b0011011, 0b000, "mrowzip.ew">; - def AME_MSCATADD_COL : AME_BINARYELEMENTWISE<0b0100010, 0b000, "mscatadd.col">; - def AME_MSCATADD_ROW : AME_BINARYELEMENTWISE<0b0011001, 0b000, "mscatadd.row">; - def AME_MSCATMAX_COL : AME_BINARYELEMENTWISE<0b0100011, 0b000, "mscatmax.col">; - def AME_MSCATMAX_ROW : AME_BINARYELEMENTWISE<0b0011010, 0b000, "mscatmax.row">; - def AME_MSELGE_EW : AME_BINARYELEMENTWISE<0b0001110, 0b000, "mselge.ew">; - def AME_MSELLT_EW : AME_BINARYELEMENTWISE<0b0001111, 0b000, "msellt.ew">; - def AME_MSUB_EW : AME_BINARYELEMENTWISE<0b0000001, 0b000, "msub.ew">; - def AME_MSUBLOG2_EW : AME_BINARYELEMENTWISE<0b0010111, 0b000, "msublog2.ew">; - def AME_MXOR_EW : AME_BINARYELEMENTWISE<0b0001011, 0b000, "mxor.ew">; + def ZTT_MABSDIFF_EW : ZTT_BINARYELEMENTWISE<0b0000100, 0b000, "mabsdiff.ew">; + def ZTT_MADD_EW : ZTT_BINARYELEMENTWISE<0b0000000, 0b000, "madd.ew">; + def ZTT_MAND_EW : ZTT_BINARYELEMENTWISE<0b0000111, 0b000, "mand.ew">; + def ZTT_MANDNOT_EW : ZTT_BINARYELEMENTWISE<0b0001000, 0b000, "mandnot.ew">; + def ZTT_MCMOVGE_EW : ZTT_BINARYELEMENTWISE<0b0010000, 0b000, "mcmovge.ew">; + def ZTT_MCMOVLT_EW : ZTT_BINARYELEMENTWISE<0b0010001, 0b000, "mcmovlt.ew">; + def ZTT_MCMPGE_EW : ZTT_BINARYELEMENTWISE<0b0001100, 0b000, "mcmpge.ew">; + def ZTT_MCMPLT_EW : ZTT_BINARYELEMENTWISE<0b0001101, 0b000, "mcmplt.ew">; + def ZTT_MGATHER_EW : ZTT_BINARYELEMENTWISE<0b0011000, 0b000, "mgather.ew">; + def ZTT_MHDIFF_EW : ZTT_BINARYELEMENTWISE<0b0000011, 0b000, "mhdiff.ew">; + def ZTT_MLDEXP_EW : ZTT_BINARYELEMENTWISE<0b0010010, 0b000, "mldexp.ew">; + def ZTT_MLDEXPACC_EW : ZTT_BINARYELEMENTWISE<0b0010011, 0b000, "mldexpacc.ew">; + def ZTT_MLOG2SUB_EW : ZTT_BINARYELEMENTWISE<0b0010110, 0b000, "mlog2sub.ew">; + def ZTT_MMAX_EW : ZTT_BINARYELEMENTWISE<0b0000101, 0b000, "mmax.ew">; + def ZTT_MMEAN_EW : ZTT_BINARYELEMENTWISE<0b0000010, 0b000, "mmean.ew">; + def ZTT_MMIN_EW : ZTT_BINARYELEMENTWISE<0b0000110, 0b000, "mmin.ew">; + def ZTT_MMUL_EW : ZTT_BINARYELEMENTWISE<0b0011100, 0b000, "mmul.ew">; + def ZTT_MMULACC_EW : ZTT_BINARYELEMENTWISE<0b0011101, 0b000, "mmulacc.ew">; + def ZTT_MMULACCNEG_EW : ZTT_BINARYELEMENTWISE<0b0100000, 0b000, "mmulaccneg.ew">; + def ZTT_MMULADD_EW : ZTT_BINARYELEMENTWISE<0b0011110, 0b000, "mmuladd.ew">; + def ZTT_MMULNEG_EW : ZTT_BINARYELEMENTWISE<0b0100001, 0b000, "mmulneg.ew">; + def ZTT_MMULSUB_EW : ZTT_BINARYELEMENTWISE<0b0011111, 0b000, "mmulsub.ew">; + def ZTT_MOR_EW : ZTT_BINARYELEMENTWISE<0b0001001, 0b000, "mor.ew">; + def ZTT_MORNOT_EW : ZTT_BINARYELEMENTWISE<0b0001010, 0b000, "mornot.ew">; + def ZTT_MRDEXP_EW : ZTT_BINARYELEMENTWISE<0b0010100, 0b000, "mrdexp.ew">; + def ZTT_MRDEXPACC_EW : ZTT_BINARYELEMENTWISE<0b0010101, 0b000, "mrdexpacc.ew">; + def ZTT_MROWZIP_EW : ZTT_BINARYELEMENTWISE<0b0011011, 0b000, "mrowzip.ew">; + def ZTT_MSCATADD_COL : ZTT_BINARYELEMENTWISE<0b0100010, 0b000, "mscatadd.col">; + def ZTT_MSCATADD_ROW : ZTT_BINARYELEMENTWISE<0b0011001, 0b000, "mscatadd.row">; + def ZTT_MSCATMAX_COL : ZTT_BINARYELEMENTWISE<0b0100011, 0b000, "mscatmax.col">; + def ZTT_MSCATMAX_ROW : ZTT_BINARYELEMENTWISE<0b0011010, 0b000, "mscatmax.row">; + def ZTT_MSELGE_EW : ZTT_BINARYELEMENTWISE<0b0001110, 0b000, "mselge.ew">; + def ZTT_MSELLT_EW : ZTT_BINARYELEMENTWISE<0b0001111, 0b000, "msellt.ew">; + def ZTT_MSUB_EW : ZTT_BINARYELEMENTWISE<0b0000001, 0b000, "msub.ew">; + def ZTT_MSUBLOG2_EW : ZTT_BINARYELEMENTWISE<0b0010111, 0b000, "msublog2.ew">; + def ZTT_MXOR_EW : ZTT_BINARYELEMENTWISE<0b0001011, 0b000, "mxor.ew">; } // Base class for binary matrix input, matrix output instructions where the // second source is a scalar GPR instead of a matrix register // (op md, xs1, ms2). Scalar type is inferred from Md[ms2]. -class AME_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> +class ZTT_BINARYELEMENTWISE_X funct7, bits<3> funct3, string opcodestr> : RVInstAME32 funct7, bits<3> funct3, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { - def AME_MABSDIFF_EW_X : AME_BINARYELEMENTWISE_X<0b0000101, 0b010, "mabsdiff.ew.x">; - def AME_MADD_EW_X : AME_BINARYELEMENTWISE_X<0b0000000, 0b010, "madd.ew.x">; - def AME_MAND_EW_X : AME_BINARYELEMENTWISE_X<0b0000111, 0b010, "mand.ew.x">; - def AME_MANDNOT_EW_X : AME_BINARYELEMENTWISE_X<0b0001000, 0b010, "mandnot.ew.x">; - def AME_MCMPGE_EW_X : AME_BINARYELEMENTWISE_X<0b0001100, 0b010, "mcmpge.ew.x">; - def AME_MCMPLT_EW_X : AME_BINARYELEMENTWISE_X<0b0001101, 0b010, "mcmplt.ew.x">; - def AME_MHDIFF_EW_X : AME_BINARYELEMENTWISE_X<0b0000110, 0b010, "mhdiff.ew.x">; - def AME_MLDEXP_EW_X : AME_BINARYELEMENTWISE_X<0b0010000, 0b010, "mldexp.ew.x">; - def AME_MLDEXPACC_EW_X : AME_BINARYELEMENTWISE_X<0b0010001, 0b010, "mldexpacc.ew.x">; - def AME_MLOG2SUB_EW_X : AME_BINARYELEMENTWISE_X<0b0001110, 0b010, "mlog2sub.ew.x">; - def AME_MMAX_EW_X : AME_BINARYELEMENTWISE_X<0b0000011, 0b010, "mmax.ew.x">; - def AME_MMEAN_EW_X : AME_BINARYELEMENTWISE_X<0b0000100, 0b010, "mmean.ew.x">; - def AME_MMIN_EW_X : AME_BINARYELEMENTWISE_X<0b0000010, 0b010, "mmin.ew.x">; - def AME_MMUL_EW_X : AME_BINARYELEMENTWISE_X<0b0010010, 0b010, "mmul.ew.x">; - def AME_MMULACC_EW_X : AME_BINARYELEMENTWISE_X<0b0010011, 0b010, "mmulacc.ew.x">; - def AME_MMULACCNEG_EW_X : AME_BINARYELEMENTWISE_X<0b0010110, 0b010, "mmulaccneg.ew.x">; - def AME_MMULADD_EW_X : AME_BINARYELEMENTWISE_X<0b0010100, 0b010, "mmuladd.ew.x">; - def AME_MMULNEG_EW_X : AME_BINARYELEMENTWISE_X<0b0010111, 0b010, "mmulneg.ew.x">; - def AME_MMULSUB_EW_X : AME_BINARYELEMENTWISE_X<0b0010101, 0b010, "mmulsub.ew.x">; - def AME_MOR_EW_X : AME_BINARYELEMENTWISE_X<0b0001001, 0b010, "mor.ew.x">; - def AME_MORNOT_EW_X : AME_BINARYELEMENTWISE_X<0b0001010, 0b010, "mornot.ew.x">; - def AME_MSUB_EW_X : AME_BINARYELEMENTWISE_X<0b0000001, 0b010, "msub.ew.x">; - def AME_MSUBLOG2_EW_X : AME_BINARYELEMENTWISE_X<0b0001111, 0b010, "msublog2.ew.x">; - def AME_MXOR_EW_X : AME_BINARYELEMENTWISE_X<0b0001011, 0b010, "mxor.ew.x">; + def ZTT_MABSDIFF_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000101, 0b010, "mabsdiff.ew.x">; + def ZTT_MADD_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000000, 0b010, "madd.ew.x">; + def ZTT_MAND_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000111, 0b010, "mand.ew.x">; + def ZTT_MANDNOT_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001000, 0b010, "mandnot.ew.x">; + def ZTT_MCMPGE_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001100, 0b010, "mcmpge.ew.x">; + def ZTT_MCMPLT_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001101, 0b010, "mcmplt.ew.x">; + def ZTT_MHDIFF_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000110, 0b010, "mhdiff.ew.x">; + def ZTT_MLDEXP_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010000, 0b010, "mldexp.ew.x">; + def ZTT_MLDEXPACC_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010001, 0b010, "mldexpacc.ew.x">; + def ZTT_MLOG2SUB_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001110, 0b010, "mlog2sub.ew.x">; + def ZTT_MMAX_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000011, 0b010, "mmax.ew.x">; + def ZTT_MMEAN_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000100, 0b010, "mmean.ew.x">; + def ZTT_MMIN_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000010, 0b010, "mmin.ew.x">; + def ZTT_MMUL_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010010, 0b010, "mmul.ew.x">; + def ZTT_MMULACC_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010011, 0b010, "mmulacc.ew.x">; + def ZTT_MMULACCNEG_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010110, 0b010, "mmulaccneg.ew.x">; + def ZTT_MMULADD_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010100, 0b010, "mmuladd.ew.x">; + def ZTT_MMULNEG_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010111, 0b010, "mmulneg.ew.x">; + def ZTT_MMULSUB_EW_X : ZTT_BINARYELEMENTWISE_X<0b0010101, 0b010, "mmulsub.ew.x">; + def ZTT_MOR_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001001, 0b010, "mor.ew.x">; + def ZTT_MORNOT_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001010, 0b010, "mornot.ew.x">; + def ZTT_MSUB_EW_X : ZTT_BINARYELEMENTWISE_X<0b0000001, 0b010, "msub.ew.x">; + def ZTT_MSUBLOG2_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001111, 0b010, "msublog2.ew.x">; + def ZTT_MXOR_EW_X : ZTT_BINARYELEMENTWISE_X<0b0001011, 0b010, "mxor.ew.x">; } // Base class for 2D matrix multiply instructions (op acc, ms1, ms2). // acc is only 2 bits, freeing bits 14-10. -class AME_MATMUL2D funct7, string opcodestr> +class ZTT_MATMUL2D funct7, string opcodestr> : RVInstAME32 funct7, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { - def AME_MMUL_2D : AME_MATMUL2D<0b0000000, "mmul.2d">; - def AME_MMULACC_2D : AME_MATMUL2D<0b0000001, "mmulacc.2d">; - def AME_MMULACCNEG_2D : AME_MATMUL2D<0b0000011, "mmulaccneg.2d">; - def AME_MMULAT_2D : AME_MATMUL2D<0b0000100, "mmulat.2d">; - def AME_MMULATACC_2D : AME_MATMUL2D<0b0000101, "mmulatacc.2d">; - def AME_MMULBT_2D : AME_MATMUL2D<0b0000110, "mmulbt.2d">; - def AME_MMULBTACC_2D : AME_MATMUL2D<0b0000111, "mmulbtacc.2d">; - def AME_MMULNEG_2D : AME_MATMUL2D<0b0000010, "mmulneg.2d">; + def ZTT_MMUL_2D : ZTT_MATMUL2D<0b0000000, "mmul.2d">; + def ZTT_MMULACC_2D : ZTT_MATMUL2D<0b0000001, "mmulacc.2d">; + def ZTT_MMULACCNEG_2D : ZTT_MATMUL2D<0b0000011, "mmulaccneg.2d">; + def ZTT_MMULAT_2D : ZTT_MATMUL2D<0b0000100, "mmulat.2d">; + def ZTT_MMULATACC_2D : ZTT_MATMUL2D<0b0000101, "mmulatacc.2d">; + def ZTT_MMULBT_2D : ZTT_MATMUL2D<0b0000110, "mmulbt.2d">; + def ZTT_MMULBTACC_2D : ZTT_MATMUL2D<0b0000111, "mmulbtacc.2d">; + def ZTT_MMULNEG_2D : ZTT_MATMUL2D<0b0000010, "mmulneg.2d">; } // Base class for the interoperability load instructions (mls, mls.cm, // mls.rm). -class AME_LOAD funct7, string opcodestr> +class ZTT_LOAD funct7, string opcodestr> : RVInstAME32 funct7, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 1, mayStore = 0 in { - def AME_MLS : AME_LOAD<0b0000010, "mls">; - def AME_MLS_CM : AME_LOAD<0b0000001, "mls.cm">; - def AME_MLS_RM : AME_LOAD<0b0000000, "mls.rm">; + def ZTT_MLS : ZTT_LOAD<0b0000010, "mls">; + def ZTT_MLS_CM : ZTT_LOAD<0b0000001, "mls.cm">; + def ZTT_MLS_RM : ZTT_LOAD<0b0000000, "mls.rm">; } // Base class for the interoperability store instructions (mss, mss.cm, // mss.rm). -class AME_STORE funct7, string opcodestr> +class ZTT_STORE funct7, string opcodestr> : RVInstAME32 funct7, string opcodestr> let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 1 in { - def AME_MSS : AME_STORE<0b0000101, "mss">; - def AME_MSS_CM : AME_STORE<0b0000100, "mss.cm">; - def AME_MSS_RM : AME_STORE<0b0000011, "mss.rm">; + def ZTT_MSS : ZTT_STORE<0b0000101, "mss">; + def ZTT_MSS_CM : ZTT_STORE<0b0000100, "mss.cm">; + def ZTT_MSS_RM : ZTT_STORE<0b0000011, "mss.rm">; } def Simm7AsmOperand : SImmAsmOperand<7>; -// 7-bit signed intermediate instr operand class (for AME_MSHIFT_EW) +// 7-bit signed intermediate instr operand class (for ZTT_MSHIFT_EW) def simm7 : Operand { let ParserMatchClass = Simm7AsmOperand; let DecoderMethod = "decodeSImmOperand<7>"; - let OperandType = "OPERAND_SIMM7"; + let OperandType = "OPERAND_IMMEDIATE"; } let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { // mzero.2d - clears an accumulator. - def AME_MZERO_2D : RVInstAME32<0b0001000, (outs), + def ZTT_MZERO_2D : RVInstAME32<0b0001000, (outs), (ins ZttAccRegIndex: $acc), "mzero.2d", "$acc"> { bits<2> acc; @@ -311,7 +311,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // mmov.a.m - copy an Acc register into an M register. - def AME_MMOV_A_M : RVInstAME32<0b0000011, (outs ), + def ZTT_MMOV_A_M : RVInstAME32<0b0000011, (outs ), (ins ZttMatrixRegIndex: $md, ZttAccRegIndex: $acc), "mmov.a.m", "$md, $acc"> { @@ -325,7 +325,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // mmov.m.m - copy one M register into another. - def AME_MMOV_M_M : RVInstAME32<0b0000010, (outs ), + def ZTT_MMOV_M_M : RVInstAME32<0b0000010, (outs ), (ins ZttMatrixRegIndex: $md, ZttMatrixRegIndex: $ms), "mmov.m.m", "$md, $ms"> { @@ -338,7 +338,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // mgettyp - read an M register's dtype tag into a GPR. - def AME_MGETTYP : RVInstAME32<0b0000010, (outs GPR: $xd), + def ZTT_MGETTYP : RVInstAME32<0b0000010, (outs GPR: $xd), (ins ZttMatrixRegIndex: $ms1), "mgettyp", "$xd, $ms1"> { bits<5> ms1; @@ -351,7 +351,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // agettyp - read an Acc register's dtype tag into a GPR. - def AME_AGETTYP : RVInstAME32<0b0000100, (outs GPR: $xd), + def ZTT_AGETTYP : RVInstAME32<0b0000100, (outs GPR: $xd), (ins ZttAccRegIndex: $ad), "agettyp", "$xd, $ad"> { bits<2> ad; @@ -364,7 +364,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // msettyp - write a GPR value as an M register's dtype tag. - def AME_MSETTYP : RVInstAME32<0b0000001, (outs ), + def ZTT_MSETTYP : RVInstAME32<0b0000001, (outs ), (ins ZttMatrixRegIndex: $md, GPR: $xs1), "msettyp", "$md, $xs1"> { @@ -378,7 +378,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // asettyp - write a GPR value as an Acc register's dtype tag. - def AME_ASETTYP : RVInstAME32<0b0000011, (outs ), + def ZTT_ASETTYP : RVInstAME32<0b0000011, (outs ), (ins ZttAccRegIndex: $ad, GPR: $xs1), "asettyp", "$ad, $xs1"> { @@ -392,7 +392,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, } // mbcast.x - broadcast a GPR scalar to every element of an M register. - def AME_MBCAST_X : RVInstAME32<0b0000000, (outs ), + def ZTT_MBCAST_X : RVInstAME32<0b0000000, (outs ), (ins ZttMatrixRegIndex: $md, GPR: $xs1), "mbcast.x", "$md, $xs1"> { @@ -407,7 +407,7 @@ let Predicates = [HasStdExtZtt], hasSideEffects = 1, mayLoad = 0, // mshift.ew - md[i,j] = ms1[i, j+imm], or 0 if j+imm is out of bounds - def AME_MSHIFT_EW : RVInst<(outs ), + def ZTT_MSHIFT_EW : RVInst<(outs ), (ins ZttMatrixRegIndex:$md, ZttMatrixRegIndex:$ms1, simm7:$imm), "mshift.ew", "$md, $ms1, $imm", [], InstFormatOther> { bits<5> ms1; @@ -433,21 +433,21 @@ class AMEUnaryPat (inst timm:$md, timm:$ms1)>; let Predicates = [HasStdExtZtt] in { - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; - def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; + def : AMEUnaryPat; } // Base pattern helper for matrix-matrix binary operations @@ -456,42 +456,42 @@ class AMEBinMatPat (inst timm:$md, timm:$ms1, timm:$ms2)>; let Predicates = [HasStdExtZtt] in { - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; - def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; + def : AMEBinMatPat; } // Base pattern helper for matrix-scalar operations. @@ -501,30 +501,30 @@ class AMEBinScalarPat (inst timm:$md, GPR:$xs1, timm:$ms2)>; let Predicates = [HasStdExtZtt, IsRV64] in { - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; - def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; + def : AMEBinScalarPat; } // Base class helper for matrix multiplication operations. @@ -534,48 +534,48 @@ class AMEMatMulPat (inst timm:$acc, timm:$ms1, timm:$ms2)>; let Predicates = [HasStdExtZtt] in { - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; - def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; + def : AMEMatMulPat; } // Miscellaneous instructions let Predicates = [HasStdExtZtt] in { // Load/Store Patterns (Memory addresses are handled as ptr_ty -> GPR) - def : Pat<(int_riscv_ame_mls timm:$md, iPTR:$xs1), (AME_MLS timm:$md, GPR:$xs1)>; - def : Pat<(int_riscv_ame_mls_cm timm:$md, iPTR:$xs1), (AME_MLS_CM timm:$md, GPR:$xs1)>; - def : Pat<(int_riscv_ame_mls_rm timm:$md, iPTR:$xs1), (AME_MLS_RM timm:$md, GPR:$xs1)>; - def : Pat<(int_riscv_ame_mss timm:$ms1, iPTR:$xs1), (AME_MSS timm:$ms1, GPR:$xs1)>; - def : Pat<(int_riscv_ame_mss_cm timm:$ms1, iPTR:$xs1), (AME_MSS_CM timm:$ms1, GPR:$xs1)>; - def : Pat<(int_riscv_ame_mss_rm timm:$ms1, iPTR:$xs1), (AME_MSS_RM timm:$ms1, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mls timm:$md, iPTR:$xs1), (ZTT_MLS timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mls_cm timm:$md, iPTR:$xs1), (ZTT_MLS_CM timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mls_rm timm:$md, iPTR:$xs1), (ZTT_MLS_RM timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mss timm:$ms1, iPTR:$xs1), (ZTT_MSS timm:$ms1, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mss_cm timm:$ms1, iPTR:$xs1), (ZTT_MSS_CM timm:$ms1, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mss_rm timm:$ms1, iPTR:$xs1), (ZTT_MSS_RM timm:$ms1, GPR:$xs1)>; // Broadcast & Zero - def : Pat<(int_riscv_ame_mzero_2d timm:$acc), (AME_MZERO_2D timm:$acc)>; + def : Pat<(int_riscv_ztt_mzero_2d timm:$acc), (ZTT_MZERO_2D timm:$acc)>; // Type operations - def : Pat<(int_riscv_ame_mgettyp timm:$ms1), (AME_MGETTYP timm:$ms1)>; - def : Pat<(int_riscv_ame_agettyp timm:$ad), (AME_AGETTYP timm:$ad)>; + def : Pat<(int_riscv_ztt_mgettyp timm:$ms1), (ZTT_MGETTYP timm:$ms1)>; + def : Pat<(int_riscv_ztt_agettyp timm:$ad), (ZTT_AGETTYP timm:$ad)>; // Moves - def : Pat<(int_riscv_ame_mmov_a_m timm:$md, timm:$acc), (AME_MMOV_A_M timm:$md, timm:$acc)>; - def : Pat<(int_riscv_ame_mmov_m_m timm:$md, timm:$ms), (AME_MMOV_M_M timm:$md, timm:$ms)>; - def : Pat<(int_riscv_ame_mshift_ew timm:$md, timm:$ms1, timm:$imm), - (AME_MSHIFT_EW timm:$md, timm:$ms1, timm:$imm)>; + def : Pat<(int_riscv_ztt_mmov_a_m timm:$md, timm:$acc), (ZTT_MMOV_A_M timm:$md, timm:$acc)>; + def : Pat<(int_riscv_ztt_mmov_m_m timm:$md, timm:$ms), (ZTT_MMOV_M_M timm:$md, timm:$ms)>; + def : Pat<(int_riscv_ztt_mshift_ew timm:$md, timm:$ms1, timm:$imm), + (ZTT_MSHIFT_EW timm:$md, timm:$ms1, timm:$imm)>; } // Miscellaneous instructions with scalar operands let Predicates = [HasStdExtZtt, IsRV64] in { // Broadcast & Zero - def : Pat<(int_riscv_ame_mbcast_x timm:$md, i64:$xs1), (AME_MBCAST_X timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_mbcast_x timm:$md, i64:$xs1), (ZTT_MBCAST_X timm:$md, GPR:$xs1)>; // Type operations - def : Pat<(int_riscv_ame_msettyp timm:$md, i64:$xs1), (AME_MSETTYP timm:$md, GPR:$xs1)>; - def : Pat<(int_riscv_ame_asettyp timm:$ad, i64:$xs1), (AME_ASETTYP timm:$ad, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_msettyp timm:$md, i64:$xs1), (ZTT_MSETTYP timm:$md, GPR:$xs1)>; + def : Pat<(int_riscv_ztt_asettyp timm:$ad, i64:$xs1), (ZTT_ASETTYP timm:$ad, GPR:$xs1)>; } // TODO: diff --git a/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll b/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll index 92922f5c3cb6d..37b10a6ed15bc 100644 --- a/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/ztt-intrinsics.ll @@ -1,595 +1,992 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + ; RUN: llc -mtriple=riscv64 -mattr=+experimental-ztt -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64 define void @test_mabs_ew() { - call void @llvm.riscv.ame.mabs.ew(i64 1, i64 2) +; RV64-LABEL: test_mabs_ew: +; RV64: # %bb.0: +; RV64-NEXT: mabs.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mabs.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mabs.ew(i64, i64) +declare void @llvm.riscv.ztt.mabs.ew(i64, i64) define void @test_mcolunzip_ew() { - call void @llvm.riscv.ame.mcolunzip.ew(i64 1, i64 2) +; RV64-LABEL: test_mcolunzip_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcolunzip.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcolunzip.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mcolunzip.ew(i64, i64) +declare void @llvm.riscv.ztt.mcolunzip.ew(i64, i64) define void @test_mcolzip_ew() { - call void @llvm.riscv.ame.mcolzip.ew(i64 1, i64 2) +; RV64-LABEL: test_mcolzip_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcolzip.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcolzip.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mcolzip.ew(i64, i64) +declare void @llvm.riscv.ztt.mcolzip.ew(i64, i64) define void @test_mconv_ew() { - call void @llvm.riscv.ame.mconv.ew(i64 1, i64 2) +; RV64-LABEL: test_mconv_ew: +; RV64: # %bb.0: +; RV64-NEXT: mconv.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mconv.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mconv.ew(i64, i64) +declare void @llvm.riscv.ztt.mconv.ew(i64, i64) define void @test_mexp2_ew() { - call void @llvm.riscv.ame.mexp2.ew(i64 1, i64 2) +; RV64-LABEL: test_mexp2_ew: +; RV64: # %bb.0: +; RV64-NEXT: mexp2.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mexp2.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mexp2.ew(i64, i64) +declare void @llvm.riscv.ztt.mexp2.ew(i64, i64) define void @test_mlog2_ew() { - call void @llvm.riscv.ame.mlog2.ew(i64 1, i64 2) +; RV64-LABEL: test_mlog2_ew: +; RV64: # %bb.0: +; RV64-NEXT: mlog2.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mlog2.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mlog2.ew(i64, i64) +declare void @llvm.riscv.ztt.mlog2.ew(i64, i64) define void @test_mprefixadd_col() { - call void @llvm.riscv.ame.mprefixadd.col(i64 1, i64 2) +; RV64-LABEL: test_mprefixadd_col: +; RV64: # %bb.0: +; RV64-NEXT: mprefixadd.col m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mprefixadd.col(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mprefixadd.col(i64, i64) +declare void @llvm.riscv.ztt.mprefixadd.col(i64, i64) define void @test_mprefixadd_row() { - call void @llvm.riscv.ame.mprefixadd.row(i64 1, i64 2) +; RV64-LABEL: test_mprefixadd_row: +; RV64: # %bb.0: +; RV64-NEXT: mprefixadd.row m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mprefixadd.row(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mprefixadd.row(i64, i64) +declare void @llvm.riscv.ztt.mprefixadd.row(i64, i64) define void @test_mprefixmax_col() { - call void @llvm.riscv.ame.mprefixmax.col(i64 1, i64 2) +; RV64-LABEL: test_mprefixmax_col: +; RV64: # %bb.0: +; RV64-NEXT: mprefixmax.col m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mprefixmax.col(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mprefixmax.col(i64, i64) +declare void @llvm.riscv.ztt.mprefixmax.col(i64, i64) define void @test_mprefixmax_row() { - call void @llvm.riscv.ame.mprefixmax.row(i64 1, i64 2) +; RV64-LABEL: test_mprefixmax_row: +; RV64: # %bb.0: +; RV64-NEXT: mprefixmax.row m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mprefixmax.row(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mprefixmax.row(i64, i64) +declare void @llvm.riscv.ztt.mprefixmax.row(i64, i64) define void @test_mreduceadd_col() { - call void @llvm.riscv.ame.mreduceadd.col(i64 1, i64 2) +; RV64-LABEL: test_mreduceadd_col: +; RV64: # %bb.0: +; RV64-NEXT: mreduceadd.col m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mreduceadd.col(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mreduceadd.col(i64, i64) +declare void @llvm.riscv.ztt.mreduceadd.col(i64, i64) define void @test_mreduceadd_row() { - call void @llvm.riscv.ame.mreduceadd.row(i64 1, i64 2) +; RV64-LABEL: test_mreduceadd_row: +; RV64: # %bb.0: +; RV64-NEXT: mreduceadd.row m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mreduceadd.row(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mreduceadd.row(i64, i64) +declare void @llvm.riscv.ztt.mreduceadd.row(i64, i64) define void @test_mreducemax_col() { - call void @llvm.riscv.ame.mreducemax.col(i64 1, i64 2) +; RV64-LABEL: test_mreducemax_col: +; RV64: # %bb.0: +; RV64-NEXT: mreducemax.col m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mreducemax.col(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mreducemax.col(i64, i64) +declare void @llvm.riscv.ztt.mreducemax.col(i64, i64) define void @test_mreducemax_row() { - call void @llvm.riscv.ame.mreducemax.row(i64 1, i64 2) +; RV64-LABEL: test_mreducemax_row: +; RV64: # %bb.0: +; RV64-NEXT: mreducemax.row m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mreducemax.row(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mreducemax.row(i64, i64) +declare void @llvm.riscv.ztt.mreducemax.row(i64, i64) define void @test_mrowunzip_ew() { - call void @llvm.riscv.ame.mrowunzip.ew(i64 1, i64 2) +; RV64-LABEL: test_mrowunzip_ew: +; RV64: # %bb.0: +; RV64-NEXT: mrowunzip.ew m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mrowunzip.ew(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mrowunzip.ew(i64, i64) +declare void @llvm.riscv.ztt.mrowunzip.ew(i64, i64) define void @test_mabsdiff_ew() { - call void @llvm.riscv.ame.mabsdiff.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mabsdiff_ew: +; RV64: # %bb.0: +; RV64-NEXT: mabsdiff.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mabsdiff.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mabsdiff.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mabsdiff.ew(i64, i64, i64) define void @test_madd_ew() { - call void @llvm.riscv.ame.madd.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_madd_ew: +; RV64: # %bb.0: +; RV64-NEXT: madd.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.madd.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.madd.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.madd.ew(i64, i64, i64) define void @test_mand_ew() { - call void @llvm.riscv.ame.mand.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mand_ew: +; RV64: # %bb.0: +; RV64-NEXT: mand.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mand.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mand.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mand.ew(i64, i64, i64) define void @test_mandnot_ew() { - call void @llvm.riscv.ame.mandnot.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mandnot_ew: +; RV64: # %bb.0: +; RV64-NEXT: mandnot.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mandnot.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mandnot.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mandnot.ew(i64, i64, i64) define void @test_mcmovge_ew() { - call void @llvm.riscv.ame.mcmovge.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mcmovge_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcmovge.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmovge.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mcmovge.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmovge.ew(i64, i64, i64) define void @test_mcmovlt_ew() { - call void @llvm.riscv.ame.mcmovlt.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mcmovlt_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcmovlt.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmovlt.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mcmovlt.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmovlt.ew(i64, i64, i64) define void @test_mcmpge_ew() { - call void @llvm.riscv.ame.mcmpge.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mcmpge_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcmpge.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmpge.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mcmpge.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmpge.ew(i64, i64, i64) define void @test_mcmplt_ew() { - call void @llvm.riscv.ame.mcmplt.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mcmplt_ew: +; RV64: # %bb.0: +; RV64-NEXT: mcmplt.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmplt.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mcmplt.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmplt.ew(i64, i64, i64) define void @test_mgather_ew() { - call void @llvm.riscv.ame.mgather.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mgather_ew: +; RV64: # %bb.0: +; RV64-NEXT: mgather.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mgather.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mgather.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mgather.ew(i64, i64, i64) define void @test_mhdiff_ew() { - call void @llvm.riscv.ame.mhdiff.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mhdiff_ew: +; RV64: # %bb.0: +; RV64-NEXT: mhdiff.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mhdiff.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mhdiff.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mhdiff.ew(i64, i64, i64) define void @test_mldexp_ew() { - call void @llvm.riscv.ame.mldexp.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mldexp_ew: +; RV64: # %bb.0: +; RV64-NEXT: mldexp.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mldexp.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mldexp.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mldexp.ew(i64, i64, i64) define void @test_mldexpacc_ew() { - call void @llvm.riscv.ame.mldexpacc.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mldexpacc_ew: +; RV64: # %bb.0: +; RV64-NEXT: mldexpacc.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mldexpacc.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mldexpacc.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mldexpacc.ew(i64, i64, i64) define void @test_mlog2sub_ew() { - call void @llvm.riscv.ame.mlog2sub.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mlog2sub_ew: +; RV64: # %bb.0: +; RV64-NEXT: mlog2sub.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mlog2sub.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mlog2sub.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mlog2sub.ew(i64, i64, i64) define void @test_mmax_ew() { - call void @llvm.riscv.ame.mmax.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmax_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmax.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmax.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmax.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmax.ew(i64, i64, i64) define void @test_mmean_ew() { - call void @llvm.riscv.ame.mmean.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmean_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmean.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmean.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmean.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmean.ew(i64, i64, i64) define void @test_mmin_ew() { - call void @llvm.riscv.ame.mmin.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmin_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmin.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmin.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmin.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmin.ew(i64, i64, i64) define void @test_mmul_ew() { - call void @llvm.riscv.ame.mmul.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmul_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmul.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmul.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmul.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmul.ew(i64, i64, i64) define void @test_mmulacc_ew() { - call void @llvm.riscv.ame.mmulacc.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulacc_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmulacc.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulacc.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulacc.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulacc.ew(i64, i64, i64) define void @test_mmulaccneg_ew() { - call void @llvm.riscv.ame.mmulaccneg.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulaccneg_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmulaccneg.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulaccneg.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulaccneg.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulaccneg.ew(i64, i64, i64) define void @test_mmuladd_ew() { - call void @llvm.riscv.ame.mmuladd.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmuladd_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmuladd.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmuladd.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmuladd.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmuladd.ew(i64, i64, i64) define void @test_mmulneg_ew() { - call void @llvm.riscv.ame.mmulneg.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulneg_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmulneg.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulneg.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulneg.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulneg.ew(i64, i64, i64) define void @test_mmulsub_ew() { - call void @llvm.riscv.ame.mmulsub.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulsub_ew: +; RV64: # %bb.0: +; RV64-NEXT: mmulsub.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulsub.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulsub.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulsub.ew(i64, i64, i64) define void @test_mor_ew() { - call void @llvm.riscv.ame.mor.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mor_ew: +; RV64: # %bb.0: +; RV64-NEXT: mor.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mor.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mor.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mor.ew(i64, i64, i64) define void @test_mornot_ew() { - call void @llvm.riscv.ame.mornot.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mornot_ew: +; RV64: # %bb.0: +; RV64-NEXT: mornot.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mornot.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mornot.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mornot.ew(i64, i64, i64) define void @test_mrdexp_ew() { - call void @llvm.riscv.ame.mrdexp.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mrdexp_ew: +; RV64: # %bb.0: +; RV64-NEXT: mrdexp.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mrdexp.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mrdexp.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mrdexp.ew(i64, i64, i64) define void @test_mrdexpacc_ew() { - call void @llvm.riscv.ame.mrdexpacc.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mrdexpacc_ew: +; RV64: # %bb.0: +; RV64-NEXT: mrdexpacc.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mrdexpacc.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mrdexpacc.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mrdexpacc.ew(i64, i64, i64) define void @test_mrowzip_ew() { - call void @llvm.riscv.ame.mrowzip.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mrowzip_ew: +; RV64: # %bb.0: +; RV64-NEXT: mrowzip.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mrowzip.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mrowzip.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mrowzip.ew(i64, i64, i64) define void @test_mscatadd_col() { - call void @llvm.riscv.ame.mscatadd.col(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mscatadd_col: +; RV64: # %bb.0: +; RV64-NEXT: mscatadd.col m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mscatadd.col(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mscatadd.col(i64, i64, i64) +declare void @llvm.riscv.ztt.mscatadd.col(i64, i64, i64) define void @test_mscatadd_row() { - call void @llvm.riscv.ame.mscatadd.row(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mscatadd_row: +; RV64: # %bb.0: +; RV64-NEXT: mscatadd.row m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mscatadd.row(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mscatadd.row(i64, i64, i64) +declare void @llvm.riscv.ztt.mscatadd.row(i64, i64, i64) define void @test_mscatmax_col() { - call void @llvm.riscv.ame.mscatmax.col(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mscatmax_col: +; RV64: # %bb.0: +; RV64-NEXT: mscatmax.col m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mscatmax.col(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mscatmax.col(i64, i64, i64) +declare void @llvm.riscv.ztt.mscatmax.col(i64, i64, i64) define void @test_mscatmax_row() { - call void @llvm.riscv.ame.mscatmax.row(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mscatmax_row: +; RV64: # %bb.0: +; RV64-NEXT: mscatmax.row m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mscatmax.row(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mscatmax.row(i64, i64, i64) +declare void @llvm.riscv.ztt.mscatmax.row(i64, i64, i64) define void @test_mselge_ew() { - call void @llvm.riscv.ame.mselge.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mselge_ew: +; RV64: # %bb.0: +; RV64-NEXT: mselge.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mselge.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mselge.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mselge.ew(i64, i64, i64) define void @test_msellt_ew() { - call void @llvm.riscv.ame.msellt.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_msellt_ew: +; RV64: # %bb.0: +; RV64-NEXT: msellt.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msellt.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.msellt.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.msellt.ew(i64, i64, i64) define void @test_msub_ew() { - call void @llvm.riscv.ame.msub.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_msub_ew: +; RV64: # %bb.0: +; RV64-NEXT: msub.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msub.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.msub.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.msub.ew(i64, i64, i64) define void @test_msublog2_ew() { - call void @llvm.riscv.ame.msublog2.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_msublog2_ew: +; RV64: # %bb.0: +; RV64-NEXT: msublog2.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msublog2.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.msublog2.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.msublog2.ew(i64, i64, i64) define void @test_mxor_ew() { - call void @llvm.riscv.ame.mxor.ew(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mxor_ew: +; RV64: # %bb.0: +; RV64-NEXT: mxor.ew m1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mxor.ew(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mxor.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mxor.ew(i64, i64, i64) define void @test_mabsdiff_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mabsdiff.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mabsdiff_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mabsdiff.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mabsdiff.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mabsdiff.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mabsdiff.ew.x(i64, i64, i64) define void @test_madd_ew_x(i64 %a1) { - call void @llvm.riscv.ame.madd.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_madd_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: madd.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.madd.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.madd.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.madd.ew.x(i64, i64, i64) define void @test_mand_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mand.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mand_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mand.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mand.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mand.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mand.ew.x(i64, i64, i64) define void @test_mandnot_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mandnot.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mandnot_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mandnot.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mandnot.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mandnot.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mandnot.ew.x(i64, i64, i64) define void @test_mcmpge_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mcmpge.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mcmpge_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mcmpge.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmpge.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mcmpge.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmpge.ew.x(i64, i64, i64) define void @test_mcmplt_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mcmplt.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mcmplt_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mcmplt.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mcmplt.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mcmplt.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mcmplt.ew.x(i64, i64, i64) define void @test_mhdiff_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mhdiff.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mhdiff_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mhdiff.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mhdiff.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mhdiff.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mhdiff.ew.x(i64, i64, i64) define void @test_mldexp_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mldexp.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mldexp_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mldexp.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mldexp.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mldexp.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mldexp.ew.x(i64, i64, i64) define void @test_mldexpacc_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mldexpacc.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mldexpacc_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mldexpacc.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mldexpacc.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mldexpacc.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mldexpacc.ew.x(i64, i64, i64) define void @test_mlog2sub_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mlog2sub.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mlog2sub_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mlog2sub.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mlog2sub.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mlog2sub.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mlog2sub.ew.x(i64, i64, i64) define void @test_mmax_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmax.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmax_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmax.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmax.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmax.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmax.ew.x(i64, i64, i64) define void @test_mmean_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmean.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmean_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmean.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmean.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmean.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmean.ew.x(i64, i64, i64) define void @test_mmin_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmin.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmin_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmin.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmin.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmin.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmin.ew.x(i64, i64, i64) define void @test_mmul_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmul.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmul_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmul.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmul.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmul.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmul.ew.x(i64, i64, i64) define void @test_mmulacc_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmulacc.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmulacc_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmulacc.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulacc.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmulacc.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulacc.ew.x(i64, i64, i64) define void @test_mmulaccneg_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmulaccneg.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmulaccneg_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmulaccneg.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulaccneg.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmulaccneg.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulaccneg.ew.x(i64, i64, i64) define void @test_mmuladd_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmuladd.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmuladd_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmuladd.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmuladd.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmuladd.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmuladd.ew.x(i64, i64, i64) define void @test_mmulneg_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmulneg.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmulneg_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmulneg.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulneg.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmulneg.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulneg.ew.x(i64, i64, i64) define void @test_mmulsub_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mmulsub.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mmulsub_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mmulsub.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulsub.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mmulsub.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulsub.ew.x(i64, i64, i64) define void @test_mor_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mor.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mor_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mor.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mor.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mor.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mor.ew.x(i64, i64, i64) define void @test_mornot_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mornot.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mornot_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mornot.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mornot.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mornot.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mornot.ew.x(i64, i64, i64) define void @test_msub_ew_x(i64 %a1) { - call void @llvm.riscv.ame.msub.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_msub_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: msub.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msub.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.msub.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.msub.ew.x(i64, i64, i64) define void @test_msublog2_ew_x(i64 %a1) { - call void @llvm.riscv.ame.msublog2.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_msublog2_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: msublog2.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msublog2.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.msublog2.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.msublog2.ew.x(i64, i64, i64) define void @test_mxor_ew_x(i64 %a1) { - call void @llvm.riscv.ame.mxor.ew.x(i64 1, i64 %a1, i64 2) +; RV64-LABEL: test_mxor_ew_x: +; RV64: # %bb.0: +; RV64-NEXT: mxor.ew.x m1, a0, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mxor.ew.x(i64 1, i64 %a1, i64 2) ret void } -declare void @llvm.riscv.ame.mxor.ew.x(i64, i64, i64) +declare void @llvm.riscv.ztt.mxor.ew.x(i64, i64, i64) define void @test_mmul_2d() { - call void @llvm.riscv.ame.mmul.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmul_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmul.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmul.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmul.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmul.2d(i64, i64, i64) define void @test_mmulacc_2d() { - call void @llvm.riscv.ame.mmulacc.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulacc_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulacc.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulacc.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulacc.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulacc.2d(i64, i64, i64) define void @test_mmulaccneg_2d() { - call void @llvm.riscv.ame.mmulaccneg.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulaccneg_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulaccneg.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulaccneg.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulaccneg.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulaccneg.2d(i64, i64, i64) define void @test_mmulat_2d() { - call void @llvm.riscv.ame.mmulat.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulat_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulat.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulat.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulat.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulat.2d(i64, i64, i64) define void @test_mmulatacc_2d() { - call void @llvm.riscv.ame.mmulatacc.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulatacc_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulatacc.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulatacc.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulatacc.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulatacc.2d(i64, i64, i64) define void @test_mmulbt_2d() { - call void @llvm.riscv.ame.mmulbt.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulbt_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulbt.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulbt.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulbt.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulbt.2d(i64, i64, i64) define void @test_mmulbtacc_2d() { - call void @llvm.riscv.ame.mmulbtacc.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulbtacc_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulbtacc.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulbtacc.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulbtacc.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulbtacc.2d(i64, i64, i64) define void @test_mmulneg_2d() { - call void @llvm.riscv.ame.mmulneg.2d(i64 1, i64 2, i64 3) +; RV64-LABEL: test_mmulneg_2d: +; RV64: # %bb.0: +; RV64-NEXT: mmulneg.2d acc1, m2, m3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmulneg.2d(i64 1, i64 2, i64 3) ret void } -declare void @llvm.riscv.ame.mmulneg.2d(i64, i64, i64) +declare void @llvm.riscv.ztt.mmulneg.2d(i64, i64, i64) define void @test_mls(ptr %addr) { - call void @llvm.riscv.ame.mls(i64 1, ptr %addr) +; RV64-LABEL: test_mls: +; RV64: # %bb.0: +; RV64-NEXT: mls m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mls(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mls(i64, ptr) +declare void @llvm.riscv.ztt.mls(i64, ptr) define void @test_mls_cm(ptr %addr) { - call void @llvm.riscv.ame.mls.cm(i64 1, ptr %addr) +; RV64-LABEL: test_mls_cm: +; RV64: # %bb.0: +; RV64-NEXT: mls.cm m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mls.cm(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mls.cm(i64, ptr) +declare void @llvm.riscv.ztt.mls.cm(i64, ptr) define void @test_mls_rm(ptr %addr) { - call void @llvm.riscv.ame.mls.rm(i64 1, ptr %addr) +; RV64-LABEL: test_mls_rm: +; RV64: # %bb.0: +; RV64-NEXT: mls.rm m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mls.rm(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mls.rm(i64, ptr) +declare void @llvm.riscv.ztt.mls.rm(i64, ptr) define void @test_mss(ptr %addr) { - call void @llvm.riscv.ame.mss(i64 1, ptr %addr) +; RV64-LABEL: test_mss: +; RV64: # %bb.0: +; RV64-NEXT: mss m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mss(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mss(i64, ptr) +declare void @llvm.riscv.ztt.mss(i64, ptr) define void @test_mss_cm(ptr %addr) { - call void @llvm.riscv.ame.mss.cm(i64 1, ptr %addr) +; RV64-LABEL: test_mss_cm: +; RV64: # %bb.0: +; RV64-NEXT: mss.cm m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mss.cm(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mss.cm(i64, ptr) +declare void @llvm.riscv.ztt.mss.cm(i64, ptr) define void @test_mss_rm(ptr %addr) { - call void @llvm.riscv.ame.mss.rm(i64 1, ptr %addr) +; RV64-LABEL: test_mss_rm: +; RV64: # %bb.0: +; RV64-NEXT: mss.rm m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mss.rm(i64 1, ptr %addr) ret void } -declare void @llvm.riscv.ame.mss.rm(i64, ptr) +declare void @llvm.riscv.ztt.mss.rm(i64, ptr) define void @test_mzero_2d() { - call void @llvm.riscv.ame.mzero.2d(i64 1) +; RV64-LABEL: test_mzero_2d: +; RV64: # %bb.0: +; RV64-NEXT: mzero.2d acc1 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mzero.2d(i64 1) ret void } -declare void @llvm.riscv.ame.mzero.2d(i64) +declare void @llvm.riscv.ztt.mzero.2d(i64) define void @test_mmov_a_m() { - call void @llvm.riscv.ame.mmov.a.m(i64 1, i64 2) +; RV64-LABEL: test_mmov_a_m: +; RV64: # %bb.0: +; RV64-NEXT: mmov.a.m m1, acc2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmov.a.m(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mmov.a.m(i64, i64) +declare void @llvm.riscv.ztt.mmov.a.m(i64, i64) define void @test_mmov_m_m() { - call void @llvm.riscv.ame.mmov.m.m(i64 1, i64 2) +; RV64-LABEL: test_mmov_m_m: +; RV64: # %bb.0: +; RV64-NEXT: mmov.m.m m1, m2 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mmov.m.m(i64 1, i64 2) ret void } -declare void @llvm.riscv.ame.mmov.m.m(i64, i64) +declare void @llvm.riscv.ztt.mmov.m.m(i64, i64) define i64 @test_mgettyp() { - %type = call i64 @llvm.riscv.ame.mgettyp(i64 1) +; RV64-LABEL: test_mgettyp: +; RV64: # %bb.0: +; RV64-NEXT: mgettyp a0, m1 +; RV64-NEXT: ret + %type = call i64 @llvm.riscv.ztt.mgettyp(i64 1) ret i64 %type } -declare i64 @llvm.riscv.ame.mgettyp(i64) +declare i64 @llvm.riscv.ztt.mgettyp(i64) define i64 @test_agettyp() { - %type = call i64 @llvm.riscv.ame.agettyp(i64 1) +; RV64-LABEL: test_agettyp: +; RV64: # %bb.0: +; RV64-NEXT: agettyp a0, acc1 +; RV64-NEXT: ret + %type = call i64 @llvm.riscv.ztt.agettyp(i64 1) ret i64 %type } -declare i64 @llvm.riscv.ame.agettyp(i64) +declare i64 @llvm.riscv.ztt.agettyp(i64) define void @test_msettyp(i64 %a1) { - call void @llvm.riscv.ame.msettyp(i64 1, i64 %a1) +; RV64-LABEL: test_msettyp: +; RV64: # %bb.0: +; RV64-NEXT: msettyp m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.msettyp(i64 1, i64 %a1) ret void } -declare void @llvm.riscv.ame.msettyp(i64, i64) +declare void @llvm.riscv.ztt.msettyp(i64, i64) define void @test_asettyp(i64 %a1) { - call void @llvm.riscv.ame.asettyp(i64 1, i64 %a1) +; RV64-LABEL: test_asettyp: +; RV64: # %bb.0: +; RV64-NEXT: asettyp acc1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.asettyp(i64 1, i64 %a1) ret void } -declare void @llvm.riscv.ame.asettyp(i64, i64) +declare void @llvm.riscv.ztt.asettyp(i64, i64) define void @test_mbcast_x(i64 %a1) { - call void @llvm.riscv.ame.mbcast.x(i64 1, i64 %a1) +; RV64-LABEL: test_mbcast_x: +; RV64: # %bb.0: +; RV64-NEXT: mbcast.x m1, a0 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mbcast.x(i64 1, i64 %a1) ret void } -declare void @llvm.riscv.ame.mbcast.x(i64, i64) +declare void @llvm.riscv.ztt.mbcast.x(i64, i64) define void @test_mshift_ew_pos() { - call void @llvm.riscv.ame.mshift.ew(i64 1, i64 2, i64 5) +; RV64-LABEL: test_mshift_ew_pos: +; RV64: # %bb.0: +; RV64-NEXT: mshift.ew m1, m2, 5 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mshift.ew(i64 1, i64 2, i64 5) ret void } define void @test_mshift_ew_neg() { - call void @llvm.riscv.ame.mshift.ew(i64 1, i64 2, i64 -3) +; RV64-LABEL: test_mshift_ew_neg: +; RV64: # %bb.0: +; RV64-NEXT: mshift.ew m1, m2, -3 +; RV64-NEXT: ret + call void @llvm.riscv.ztt.mshift.ew(i64 1, i64 2, i64 -3) ret void } -declare void @llvm.riscv.ame.mshift.ew(i64, i64, i64) +declare void @llvm.riscv.ztt.mshift.ew(i64, i64, i64) diff --git a/llvm/test/MC/RISCV/ztt-invalid.s b/llvm/test/MC/RISCV/ztt-invalid.s index 815606ed5f924..43f4298ef5630 100644 --- a/llvm/test/MC/RISCV/ztt-invalid.s +++ b/llvm/test/MC/RISCV/ztt-invalid.s @@ -1,68 +1,68 @@ -# RUN: not llvm-mc -triple=riscv64 --mattr=-experimental-ztt-ame-mregs-16,-experimental-ztt-ame-mregs-32 %s 2>&1 \ + # RUN: not llvm-mc -triple=riscv64 --mattr=-experimental-ztt-ame-mregs-16,-experimental-ztt-ame-mregs-32 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-NO-M-CONFIG # RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-ztt-ame-mregs-16,+experimental-ztt-ame-mregs-32 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-CONFLICT-M -# CHECK-NO-M-CONFIG: error: AME subtarget extension requires a matrix register configuration width to be chosen -# CHECK-CONFLICT-M: error: Conflicting AME register bounds chosen: cannot enable both 16 and 32 matrix registers simultaneously +# CHECK-NO-M-CONFIG: error: no ztt (AME) matrix register count feature enabled +# CHECK-CONFLICT-M: error: conflicting ztt (AME) matrix register bounds chosen; cannot enable both 16 and 32 matrix registers simultaneously # RUN: not llvm-mc -triple=riscv64 --mattr=-experimental-ztt-ame-accregs-1,-experimental-ztt-ame-accregs-2,-experimental-ztt-ame-accregs-4 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-NO-ACC-CONFIG # RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-ztt-ame-accregs-1,+experimental-ztt-ame-accregs-2 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-CONFLICT-ACC -# CHECK-NO-ACC-CONFIG: error: AME subtarget extension requires an accumulator register configuration count to be chosen -# CHECK-CONFLICT-ACC: error: Conflicting AME accumulator bounds chosen: cannot enable multiple accumulator register configurations simultaneously +# CHECK-NO-ACC-CONFIG: error: no ztt (AME) accumulator register count feature enabled +# CHECK-CONFLICT-ACC: error: conflicting ztt (AME) accumulator register bounds chosen; cannot enable multiple accumulator register configurations simultaneously # RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt %s 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-64 +# RUN: | FileCheck %s --check-prefixes=CHECK # RUN: not llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-ztt %s 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-32 -# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-mregs-16 %s 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=CHECK +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-mregs-16,-experimental-ztt-ame-mregs-32 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-M16 -# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-1 %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-1,-experimental-ztt-ame-accregs-2,-experimental-ztt-ame-accregs-4 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ACC1 -# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-2 %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-ztt,+experimental-ztt-ame-accregs-2,-experimental-ztt-ame-accregs-4 %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ACC2 # Immediate underflow: Value falls below the 7-bit signed boundary -# CHECK: :[[@LINE+1]]:24: error: immediate must be an integer in the range [-64, 63] +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} mshift.ew m1, m2, -65 # Immediate overflow: Value exceeds the 7-bit signed boundary -# CHECK: :[[@LINE+1]]:23: error: immediate must be an integer in the range [-64, 63] +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} mshift.ew m1, m2, 64 # Base register mismatch: Instruction expects matrix register class # but gets scalar GPR. -# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} mshift.ew x10, m2, 5 # Operand type mismatch: Instruction expects scalar register class but # gets accumulator register. -# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: register must be a GPR msettyp m1, acc1 # Destination target mismatch: Broadcast instruction targets accumulator # instead of matrix register. -# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} mbcast.x acc1, a0 # Syntax error: Operand count is lower than instruction signature requirements -# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction +# CHECK: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: too few operands for instruction mshift.ew m1, m2 # Matrix register out of bounds: Attempting to access m16 when constraint # drops limit down to 16. -# CHECK-M16: :[[@LINE+1]]:11: error: invalid operand for instruction +# CHECK-M16: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} mabs.ew m16, m2 # Accumulator register out of bounds: Attempting to access acc1 when configuration # limits context to 1 accumulator (acc0). -# CHECK-ACC1: :[[@LINE+1]]:14: error: invalid operand for instruction +# CHECK-ACC1: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} agettyp a0, acc1 # Accumulator register out of bounds: Attempting to access acc2 when configuration # limits context to 2 accumulators (acc0-acc1). -# CHECK-ACC2: :[[@LINE+1]]:14: error: invalid operand for instruction +# CHECK-ACC2: {{.*}}:{{[0-9]+}}:{{[0-9]+}}: error: {{invalid operand for instruction|invalid instruction}} agettyp a0, acc2