Skip to content

Commit

Permalink
[LLVM][AArch64][Assembly]: Add FAMINMAX assembly/disasse… (llvm#70115)
Browse files Browse the repository at this point in the history
…mbly.

This patch adds the feature flag FAMINMAX and the assembly/disassembly
for the following instructions of NEON, SVE2 and SME2:
* NEON:
  - FAMIN
  - FAMAX
* SVE2:
  - FAMIN_ZPmZ
  - FAMAX_ZPmZ
* SME2:
  - FAMAX_2Z2Z
  - FAMIN_2Z2Z
  - FAMAX_4Z4Z
  - FAMIN_4Z4Z

That is according to this documentation:
https://developer.arm.com/documentation/ddi0602/2023-09

Co-authored-by: Caroline Concatto <[email protected]>
  • Loading branch information
hassnaaHamdi and CarolineConcatto authored Oct 27, 2023
1 parent 7360c6a commit b23426e
Show file tree
Hide file tree
Showing 15 changed files with 770 additions and 2 deletions.
2 changes: 2 additions & 0 deletions llvm/include/llvm/TargetParser/AArch64TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ enum ArchExtKind : unsigned {
AEK_GCS = 57, // FEAT_GCS
AEK_FPMR = 58, // FEAT_FPMR
AEK_FP8 = 59, // FEAT_FP8
AEK_FAMINMAX = 60, // FEAT_FAMINMAX
AEK_NUM_EXTENSIONS
};
using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
Expand Down Expand Up @@ -271,6 +272,7 @@ inline constexpr ExtensionInfo Extensions[] = {
{"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0},
{"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0},
{"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0},
{"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0},
// Special cases
{"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority},
};
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64.td
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,9 @@ def FeatureSME2 : SubtargetFeature<"sme2", "HasSME2", "true",
def FeatureSME2p1 : SubtargetFeature<"sme2p1", "HasSME2p1", "true",
"Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions", [FeatureSME2]>;

def FeatureFAMINMAX: SubtargetFeature<"faminmax", "HasFAMINMAX", "true",
"Enable FAMIN and FAMAX instructions (FEAT_FAMINMAX)">;

def FeatureAppleA7SysReg : SubtargetFeature<"apple-a7-sysreg", "HasAppleA7SysReg", "true",
"Apple A7 (the CPU formerly known as Cyclone)">;

Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ def HasFPMR : Predicate<"Subtarget->hasFPMR()">,
AssemblerPredicateWithAll<(all_of FeatureFPMR), "fpmr">;
def HasFP8 : Predicate<"Subtarget->hasFP8()">,
AssemblerPredicateWithAll<(all_of FeatureFP8), "fp8">;
def HasFAMINMAX : Predicate<"Subtarget->hasFAMINMAX()">,
AssemblerPredicateWithAll<(all_of FeatureFAMINMAX), "faminmax">;

// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
Expand Down Expand Up @@ -9265,6 +9267,12 @@ let Predicates = [HasFP8] in {
defm FSCALE : SIMDThreeSameVectorFP<0b1, 0b1, 0b111, "fscale", null_frag>;
} // End let Predicates = [HasFP8]

let Predicates = [HasFAMINMAX] in {
defm FAMAX : SIMDThreeSameVectorFP<0b0, 0b1, 0b011, "famax", null_frag>;
defm FAMIN : SIMDThreeSameVectorFP<0b1, 0b1, 0b011, "famin", null_frag>;
} // End let Predicates = [HasFAMAXMIN]


include "AArch64InstrAtomics.td"
include "AArch64SVEInstrInfo.td"
include "AArch64SMEInstrInfo.td"
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -878,3 +878,10 @@ defm FSCALE_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"fscale", 0b001100

} // [HasSME2, HasFP8]

let Predicates = [HasSME2, HasFAMINMAX] in {
defm FAMAX_2Z2Z : sme2_fp_sve_destructive_vector_vg2_multi<"famax", 0b0010100>;
defm FAMIN_2Z2Z : sme2_fp_sve_destructive_vector_vg2_multi<"famin", 0b0010101>;

defm FAMAX_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"famax", 0b0010100>;
defm FAMIN_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"famin", 0b0010101>;
} //[HasSME2, HasFAMINMAX]
8 changes: 7 additions & 1 deletion llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -4022,4 +4022,10 @@ defm FCVTN_Z2Z_HtoB : sve2_fp8_down_cvt_single<0b00, "fcvtn", ZZ_h_mul_r>;
defm FCVTNB_Z2Z_StoB : sve2_fp8_down_cvt_single<0b01, "fcvtnb", ZZ_s_mul_r>;
defm BFCVTN_Z2Z_HtoB : sve2_fp8_down_cvt_single<0b10, "bfcvtn", ZZ_h_mul_r>;
defm FCVTNT_Z2Z_StoB : sve2_fp8_down_cvt_single<0b11, "fcvtnt", ZZ_s_mul_r>;
} // End HasSVE2orSME2, HasFP8
} // End HasSVE2orSME2, HasFP8

let Predicates = [HasSVE2orSME2, HasFAMINMAX] in {
// FP8 Arithmetic - Predicated Group
defm FAMIN_ZPmZ : sve_fp_2op_p_zds<0b1111, "famin", "", null_frag, DestructiveOther>;
defm FAMAX_ZPmZ : sve_fp_2op_p_zds<0b1110, "famax", "", null_frag, DestructiveOther>;
} // End HasSVE2orSME2, HasFAMINMAX
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3640,6 +3640,7 @@ static const struct Extension {
{"tme", {AArch64::FeatureTME}},
{"fpmr", {AArch64::FeatureFPMR}},
{"fp8", {AArch64::FeatureFP8}},
{"faminmax", {AArch64::FeatureFAMINMAX}},
};

static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
Expand Down
7 changes: 7 additions & 0 deletions llvm/test/MC/AArch64/FP8/directive-arch-negative.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@
bf1cvtl v0.8h, v0.8b
// CHECK: error: instruction requires: fp8
// CHECK: bf1cvtl v0.8h, v0.8b

.arch armv9-a+faminmax
.arch armv9-a+nofaminmax
famax v31.4h, v31.4h, v31.4h
// CHECK: error: instruction requires: faminmax
// CHECK: famax v31.4h, v31.4h, v31.4h

6 changes: 6 additions & 0 deletions llvm/test/MC/AArch64/FP8/directive-arch.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ bf1cvtl v0.8h, v0.8b
// CHECK: bf1cvtl v0.8h, v0.8b

.arch armv9-a+nofp8
.arch armv9-a+faminmax
famax v31.4h, v31.4h, v31.4h
// CHECK: famax v31.4h, v31.4h, v31.4h

.arch armv9-a+nofaminmax

64 changes: 64 additions & 0 deletions llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax 2>&1 < %s| FileCheck %s

// --------------------------------------------------------------------------//
// Element size extension incorrect

famax v0.16s, v0.4s, v0.4s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: famax v0.16s, v0.4s, v0.4s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famax v0.4h, v0.4s, v0.4s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famax v0.4h, v0.4s, v0.4s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famax v0.8h, v0.8s, v0.8s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: famax v0.8h, v0.8s, v0.8s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famax v0.2s, v0.2h, v0.2h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famax v0.2s, v0.2h, v0.2h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famax v0.4s, v31.4h, v0.4h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famax v0.4s, v31.4h, v0.4h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famax v0.2d, v31.2h, v0.2h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famax v0.2d, v31.2h, v0.2h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.16s, v0.4s, v0.4s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: famin v0.16s, v0.4s, v0.4s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.4h, v0.4s, v0.4s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famin v0.4h, v0.4s, v0.4s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.8h, v0.8s, v0.8s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: famin v0.8h, v0.8s, v0.8s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.2s, v0.2h, v0.2h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famin v0.2s, v0.2h, v0.2h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.4s, v31.4h, v0.4h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famin v0.4s, v31.4h, v0.4h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

famin v0.2d, v31.2h, v0.2h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: famin v0.2d, v31.2h, v0.2h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
197 changes: 197 additions & 0 deletions llvm/test/MC/AArch64/FP8/faminmax.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+faminmax < %s \
// RUN: | llvm-objdump -d --mattr=+faminmax - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+faminmax < %s \
// RUN: | llvm-objdump -d --mattr=-faminmax - | FileCheck %s --check-prefix=CHECK-UNKNOWN
// Disassemble encoding and check the re-encoding (-show-encoding) matches.
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax < %s \
// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
// RUN: | llvm-mc -triple=aarch64 -mattr=+faminmax -disassemble -show-encoding \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST

/// FAMAX instructions.
famax v31.4h, v31.4h, v31.4h
// CHECK-INST: famax v31.4h, v31.4h, v31.4h
// CHECK-ENCODING: [0xff,0x1f,0xdf,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0edf1fff <unknown>

famax v31.4h, v0.4h, v31.4h
// CHECK-INST: famax v31.4h, v0.4h, v31.4h
// CHECK-ENCODING: [0x1f,0x1c,0xdf,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0edf1c1f <unknown>

famax v0.4h, v0.4h, v0.4h
// CHECK-INST: famax v0.4h, v0.4h, v0.4h
// CHECK-ENCODING: [0x00,0x1c,0xc0,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0ec01c00 <unknown>

famax v31.8h, v31.8h, v31.8h
// CHECK-INST: famax v31.8h, v31.8h, v31.8h
// CHECK-ENCODING: [0xff,0x1f,0xdf,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4edf1fff <unknown>

famax v31.8h, v31.8h, v0.8h
// CHECK-INST: famax v31.8h, v31.8h, v0.8h
// CHECK-ENCODING: [0xff,0x1f,0xc0,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ec01fff <unknown>

famax v0.8h, v0.8h, v0.8h
// CHECK-INST: famax v0.8h, v0.8h, v0.8h
// CHECK-ENCODING: [0x00,0x1c,0xc0,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ec01c00 <unknown>

famax v31.2s, v31.2s, v31.2s
// CHECK-INST: famax v31.2s, v31.2s, v31.2s
// CHECK-ENCODING: [0xff,0xdf,0xbf,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0ebfdfff <unknown>

famax v31.2s, v0.2s, v0.2s
// CHECK-INST: famax v31.2s, v0.2s, v0.2s
// CHECK-ENCODING: [0x1f,0xdc,0xa0,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0ea0dc1f <unknown>

famax v0.2s, v0.2s, v0.2s
// CHECK-INST: famax v0.2s, v0.2s, v0.2s
// CHECK-ENCODING: [0x00,0xdc,0xa0,0x0e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 0ea0dc00 <unknown>

famax v31.4s, v31.4s, v31.4s
// CHECK-INST: famax v31.4s, v31.4s, v31.4s
// CHECK-ENCODING: [0xff,0xdf,0xbf,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ebfdfff <unknown>

famax v0.4s, v31.4s, v31.4s
// CHECK-INST: famax v0.4s, v31.4s, v31.4s
// CHECK-ENCODING: [0xe0,0xdf,0xbf,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ebfdfe0 <unknown>

famax v0.4s, v0.4s, v0.4s
// CHECK-INST: famax v0.4s, v0.4s, v0.4s
// CHECK-ENCODING: [0x00,0xdc,0xa0,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ea0dc00 <unknown>

famax v31.2d, v31.2d, v31.2d
// CHECK-INST: famax v31.2d, v31.2d, v31.2d
// CHECK-ENCODING: [0xff,0xdf,0xff,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4effdfff <unknown>

famax v0.2d, v0.2d, v31.2d
// CHECK-INST: famax v0.2d, v0.2d, v31.2d
// CHECK-ENCODING: [0x00,0xdc,0xff,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4effdc00 <unknown>

famax v0.2d, v0.2d, v0.2d
// CHECK-INST: famax v0.2d, v0.2d, v0.2d
// CHECK-ENCODING: [0x00,0xdc,0xe0,0x4e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 4ee0dc00 <unknown>


/// FAMIN instructions.
famin v31.4h, v31.4h, v31.4h
// CHECK-INST: famin v31.4h, v31.4h, v31.4h
// CHECK-ENCODING: [0xff,0x1f,0xdf,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2edf1fff <unknown>

famin v31.4h, v0.4h, v31.4h
// CHECK-INST: famin v31.4h, v0.4h, v31.4h
// CHECK-ENCODING: [0x1f,0x1c,0xdf,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2edf1c1f <unknown>

famin v0.4h, v0.4h, v0.4h
// CHECK-INST: famin v0.4h, v0.4h, v0.4h
// CHECK-ENCODING: [0x00,0x1c,0xc0,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2ec01c00 <unknown>

famin v31.8h, v31.8h, v31.8h
// CHECK-INST: famin v31.8h, v31.8h, v31.8h
// CHECK-ENCODING: [0xff,0x1f,0xdf,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6edf1fff <unknown>

famin v31.8h, v31.8h, v0.8h
// CHECK-INST: famin v31.8h, v31.8h, v0.8h
// CHECK-ENCODING: [0xff,0x1f,0xc0,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ec01fff <unknown>

famin v0.8h, v0.8h, v0.8h
// CHECK-INST: famin v0.8h, v0.8h, v0.8h
// CHECK-ENCODING: [0x00,0x1c,0xc0,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ec01c00 <unknown>

famin v31.2s, v31.2s, v31.2s
// CHECK-INST: famin v31.2s, v31.2s, v31.2s
// CHECK-ENCODING: [0xff,0xdf,0xbf,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2ebfdfff <unknown>

famin v31.2s, v0.2s, v0.2s
// CHECK-INST: famin v31.2s, v0.2s, v0.2s
// CHECK-ENCODING: [0x1f,0xdc,0xa0,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2ea0dc1f <unknown>

famin v0.2s, v0.2s, v0.2s
// CHECK-INST: famin v0.2s, v0.2s, v0.2s
// CHECK-ENCODING: [0x00,0xdc,0xa0,0x2e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 2ea0dc00 <unknown>

famin v31.4s, v31.4s, v31.4s
// CHECK-INST: famin v31.4s, v31.4s, v31.4s
// CHECK-ENCODING: [0xff,0xdf,0xbf,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ebfdfff <unknown>

famin v0.4s, v31.4s, v31.4s
// CHECK-INST: famin v0.4s, v31.4s, v31.4s
// CHECK-ENCODING: [0xe0,0xdf,0xbf,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ebfdfe0 <unknown>

famin v0.4s, v0.4s, v0.4s
// CHECK-INST: famin v0.4s, v0.4s, v0.4s
// CHECK-ENCODING: [0x00,0xdc,0xa0,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ea0dc00 <unknown>

famin v31.2d, v31.2d, v31.2d
// CHECK-INST: famin v31.2d, v31.2d, v31.2d
// CHECK-ENCODING: [0xff,0xdf,0xff,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6effdfff <unknown>

famin v0.2d, v0.2d, v31.2d
// CHECK-INST: famin v0.2d, v0.2d, v31.2d
// CHECK-ENCODING: [0x00,0xdc,0xff,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6effdc00 <unknown>

famin v0.2d, v0.2d, v0.2d
// CHECK-INST: famin v0.2d, v0.2d, v0.2d
// CHECK-ENCODING: [0x00,0xdc,0xe0,0x6e]
// CHECK-ERROR: instruction requires: faminmax
// CHECK-UNKNOWN: 6ee0dc00 <unknown>

Loading

0 comments on commit b23426e

Please sign in to comment.