From 5db783a3218c48d844cdd92d63f342d8cfedf20e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 30 Apr 2025 14:09:58 -0700 Subject: [PATCH 1/2] Make unsupported asm! general for all macros This rule doesn't just apply to `asm!` but all of the macros. --- src/inline-assembly.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inline-assembly.md b/src/inline-assembly.md index cd0d41d3c..585274b96 100644 --- a/src/inline-assembly.md +++ b/src/inline-assembly.md @@ -18,7 +18,7 @@ Support for inline assembly is stable on the following architectures: - LoongArch - s390x -The compiler will emit an error if `asm!` is used on an unsupported target. +The compiler will emit an error if an assembly macro is used on an unsupported target. r[asm.example] ## Example From 4d1e09576afdd9a017256f43198fa35e4e5ffd26 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 30 Apr 2025 14:39:19 -0700 Subject: [PATCH 2/2] Use the reference grammar for inline assembly This updates the inline assembly grammar description to use the grammar style used in the rest of the reference, which also supports diagrams. I also appreciate that this is more precisely defined using existing grammar productions. I realize that this is not as compressed as before. If that is a real problem, then I think we can look at improving that throughout the reference in general. I did not change other parts of the chapter even though they mention things like `in() `. I could rewrite those, though I'm not sure if that would help a lot. There are restrictions not captured in the grammar which are explained in the text. For example, global_asm and naked_asm do not allow clobber_abi. I think I'm fine with the grammar not including everything since there isn't the concept of an AST here. This is not a direct translation because the old grammar was not entirely precise or match with the existing grammar. This also renames the rules to use PascalCase. The exhaustive list of differences: Removed: - Removed the `asm`, `naked_asm` and `global_asm` rules since I don't think they really added anything, and the macro names aren't exactly part of the grammar being described here. Instead it is just `AsmArgs`. - Removed the explicit `_` since that is now a normal Expression. New: - FormatString added MacroInvocation because that is supported. - Defined AbiString. - Defined RegisterClass. - Defined ExplicitRegister. Changed: - Renamed option and options to AsmOption and AsmOptions (since our namespace is global). - Clarified the meaning of "ident". - ArgName allows ident, keywords, and raw identifiers. - RegisterClass allows ident, keywords, but NOT raw identifiers. - Split DirSpec into two, since there is a separate `Expression => Expression` syntax that is only valid for a subset of DirSpecs. - Clarified that `sym` takes a PathExpression. - Clarified that label's block doesn't allow inner attributes. - Fixed sym/const/label which weren't properly quoted. - Fixed some ambiguous precedence like alternation in reg_operand. --- src/inline-assembly.md | 75 +++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/src/inline-assembly.md b/src/inline-assembly.md index 585274b96..4e6d03dea 100644 --- a/src/inline-assembly.md +++ b/src/inline-assembly.md @@ -46,21 +46,66 @@ assert_eq!(x, 4 * 6); r[asm.syntax] ## Syntax -The following ABNF specifies the general syntax: - -```text -format_string := STRING_LITERAL / RAW_STRING_LITERAL -dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout" -reg_spec := / "\"" "\"" -operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" -reg_operand := [ident "="] dir_spec "(" reg_spec ")" operand_expr / sym / const / label -clobber_abi := "clobber_abi(" *("," ) [","] ")" -option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" -options := "options(" option *("," option) [","] ")" -operand := reg_operand / clobber_abi / options -asm := "asm!(" format_string *("," format_string) *("," operand) [","] ")" -naked_asm := "naked_asm!(" format_string *("," format_string) *("," operand) [","] ")" -global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")" +The following grammar specifies the arguments that can be passed to the `asm!`, `global_asm!` and `naked_asm!` macros. + +```grammar,assembly +@root AsmArgs -> FormatString (`,` FormatString)* (`,` Operand)* `,`? + +FormatString -> StringLiteral | MacroInvocation + +StringLiteral -> STRING_LITERAL | RAW_STRING_LITERAL + +Operand -> + ClobberAbi + | AsmOptions + | RegOperand + +ClobberAbi -> `clobber_abi` `(` AbiString (`,` AbiString)* `,`? `)` + +AbiString -> StringLiteral + +AsmOptions -> + `options` `(` AsmOption (`,` AsmOption)* `,`? `)` + +AsmOption -> + `pure` + | `nomem` + | `readonly` + | `preserves_flags` + | `noreturn` + | `nostack` + | `att_syntax` + | `raw` + +RegOperand -> (ArgName `=`)? + ( + DirSpec `(` RegSpec `)` Expression + | DualDirSpec `(` RegSpec `)` DualDirSpecExpression + | `sym` PathExpression + | `const` Expression + | `label` BlockExpression _no [InnerAttribute]s_ + ) + +ArgName -> IDENTIFIER_OR_KEYWORD | RAW_IDENTIFIER + +DualDirSpecExpression -> + Expression + | Expression `=>` Expression + +RegSpec -> RegisterClass | ExplicitRegister + +RegisterClass -> IDENTIFIER_OR_KEYWORD + +ExplicitRegister -> STRING_LITERAL + +DirSpec -> + `in` + | `out` + | `lateout` + +DualDirSpec -> + `inout` + | `inlateout` ``` r[asm.scope]