1 .. Copyright (C) 2020-2024 Free Software Foundation, Inc.
2 Originally contributed by David Malcolm <dmalcolm@redhat.com>
4 This is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see
16 <https://www.gnu.org/licenses/>.
18 .. default-domain:: cpp
20 Using Assembly Language with libgccjit++
21 ========================================
23 libgccjit has some support for directly embedding assembler instructions.
24 This is based on GCC's support for inline ``asm`` in C code, and the
25 following assumes a familiarity with that functionality. See
26 `How to Use Inline Assembly Language in C Code <https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html>`_
27 in GCC's documentation, the "Extended Asm" section in particular.
29 These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test
30 for their presence using
34 #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS
36 Adding assembler instructions within a function
37 ***********************************************
39 .. class:: gccjit::extended_asm
41 A `gccjit::extended_asm` represents an extended ``asm`` statement: a
42 series of low-level instructions inside a function that convert inputs
45 :class:`gccjit::extended_asm` is a subclass of :class:`gccjit::object`.
46 It is a thin wrapper around the C API's :c:expr:`gcc_jit_extended_asm *`.
48 To avoid having an API entrypoint with a very large number of
49 parameters, an extended ``asm`` statement is made in stages:
50 an initial call to create the :type:`gccjit::extended_asm`,
51 followed by calls to add operands and set other properties of the
54 There are two API entrypoints for creating a :type:`gccjit::extended_asm`:
56 * :func:`gccjit::block::add_extended_asm` for an ``asm`` statement with
59 * :func:`gccjit::block::end_with_extended_asm_goto` for an ``asm goto``.
61 For example, to create the equivalent of:
63 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
64 :start-after: // Quote from here in docs/cp/topics/asm.rst: example 1: C
65 :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 1: C
68 the following API calls could be used:
70 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
71 :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 1: jit. */
72 :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 1: jit. */
75 .. warning:: When considering the numbering of operands within an
76 extended ``asm`` statement (e.g. the ``%0`` and ``%1``
77 above), the equivalent to the C syntax is followed i.e. all
78 output operands, then all input operands, regardless of
79 what order the calls to
80 :func:`gccjit::extended_asm::add_output_operand` and
81 :func:`gccjit::extended_asm::add_input_operand` were made in.
83 As in the C syntax, operands can be given symbolic names to avoid having
84 to number them. For example, to create the equivalent of:
86 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
87 :start-after: // Quote from here in docs/cp/topics/asm.rst: example 2: C
88 :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 2: C
91 the following API calls could be used:
93 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
94 :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 2: jit. */
95 :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 2: jit. */
98 .. function:: extended_asm \
99 gccjit::block::add_extended_asm (const std::string &asm_template,\
100 gccjit::location loc = location ())
102 Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
103 with no control flow (i.e. without the ``goto`` qualifier).
105 The parameter ``asm_template`` corresponds to the `AssemblerTemplate`
106 within C's extended ``asm`` syntax. It must be non-NULL. The call takes
107 a copy of the underlying string, so it is valid to pass in a pointer to
110 .. function:: extended_asm\
111 gccjit::block::end_with_extended_asm_goto (const std::string &asm_template,\
112 std::vector<block> goto_blocks,\
113 block *fallthrough_block,\
114 location loc = location ())
116 Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
117 that may perform jumps, and use it to terminate the given block.
118 This is equivalent to the ``goto`` qualifier in C's extended ``asm``
121 For example, to create the equivalent of:
123 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
124 :start-after: // Quote from here in docs/cp/topics/asm.rst: example 3b: C
125 :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 3b: C
128 the following API calls could be used:
130 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
131 :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 3: jit. */
132 :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 3: jit. */
135 here referencing a :type:`gcc_jit_block` named "carry".
137 ``num_goto_blocks`` corresponds to the ``GotoLabels`` parameter within C's
138 extended ``asm`` syntax. The block names can be referenced within the
141 ``fallthrough_block`` can be NULL. If non-NULL, it specifies the block
142 to fall through to after the statement.
144 .. note:: This is needed since each :type:`gccjit::block` must have a
145 single exit point, as a basic block: you can't jump from the
146 middle of a block. A "goto" is implicitly added after the
147 asm to handle the fallthrough case, which is equivalent to what
148 would have happened in the C case.
150 .. function:: gccjit::extended_asm &\
151 gccjit::extended_asm::set_volatile_flag (bool flag)
153 Set whether the :type:`gccjit::extended_asm` has side-effects, equivalent to the
154 `volatile <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile>`_
155 qualifier in C's extended asm syntax.
157 For example, to create the equivalent of:
161 asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
162 "shl $32, %%rdx\n\t" // Shift the upper bits left.
163 "or %%rdx, %0" // 'Or' in the lower bits.
168 the following API calls could be used:
170 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
171 :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 4: jit. */
172 :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 4: jit. */
175 where the :type:`gccjit::extended_asm` is flagged as volatile.
177 .. function:: gccjit::extended_asm &\
178 gccjit::extended_asm::set_inline_flag (bool flag)
180 Set the equivalent of the
181 `inline <https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm>`_
182 qualifier in C's extended ``asm`` syntax.
184 .. function:: gccjit::extended_asm&\
185 gccjit::extended_asm::add_output_operand (const std::string &asm_symbolic_name,\
186 const std::string &constraint,\
189 Add an output operand to the extended ``asm`` statement. See the
190 `Output Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>`_
191 section of the documentation of the C syntax.
193 ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of
194 C's extended ``asm`` syntax, and specifies the symbolic name for the operand.
195 See the overload below for an alternative that does not supply a symbolic
198 ``constraint`` corresponds to the ``constraint`` component of C's extended
201 ``dest`` corresponds to the ``cvariablename`` component of C's extended
206 // Example with a symbolic name ("aIndex"), the equivalent of:
207 // : [aIndex] "=r" (index)
208 ext_asm.add_output_operand ("aIndex", "=r", index);
210 This function can't be called on an ``asm goto`` as such instructions can't
211 have outputs; see the
212 `Goto Labels <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels>`_
213 section of GCC's "Extended Asm" documentation.
215 .. function:: gccjit::extended_asm&\
216 gccjit::extended_asm::add_output_operand (const std::string &constraint,\
219 As above, but don't supply a symbolic name for the operand.
223 // Example without a symbolic name, the equivalent of:
225 ext_asm.add_output_operand ("=r", dst);
227 .. function:: gccjit::extended_asm&\
228 gccjit::extended_asm::add_input_operand (const std::string &asm_symbolic_name, \
229 const std::string &constraint, \
232 Add an input operand to the extended ``asm`` statement. See the
233 `Input Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands>`_
234 section of the documentation of the C syntax.
236 ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component
237 of C's extended ``asm`` syntax. See the overload below for an alternative
238 that does not supply a symbolic name.
240 ``constraint`` corresponds to the ``constraint`` component of C's extended
243 ``src`` corresponds to the ``cexpression`` component of C's extended
248 // Example with a symbolic name ("aMask"), the equivalent of:
249 // : [aMask] "r" (Mask)
250 ext_asm.add_input_operand ("aMask", "r", mask);
252 .. function:: gccjit::extended_asm&\
253 gccjit::extended_asm::add_input_operand (const std::string &constraint,\
256 As above, but don't supply a symbolic name for the operand.
260 // Example without a symbolic name, the equivalent of:
262 ext_asm.add_input_operand ("r", src);
264 .. function:: gccjit::extended_asm&\
265 gccjit::extended_asm::add_clobber (const std::string &victim)
267 Add `victim` to the list of registers clobbered by the extended ``asm``
269 `Clobbers and Scratch Registers <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#>`_
270 section of the documentation of the C syntax.
272 Statements with multiple clobbers will require multiple calls, one per
279 ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");
282 Adding top-level assembler statements
283 *************************************
285 In addition to creating extended ``asm`` instructions within a function,
286 there is support for creating "top-level" assembler statements, outside
290 gccjit::context::add_top_level_asm (const char *asm_stmts,\
291 gccjit::location loc = location ())
293 Create a set of top-level asm statements, analogous to those created
294 by GCC's "basic" ``asm`` syntax in C at file scope.
296 For example, to create the equivalent of:
298 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
299 :start-after: // Quote from here in docs/cp/topics/asm.rst: example 5: C
300 :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 5: C
303 the following API calls could be used:
305 .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
306 :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 5: jit. */
307 :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 5: jit. */