Skip to content

Commit 17baba9

Browse files
[llvm][AArch64][Assembly] Implement support to read/write FPMR (#69618)
Also add Read only registers: ID_AA64FPFR0_EL1 ID_AA64ISAR3_EL1 This is based on this documentation: https://developer.arm.com/documentation/ddi0602/2023-09 Co-authored-by: Caroline Concatto <[email protected]>
1 parent 6d53fde commit 17baba9

File tree

8 files changed

+56
-2
lines changed

8 files changed

+56
-2
lines changed

llvm/include/llvm/TargetParser/AArch64TargetParser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ enum ArchExtKind : unsigned {
159159
AEK_RASv2 = 55, // FEAT_RASv2
160160
AEK_ITE = 56, // FEAT_ITE
161161
AEK_GCS = 57, // FEAT_GCS
162-
AEK_NUM_EXTENSIONS = AEK_GCS + 1
162+
AEK_FPMR = 58, // FEAT_FPMR
163+
AEK_NUM_EXTENSIONS
163164
};
164165
using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
165166
// clang-format on
@@ -267,6 +268,7 @@ inline constexpr ExtensionInfo Extensions[] = {
267268
{"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_INIT, "", 0},
268269
{"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550},
269270
{"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0},
271+
{"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0},
270272
// Special cases
271273
{"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority},
272274
};

llvm/lib/Target/AArch64/AArch64.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ def FeatureCCPP : SubtargetFeature<"ccpp", "HasCCPP",
127127
def FeatureSVE : SubtargetFeature<"sve", "HasSVE", "true",
128128
"Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", [FeatureFullFP16]>;
129129

130+
def FeatureFPMR : SubtargetFeature<"fpmr", "HasFPMR", "true",
131+
"Enable FPMR Register (FEAT_FPMR)">;
132+
130133
// This flag is currently still labeled as Experimental, but when fully
131134
// implemented this should tell the compiler to use the zeroing pseudos to
132135
// benefit from the reverse instructions (e.g. SUB vs SUBR) if the inactive

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ def HasSME2 : Predicate<"Subtarget->hasSME2()">,
160160
AssemblerPredicateWithAll<(all_of FeatureSME2), "sme2">;
161161
def HasSME2p1 : Predicate<"Subtarget->hasSME2p1()">,
162162
AssemblerPredicateWithAll<(all_of FeatureSME2p1), "sme2p1">;
163+
def HasFPMR : Predicate<"Subtarget->hasFPMR()">,
164+
AssemblerPredicateWithAll<(all_of FeatureFPMR), "fpmr">;
163165

164166
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
165167
// they should be enabled if either has been specified.

llvm/lib/Target/AArch64/AArch64SystemOperands.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ def : ROSysReg<"ID_AA64AFR1_EL1", 0b11, 0b000, 0b0000, 0b0101, 0b101>;
743743
def : ROSysReg<"ID_AA64ISAR0_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b000>;
744744
def : ROSysReg<"ID_AA64ISAR1_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b001>;
745745
def : ROSysReg<"ID_AA64ISAR2_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b010>;
746+
def : ROSysReg<"ID_AA64ISAR3_EL1", 0b11, 0b000, 0b0000, 0b0110, 0b011>;
746747
def : ROSysReg<"ID_AA64MMFR0_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b000>;
747748
def : ROSysReg<"ID_AA64MMFR1_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b001>;
748749
def : ROSysReg<"ID_AA64MMFR2_EL1", 0b11, 0b000, 0b0000, 0b0111, 0b010>;
@@ -1927,3 +1928,12 @@ def : RWSysReg<"PFAR_EL2", 0b11, 0b100, 0b0110, 0b0000, 0b101>;
19271928
// v9.4a Exception-based event profiling (FEAT_EBEP)
19281929
// Op0 Op1 CRn CRm Op2
19291930
def : RWSysReg<"PM", 0b11, 0b000, 0b0100, 0b0011, 0b001>;
1931+
1932+
// 2023 ISA Extension
1933+
// AArch64 Floating-point Mode Register controls behaviors of the FP8
1934+
// instructions (FEAT_FPMR)
1935+
let Requires = [{ {AArch64::FeatureFPMR} }] in {
1936+
// Op0 Op1 CRn CRm Op2
1937+
def : ROSysReg<"ID_AA64FPFR0_EL1", 0b11, 0b000, 0b0000, 0b0100, 0b111>;
1938+
def : RWSysReg<"FPMR", 0b11, 0b011, 0b0100, 0b0100, 0b010>;
1939+
}

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3638,6 +3638,7 @@ static const struct Extension {
36383638
{"sb", {AArch64::FeatureSB}},
36393639
{"ssbs", {AArch64::FeatureSSBS}},
36403640
{"tme", {AArch64::FeatureTME}},
3641+
{"fpmr", {AArch64::FeatureFPMR}},
36413642
};
36423643

36433644
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fpmr < %s \
2+
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
3+
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
4+
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
5+
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fpmr < %s \
6+
// RUN: | llvm-objdump -d --mattr=+fpmr - | FileCheck %s --check-prefix=CHECK-INST
7+
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fpmr < %s \
8+
// RUN: | llvm-objdump --mattr=-fpmr -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
9+
10+
// --------------------------------------------------------------------------//
11+
// read
12+
13+
mrs x3, FPMR
14+
// CHECK-INST: mrs x3, FPMR
15+
// CHECK-ENCODING: [0x43,0x44,0x3b,0xd5]
16+
// CHECK-ERROR: expected readable system register
17+
// CHECK-UNKNOWN: d53b4443 mrs x3, S3_3_C4_C4_2
18+
19+
mrs x3, ID_AA64FPFR0_EL1
20+
// CHECK-INST: mrs x3, ID_AA64FPFR0_EL1
21+
// CHECK-ENCODING: [0xe3,0x04,0x38,0xd5]
22+
// CHECK-ERROR: expected readable system register
23+
// CHECK-UNKNOWN: d53804e3 mrs x3, S3_0_C0_C4_7
24+
25+
// --------------------------------------------------------------------------//
26+
// write
27+
28+
msr FPMR, x3
29+
// CHECK-INST: msr FPMR, x3
30+
// CHECK-ENCODING: [0x43,0x44,0x1b,0xd5]
31+
// CHECK-ERROR: expected writable system register or pstate
32+
// CHECK-UNKNOWN: d51b4443 msr S3_3_C4_C4_2, x3

llvm/test/MC/AArch64/arm64-system-encoding.s

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ foo:
336336
mrs x3, ID_AA64ISAR0_EL1
337337
mrs x3, ID_AA64ISAR1_EL1
338338
mrs x3, ID_AA64ISAR2_EL1
339+
mrs x3, ID_AA64ISAR3_EL1
339340
mrs x3, ID_AA64MMFR0_EL1
340341
mrs x3, ID_AA64MMFR1_EL1
341342
mrs x3, ID_AA64MMFR2_EL1
@@ -556,6 +557,7 @@ foo:
556557
; CHECK: mrs x3, ID_AA64ISAR0_EL1 ; encoding: [0x03,0x06,0x38,0xd5]
557558
; CHECK: mrs x3, ID_AA64ISAR1_EL1 ; encoding: [0x23,0x06,0x38,0xd5]
558559
; CHECK: mrs x3, ID_AA64ISAR2_EL1 ; encoding: [0x43,0x06,0x38,0xd5]
560+
; CHECK: mrs x3, ID_AA64ISAR3_EL1 ; encoding: [0x63,0x06,0x38,0xd5]
559561
; CHECK: mrs x3, ID_AA64MMFR0_EL1 ; encoding: [0x03,0x07,0x38,0xd5]
560562
; CHECK: mrs x3, ID_AA64MMFR1_EL1 ; encoding: [0x23,0x07,0x38,0xd5]
561563
; CHECK: mrs x3, ID_AA64MMFR2_EL1 ; encoding: [0x43,0x07,0x38,0xd5]

llvm/unittests/TargetParser/TargetParserTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1731,7 +1731,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
17311731
AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
17321732
AArch64::AEK_RCPC3, AArch64::AEK_THE, AArch64::AEK_D128,
17331733
AArch64::AEK_LSE128, AArch64::AEK_SPECRES2, AArch64::AEK_RASv2,
1734-
AArch64::AEK_ITE, AArch64::AEK_GCS,
1734+
AArch64::AEK_ITE, AArch64::AEK_GCS, AArch64::AEK_FPMR,
17351735
};
17361736

17371737
std::vector<StringRef> Features;
@@ -1804,6 +1804,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
18041804
EXPECT_TRUE(llvm::is_contained(Features, "+specres2"));
18051805
EXPECT_TRUE(llvm::is_contained(Features, "+ite"));
18061806
EXPECT_TRUE(llvm::is_contained(Features, "+gcs"));
1807+
EXPECT_TRUE(llvm::is_contained(Features, "+fpmr"));
18071808

18081809
// Assuming we listed every extension above, this should produce the same
18091810
// result. (note that AEK_NONE doesn't have a name so it won't be in the
@@ -1927,6 +1928,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
19271928
{"predres2", "nopredres2", "+specres2", "-specres2"},
19281929
{"rasv2", "norasv2", "+rasv2", "-rasv2"},
19291930
{"gcs", "nogcs", "+gcs", "-gcs"},
1931+
{"fpmr", "nofpmr", "+fpmr", "-fpmr"},
19301932
};
19311933

19321934
for (unsigned i = 0; i < std::size(ArchExt); i++) {

0 commit comments

Comments
 (0)