Yury Khrustalev <[email protected]> writes:
> From: Szabolcs Nagy <[email protected]>
>
> Add instructions for the Guarded Control Stack extension.
>
> GCSSS1 and GCSSS2 are modelled as a single GCSSS unspec, because they
> are always used together in the compiler.
>
> Before GCSPOPM and GCSSS2 an extra "mov xn, 0" is added to clear the
> output register, this is needed to get reasonable result when GCS is
> disabled, when the instructions are NOPs. Since the instructions are
> expected to be used behind runtime feature checks, this is mainly
> relevant if GCS can be disabled asynchronously.
>
> The output of GCSPOPM is usually not needed, so a separate gcspopm_xzr
> was added to model that. Did not do the same for GCSSS as it is a less
> common operation.
>
> The used mnemonics do not depend on updated assembler since these
> instructions can be used without new -march setting behind a runtime
> check.
>
> Reading the GCSPR is modelled as unspec_volatile so it does not get
> reordered wrt the other instructions changing the GCSPR.
Sorry to be awkward, but I think we should still use one define_insn
per instruction, with no embedded moves. E.g.:
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64.md (aarch64_load_gcspr): New.
> (aarch64_gcspopm): New.
> (aarch64_gcspopm_xzr): New.
> (aarch64_gcsss): New.
> ---
> gcc/config/aarch64/aarch64.md | 35 +++++++++++++++++++++++++++++++++++
> 1 file changed, 35 insertions(+)
>
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 43bed0ce10f..e4e11e35b5b 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -382,6 +382,9 @@ (define_c_enum "unspecv" [
> UNSPECV_BTI_J ; Represent BTI j.
> UNSPECV_BTI_JC ; Represent BTI jc.
> UNSPECV_CHKFEAT ; Represent CHKFEAT X16.
> + UNSPECV_GCSPR ; Represent MRS Xn, GCSPR_EL0
> + UNSPECV_GCSPOPM ; Represent GCSPOPM.
> + UNSPECV_GCSSS ; Represent GCSSS1 and GCSSS2.
> UNSPECV_TSTART ; Represent transaction start.
> UNSPECV_TCOMMIT ; Represent transaction commit.
> UNSPECV_TCANCEL ; Represent transaction cancel.
> @@ -8321,6 +8324,38 @@ (define_insn "aarch64_chkfeat"
> "hint\\t40 // chkfeat x16"
> )
>
> +;; Guarded Control Stack (GCS) instructions
> +(define_insn "aarch64_load_gcspr"
> + [(set (match_operand:DI 0 "register_operand" "=r")
> + (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPR))]
> + ""
> + "mrs\\t%0, s3_3_c2_c5_1 // gcspr_el0"
> + [(set_attr "type" "mrs")]
> +)
> +
> +(define_insn "aarch64_gcspopm"
> + [(set (match_operand:DI 0 "register_operand" "=r")
> + (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPOPM))]
> + ""
> + "mov\\t%0, 0\;sysl\\t%0, #3, c7, c7, #1 // gcspopm"
> + [(set_attr "length" "8")]
> +)
...this would be:
(define_insn "aarch64_gcspopm"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
UNSPECV_GCSPOPM))]
""
"sysl\\t%0, #3, c7, c7, #1 // gcspopm"
)
with the code that emits the instruction first emitting a zeroing
of operand 1.
Thanks,
Richard
> +
> +(define_insn "aarch64_gcspopm_xzr"
> + [(unspec_volatile [(const_int 0)] UNSPECV_GCSPOPM)]
> + ""
> + "sysl\\txzr, #3, c7, c7, #1 // gcspopm"
> +)
> +
> +(define_insn "aarch64_gcsss"
> + [(set (match_operand:DI 0 "register_operand" "=r")
> + (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
> + UNSPECV_GCSSS))]
> + ""
> + "sys\\t#3, c7, c7, #2, %1 // gcsss1\;mov\\t%0, 0\;sysl\\t%0, #3, c7, c7,
> #3 // gcsss2"
> + [(set_attr "length" "12")]
> +)
> +
> ;; AdvSIMD Stuff
> (include "aarch64-simd.md")