diff options
author | Andi Kleen <ak@linux.intel.com> | 2024-01-24 04:27:13 -0800 |
---|---|---|
committer | Andi Kleen <ak@linux.intel.com> | 2024-06-11 09:52:28 -0700 |
commit | 53ac88cedf9348b0139fa92c3257b877694f6194 (patch) | |
tree | 5525ad215ef852168853d3f5ffa76a710940c237 /gcc/doc | |
parent | 6ef8c905e0064c4dfb7ca302355fc20cb96b147b (diff) | |
download | gcc-53ac88cedf9348b0139fa92c3257b877694f6194.zip gcc-53ac88cedf9348b0139fa92c3257b877694f6194.tar.gz gcc-53ac88cedf9348b0139fa92c3257b877694f6194.tar.bz2 |
C++: Support constexpr strings for asm statements
Some programing styles use a lot of inline assembler, and it is common
to use very complex preprocessor macros to generate the assembler
strings for the asm statements. In C++ there would be a typesafe alternative
using templates and constexpr to generate the assembler strings, but
unfortunately the asm statement requires plain string literals, so this
doesn't work.
This patch modifies the C++ parser to accept strings generated by
constexpr instead of just plain strings. This requires new syntax
because e.g. asm("..." : "r" (expr)) would be ambigious with a function
call. I chose () to make it unique. For example now you can write
constexpr const char *genasm() { return "insn"; }
constexpr const char *genconstraint() { return "r"; }
asm(genasm() :: (genconstraint()) (input));
The constexpr strings are allowed for the asm template, the
constraints and the clobbers (every time current asm accepts a string)
This version allows the same constexprs as C++26 static_assert,
following Jakub's suggestion.
The drawback of this scheme is that the constexpr doesn't have
full control over the input/output/clobber lists, but that can be
usually handled with a switch statement. One could imagine
more flexible ways to handle that, for example supporting constexpr
vectors for the clobber list, or similar. But even without
that it is already useful.
Bootstrapped and full test on x86_64-linux.
gcc/c-family/ChangeLog:
* c-cppbuiltin.cc (c_cpp_builtins): Define __GXX_CONSTEXPR_ASM__
gcc/cp/ChangeLog:
* parser.cc (cp_parser_asm_string_expression): New function
to handle constexpr strings for asm.
(cp_parser_asm_definition): Use cp_parser_asm_string_expression.
(cp_parser_yield_expression): Dito.
(cp_parser_asm_specification_opt): Dito.
(cp_parser_asm_operand_list): Dito.
(cp_parser_asm_clobber_list): Dito.
gcc/ChangeLog:
* doc/extend.texi: Document constexpr asm.
gcc/testsuite/ChangeLog:
* g++.dg/ext/asm11.C: Adjust to new error message.
* g++.dg/ext/asm9.C: Dito.
* g++.dg/parse/asm1.C: Dito.
* g++.dg/parse/asm2.C: Dito.
* g++.dg/parse/asm3.C: Dito.
* g++.dg/cpp1z/constexpr-asm-1.C: New test.
* g++.dg/cpp1z/constexpr-asm-2.C: New test.
* g++.dg/cpp1z/constexpr-asm-3.C: New test.
Diffstat (limited to 'gcc/doc')
-rw-r--r-- | gcc/doc/extend.texi | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 799a365..17e26c5 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -10700,14 +10700,30 @@ contain any instructions recognized by the assembler, including directives. GCC does not parse the assembler instructions themselves and does not know what they mean or even whether they are valid assembler input. -You may place multiple assembler instructions together in a single @code{asm} -string, separated by the characters normally used in assembly code for the -system. A combination that works in most places is a newline to break the +You may place multiple assembler instructions together in a single @code{asm} +string, separated by the characters normally used in assembly code for the +system. A combination that works in most places is a newline to break the line, plus a tab character (written as @samp{\n\t}). -Some assemblers allow semicolons as a line separator. However, -note that some assembler dialects use semicolons to start a comment. +Some assemblers allow semicolons as a line separator. However, +note that some assembler dialects use semicolons to start a comment. @end table +@node asm constexprs +With gnu++11 or later the string can also be a compile time constant expression +inside parens. The constant expression can return a string or a container +with data and size members, following similar rules as C++26 @code{static_assert} +message. Any string is converted to the character set of the source code. +When this feature is available the @code{__GXX_CONSTEXPR_ASM__} cpp symbol is defined. + +@example +constexpr const char *genfoo() @{ return "foo"; @} + +void function() +@{ + asm((genfoo())); +@} +@end example + @subsubheading Remarks Using extended @code{asm} (@pxref{Extended Asm}) typically produces smaller, safer, and more efficient code, and in most cases it is a @@ -10850,20 +10866,27 @@ perform a jump to one of the labels listed in the @var{GotoLabels}. @item AssemblerTemplate This is a literal string that is the template for the assembler code. It is a combination of fixed text and tokens that refer to the input, output, -and goto parameters. @xref{AssemblerTemplate}. +and goto parameters. @xref{AssemblerTemplate}. With gnu++11 or later it can +also be a constant expression inside parens (see @ref{asm constexprs}). @item OutputOperands A comma-separated list of the C variables modified by the instructions in the @var{AssemblerTemplate}. An empty list is permitted. @xref{OutputOperands}. +With gnu++11 or later the strings can also be constant expressions inside parens +(see @ref{asm constexprs}) @item InputOperands A comma-separated list of C expressions read by the instructions in the @var{AssemblerTemplate}. An empty list is permitted. @xref{InputOperands}. +With gnu++11 or later the strings can also be constant expressions inside parens +(see @ref{asm constexprs}) @item Clobbers A comma-separated list of registers or other values changed by the @var{AssemblerTemplate}, beyond those listed as outputs. An empty list is permitted. @xref{Clobbers and Scratch Registers}. +With gnu++11 or later the strings can also be constant expressions inside parens +(see @ref{asm constexprs}) @item GotoLabels When you are using the @code{goto} form of @code{asm}, this section contains |