A gccjit::extended_asm represents an extended asm statement: a
series of low-level instructions inside a function that convert inputs
to outputs.
gccjit;;extended_asm is a subclass of gccjit;;object. It is a thin wrapper around the C API’s gcc_jit_extended_asm *.
To avoid having an API entrypoint with a very large number of
parameters, an extended asm statement is made in stages:
an initial call to create the gccjit;;extended_asm,
followed by calls to add operands and set other properties of the
statement.
There are two API entrypoints for creating a gccjit;;extended_asm:
asm statement with
no control flow, and
asm goto.
For example, to create the equivalent of:
asm ("mov %1, %0\n\t"
"add $1, %0"
: "=r" (dst)
: "r" (src));
the following API calls could be used:
block.add_extended_asm ("mov %1, %0\n\t"
"add $1, %0")
.add_output_operand ("=r", dst)
.add_input_operand ("r", src);
|
As in the C syntax, operands can be given symbolic names to avoid having to number them. For example, to create the equivalent of:
asm ("bsfl %[aMask], %[aIndex]"
: [aIndex] "=r" (Index)
: [aMask] "r" (Mask)
: "cc");
the following API calls could be used:
block.add_extended_asm ("bsfl %[aMask], %[aIndex]")
.add_output_operand ("aIndex", "=r", index)
.add_input_operand ("aMask", "r", mask)
.add_clobber ("cc");
Create a gccjit;;extended_asm for an extended asm statement
with no control flow (i.e. without the goto qualifier).
The parameter asm_template corresponds to the AssemblerTemplate
within C’s extended asm syntax. It must be non-NULL. The call takes
a copy of the underlying string, so it is valid to pass in a pointer to
an on-stack buffer.
Create a gccjit;;extended_asm for an extended asm statement
that may perform jumps, and use it to terminate the given block.
This is equivalent to the goto qualifier in C’s extended asm
syntax.
For example, to create the equivalent of:
asm goto ("btl %1, %0\n\t"
"jc %l[carry]"
: // No outputs
: "r" (p1), "r" (p2)
: "cc"
: carry);
the following API calls could be used:
const char *asm_template =
(use_name
? /* Label referred to by name: "%l[carry]". */
("btl %1, %0\n\t"
"jc %l[carry]")
: /* Label referred to numerically: "%l2". */
("btl %1, %0\n\t"
"jc %l2"));
std::vector<gccjit::block> goto_blocks ({b_carry});
gccjit::extended_asm ext_asm
= (b_start.end_with_extended_asm_goto (asm_template,
goto_blocks,
&b_fallthru)
.add_input_operand ("r", p1)
.add_input_operand ("r", p2)
.add_clobber ("cc"));
here referencing a gcc_jit_block named “carry”.
num_goto_blocks corresponds to the GotoLabels parameter within C’s
extended asm syntax. The block names can be referenced within the
assembler template.
fallthrough_block can be NULL. If non-NULL, it specifies the block
to fall through to after the statement.
|
Set whether the gccjit;;extended_asm has side-effects, equivalent to the volatile12 qualifier in C’s extended asm syntax.
For example, to create the equivalent of:
asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n\t" // Shift the upper bits left.
"or %%rdx, %0" // 'Or' in the lower bits.
: "=a" (msr)
:
: "rdx");
the following API calls could be used:
gccjit::extended_asm ext_asm
= block.add_extended_asm
("rdtsc\n\t" /* Returns the time in EDX:EAX. */
"shl $32, %%rdx\n\t" /* Shift the upper bits left. */
"or %%rdx, %0") /* 'Or' in the lower bits. */
.set_volatile_flag (true)
.add_output_operand ("=a", msr)
.add_clobber ("rdx");
where the gccjit;;extended_asm is flagged as volatile.
Set the equivalent of the
inline13
qualifier in C’s extended asm syntax.
Add an output operand to the extended asm statement. See the
Output Operands14
section of the documentation of the C syntax.
asm_symbolic_name corresponds to the asmSymbolicName component of
C’s extended asm syntax, and specifies the symbolic name for the operand.
See the overload below for an alternative that does not supply a symbolic
name.
constraint corresponds to the constraint component of C’s extended
asm syntax.
dest corresponds to the cvariablename component of C’s extended
asm syntax.
// Example with a symbolic name ("aIndex"), the equivalent of:
// : [aIndex] "=r" (index)
ext_asm.add_output_operand ("aIndex", "=r", index);
This function can’t be called on an asm goto as such instructions can’t
have outputs; see the
Goto Labels15
section of GCC’s “Extended Asm” documentation.
As above, but don’t supply a symbolic name for the operand.
// Example without a symbolic name, the equivalent of:
// : "=r" (dst)
ext_asm.add_output_operand ("=r", dst);
Add an input operand to the extended asm statement. See the
Input Operands16
section of the documentation of the C syntax.
asm_symbolic_name corresponds to the asmSymbolicName component
of C’s extended asm syntax. See the overload below for an alternative
that does not supply a symbolic name.
constraint corresponds to the constraint component of C’s extended
asm syntax.
src corresponds to the cexpression component of C’s extended
asm syntax.
// Example with a symbolic name ("aMask"), the equivalent of:
// : [aMask] "r" (Mask)
ext_asm.add_input_operand ("aMask", "r", mask);
As above, but don’t supply a symbolic name for the operand.
// Example without a symbolic name, the equivalent of:
// : "r" (src)
ext_asm.add_input_operand ("r", src);
Add victim to the list of registers clobbered by the extended asm
statement. See the
Clobbers and Scratch Registers17
section of the documentation of the C syntax.
Statements with multiple clobbers will require multiple calls, one per clobber.
For example:
ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#