From 946af489d2f7a9469144dbf2e6bdfada121a7dea Mon Sep 17 00:00:00 2001 From: Jonathan Thackray Date: Fri, 30 May 2025 11:46:00 +0100 Subject: [PATCH] [AArch64] Fix `GCS{PUSHX|POPCX|POPX}` instrs to take an optional register The Arm Archicture Reference Manual (DDI 0487K.a) says that: * `GCSPUSHX` * `GCSPOPCX` * `GCSPOPX` instructions, which are `SYS` aliases, can take an optional register, e.g. `GCSPUSHX {}` Fix the code and tests to allow this to be encoded. --- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 21 +++++++++---------- llvm/test/MC/AArch64/armv9.4a-gcs.s | 12 +++++++++++ .../MC/Disassembler/AArch64/armv9.4a-gcs.txt | 9 ++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 72445172059bf..b1ab0175b531f 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -1537,16 +1537,6 @@ def : TokenAlias<"IALL", "iall">; // ARMv9.4-A Guarded Control Stack -class GCSNoOp op2, string mnemonic> - : SimpleSystemI<0, (ins), mnemonic, "">, Sched<[]> { - let Inst{20-8} = 0b0100001110111; - let Inst{7-5} = op2; - let Predicates = [HasGCS]; -} -def GCSPUSHX : GCSNoOp<0b100, "gcspushx">; -def GCSPOPCX : GCSNoOp<0b101, "gcspopcx">; -def GCSPOPX : GCSNoOp<0b110, "gcspopx">; - class GCSRtIn op1, bits<3> op2, string mnemonic, list pattern = []> : RtSystemI<0, (outs), (ins GPR64:$Rt), mnemonic, "\t$Rt", pattern> { @@ -1560,8 +1550,17 @@ class GCSRtIn op1, bits<3> op2, string mnemonic, let mayStore = 1, mayLoad = 1 in def GCSSS1 : GCSRtIn<0b011, 0b010, "gcsss1">; -let mayStore = 1 in + +let mayStore = 1 in { def GCSPUSHM : GCSRtIn<0b011, 0b000, "gcspushm">; +def GCSPUSHX : GCSRtIn<0b000, 0b100, "gcspushx">; +def GCSPOPCX : GCSRtIn<0b000, 0b101, "gcspopcx">; +def GCSPOPX : GCSRtIn<0b000, 0b110, "gcspopx">; +} + +def GCSPUSHX_NoOp : InstAlias<"gcspushx", (GCSPUSHX XZR)>, Requires<[HasGCS]>; // Rt defaults to XZR if absent +def GCSPOPCX_NoOp : InstAlias<"gcspopcx", (GCSPOPCX XZR)>, Requires<[HasGCS]>; // Rt defaults to XZR if absent +def GCSPOPX_NoOp : InstAlias<"gcspopx", (GCSPOPX XZR)>, Requires<[HasGCS]>; // Rt defaults to XZR if absent class GCSRtOut op1, bits<3> op2, string mnemonic, list pattern = []> diff --git a/llvm/test/MC/AArch64/armv9.4a-gcs.s b/llvm/test/MC/AArch64/armv9.4a-gcs.s index b4af9b5dcb10c..b4b1baba2b788 100644 --- a/llvm/test/MC/AArch64/armv9.4a-gcs.s +++ b/llvm/test/MC/AArch64/armv9.4a-gcs.s @@ -113,3 +113,15 @@ gcspopcx gcspopx // CHECK: gcspopx // encoding: [0xdf,0x77,0x08,0xd5] // ERROR-NO-GCS: [[@LINE-2]]:1: error: instruction requires: gcs + +gcspushx x3 +// CHECK: gcspushx x3 // encoding: [0x83,0x77,0x08,0xd5] +// ERROR-NO-GCS: [[@LINE-2]]:1: error: instruction requires: gcs + +gcspopcx x3 +// CHECK: gcspopcx x3 // encoding: [0xa3,0x77,0x08,0xd5] +// ERROR-NO-GCS: [[@LINE-2]]:1: error: instruction requires: gcs + +gcspopx x3 +// CHECK: gcspopx x3 // encoding: [0xc3,0x77,0x08,0xd5] +// ERROR-NO-GCS: [[@LINE-2]]:1: error: instruction requires: gcs diff --git a/llvm/test/MC/Disassembler/AArch64/armv9.4a-gcs.txt b/llvm/test/MC/Disassembler/AArch64/armv9.4a-gcs.txt index 512f4027d9761..7ad0931d505f5 100644 --- a/llvm/test/MC/Disassembler/AArch64/armv9.4a-gcs.txt +++ b/llvm/test/MC/Disassembler/AArch64/armv9.4a-gcs.txt @@ -88,3 +88,12 @@ [0xdf,0x77,0x08,0xd5] // CHECK: gcspopx + +[0x83,0x77,0x08,0xd5] +// CHECK: gcspushx x3 + +[0xa3,0x77,0x08,0xd5] +// CHECK: gcspopcx x3 + +[0xc3,0x77,0x08,0xd5] +// CHECK: gcspopx x3