1.. Copyright (C) 2020-2022 Free Software Foundation, Inc. 2 Originally contributed by David Malcolm <dmalcolm@redhat.com> 3 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. 8 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. 13 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/>. 17 18.. default-domain:: cpp 19 20Using Assembly Language with libgccjit++ 21======================================== 22 23libgccjit has some support for directly embedding assembler instructions. 24This is based on GCC's support for inline ``asm`` in C code, and the 25following 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>`_ 27in GCC's documentation, the "Extended Asm" section in particular. 28 29These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test 30for their presence using 31 32 .. code-block:: c 33 34 #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS 35 36Adding assembler instructions within a function 37*********************************************** 38 39.. class:: gccjit::extended_asm 40 41 A `gccjit::extended_asm` represents an extended ``asm`` statement: a 42 series of low-level instructions inside a function that convert inputs 43 to outputs. 44 45 :class:`gccjit::extended_asm` is a subclass of :class:`gccjit::object`. 46 It is a thin wrapper around the C API's :c:type:`gcc_jit_extended_asm *`. 47 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 52 statement. 53 54 There are two API entrypoints for creating a :type:`gccjit::extended_asm`: 55 56 * :func:`gccjit::block::add_extended_asm` for an ``asm`` statement with 57 no control flow, and 58 59 * :func:`gccjit::block::end_with_extended_asm_goto` for an ``asm goto``. 60 61 For example, to create the equivalent of: 62 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 66 :language: c 67 68 the following API calls could be used: 69 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. */ 73 :language: c 74 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. 82 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: 85 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 89 :language: c 90 91 the following API calls could be used: 92 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. */ 96 :language: c 97 98.. function:: extended_asm \ 99 gccjit::block::add_extended_asm (const std::string &asm_template,\ 100 gccjit::location loc = location ()) 101 102 Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement 103 with no control flow (i.e. without the ``goto`` qualifier). 104 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 108 an on-stack buffer. 109 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 ()) 115 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`` 119 syntax. 120 121 For example, to create the equivalent of: 122 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 126 :language: c 127 128 the following API calls could be used: 129 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. */ 133 :language: c 134 135 here referencing a :type:`gcc_jit_block` named "carry". 136 137 ``num_goto_blocks`` corresponds to the ``GotoLabels`` parameter within C's 138 extended ``asm`` syntax. The block names can be referenced within the 139 assembler template. 140 141 ``fallthrough_block`` can be NULL. If non-NULL, it specifies the block 142 to fall through to after the statement. 143 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. 149 150.. function:: gccjit::extended_asm &\ 151 gccjit::extended_asm::set_volatile_flag (bool flag) 152 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. 156 157 For example, to create the equivalent of: 158 159 .. code-block:: c 160 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. 164 : "=a" (msr) 165 : 166 : "rdx"); 167 168 the following API calls could be used: 169 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. */ 173 :language: c 174 175 where the :type:`gccjit::extended_asm` is flagged as volatile. 176 177.. function:: gccjit::extended_asm &\ 178 gccjit::extended_asm::set_inline_flag (bool flag) 179 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. 183 184.. function:: gccjit::extended_asm&\ 185 gccjit::extended_asm::add_output_operand (const std::string &asm_symbolic_name,\ 186 const std::string &constraint,\ 187 gccjit::lvalue dest) 188 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. 192 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 196 name. 197 198 ``constraint`` corresponds to the ``constraint`` component of C's extended 199 ``asm`` syntax. 200 201 ``dest`` corresponds to the ``cvariablename`` component of C's extended 202 ``asm`` syntax. 203 204 .. code-block:: c++ 205 206 // Example with a symbolic name ("aIndex"), the equivalent of: 207 // : [aIndex] "=r" (index) 208 ext_asm.add_output_operand ("aIndex", "=r", index); 209 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. 214 215.. function:: gccjit::extended_asm&\ 216 gccjit::extended_asm::add_output_operand (const std::string &constraint,\ 217 gccjit::lvalue dest) 218 219 As above, but don't supply a symbolic name for the operand. 220 221 .. code-block:: c++ 222 223 // Example without a symbolic name, the equivalent of: 224 // : "=r" (dst) 225 ext_asm.add_output_operand ("=r", dst); 226 227.. function:: gccjit::extended_asm&\ 228 gccjit::extended_asm::add_input_operand (const std::string &asm_symbolic_name, \ 229 const std::string &constraint, \ 230 gccjit::rvalue src) 231 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. 235 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. 239 240 ``constraint`` corresponds to the ``constraint`` component of C's extended 241 ``asm`` syntax. 242 243 ``src`` corresponds to the ``cexpression`` component of C's extended 244 ``asm`` syntax. 245 246 .. code-block:: c++ 247 248 // Example with a symbolic name ("aMask"), the equivalent of: 249 // : [aMask] "r" (Mask) 250 ext_asm.add_input_operand ("aMask", "r", mask); 251 252.. function:: gccjit::extended_asm&\ 253 gccjit::extended_asm::add_input_operand (const std::string &constraint,\ 254 gccjit::rvalue src) 255 256 As above, but don't supply a symbolic name for the operand. 257 258 .. code-block:: c++ 259 260 // Example without a symbolic name, the equivalent of: 261 // : "r" (src) 262 ext_asm.add_input_operand ("r", src); 263 264.. function:: gccjit::extended_asm&\ 265 gccjit::extended_asm::add_clobber (const std::string &victim) 266 267 Add `victim` to the list of registers clobbered by the extended ``asm`` 268 statement. See the 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. 271 272 Statements with multiple clobbers will require multiple calls, one per 273 clobber. 274 275 For example: 276 277 .. code-block:: c++ 278 279 ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory"); 280 281 282Adding top-level assembler statements 283************************************* 284 285In addition to creating extended ``asm`` instructions within a function, 286there is support for creating "top-level" assembler statements, outside 287of any function. 288 289.. function:: void\ 290 gccjit::context::add_top_level_asm (const char *asm_stmts,\ 291 gccjit::location loc = location ()) 292 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. 295 296 For example, to create the equivalent of: 297 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 301 :language: c 302 303 the following API calls could be used: 304 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. */ 308 :language: c 309