forked from OSchip/llvm-project
829 lines
19 KiB
ReStructuredText
829 lines
19 KiB
ReStructuredText
|
|
.. _gmir-opcodes:
|
|
|
|
Generic Opcodes
|
|
===============
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
.. note::
|
|
|
|
This documentation does not yet fully account for vectors. Many of the
|
|
scalar/integer/floating-point operations can also take vectors.
|
|
|
|
Constants
|
|
---------
|
|
|
|
G_IMPLICIT_DEF
|
|
^^^^^^^^^^^^^^
|
|
|
|
An undefined value.
|
|
|
|
.. code-block:: none
|
|
|
|
%0:_(s32) = G_IMPLICIT_DEF
|
|
|
|
G_CONSTANT
|
|
^^^^^^^^^^
|
|
|
|
An integer constant.
|
|
|
|
.. code-block:: none
|
|
|
|
%0:_(s32) = G_CONSTANT i32 1
|
|
|
|
G_FCONSTANT
|
|
^^^^^^^^^^^
|
|
|
|
A floating point constant.
|
|
|
|
.. code-block:: none
|
|
|
|
%0:_(s32) = G_FCONSTANT float 1.0
|
|
|
|
G_FRAME_INDEX
|
|
^^^^^^^^^^^^^
|
|
|
|
The address of an object in the stack frame.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(p0) = G_FRAME_INDEX %stack.0.ptr0
|
|
|
|
G_GLOBAL_VALUE
|
|
^^^^^^^^^^^^^^
|
|
|
|
The address of a global value.
|
|
|
|
.. code-block:: none
|
|
|
|
%0(p0) = G_GLOBAL_VALUE @var_local
|
|
|
|
G_BLOCK_ADDR
|
|
^^^^^^^^^^^^
|
|
|
|
The address of a basic block.
|
|
|
|
.. code-block:: none
|
|
|
|
%0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
|
|
|
|
Integer Extension and Truncation
|
|
--------------------------------
|
|
|
|
G_ANYEXT
|
|
^^^^^^^^
|
|
|
|
Extend the underlying scalar type of an operation, leaving the high bits
|
|
unspecified.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_ANYEXT %0:_(s16)
|
|
|
|
G_SEXT
|
|
^^^^^^
|
|
|
|
Sign extend the underlying scalar type of an operation, copying the sign bit
|
|
into the newly-created space.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_SEXT %0:_(s16)
|
|
|
|
G_SEXT_INREG
|
|
^^^^^^^^^^^^
|
|
|
|
Sign extend the value from an arbitrary bit position, copying the sign bit
|
|
into all bits above it. This is equivalent to a shl + ashr pair with an
|
|
appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
|
|
returns true) to allow targets to have some bitwidths legal and others
|
|
lowered. This opcode is particularly useful if the target has sign-extension
|
|
instructions that are cheaper than the constituent shifts as the optimizer is
|
|
able to make decisions on whether it's better to hang on to the G_SEXT_INREG
|
|
or to lower it and optimize the individual shifts.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_SEXT_INREG %0:_(s32), 16
|
|
|
|
G_ZEXT
|
|
^^^^^^
|
|
|
|
Zero extend the underlying scalar type of an operation, putting zero bits
|
|
into the newly-created space.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_ZEXT %0:_(s16)
|
|
|
|
G_TRUNC
|
|
^^^^^^^
|
|
|
|
Truncate the underlying scalar type of an operation. This is equivalent to
|
|
G_EXTRACT for scalar types, but acts elementwise on vectors.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s16) = G_TRUNC %0:_(s32)
|
|
|
|
Type Conversions
|
|
----------------
|
|
|
|
G_INTTOPTR
|
|
^^^^^^^^^^
|
|
|
|
Convert an integer to a pointer.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(p0) = G_INTTOPTR %0:_(s32)
|
|
|
|
G_PTRTOINT
|
|
^^^^^^^^^^
|
|
|
|
Convert a pointer to an integer.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_PTRTOINT %0:_(p0)
|
|
|
|
G_BITCAST
|
|
^^^^^^^^^
|
|
|
|
Reinterpret a value as a new type. This is usually done without
|
|
changing any bits but this is not always the case due a subtlety in the
|
|
definition of the :ref:`LLVM-IR Bitcast Instruction <i_bitcast>`. It
|
|
is allowed to bitcast between pointers with the same size, but
|
|
different address spaces.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s64) = G_BITCAST %0:_(<2 x s32>)
|
|
|
|
G_ADDRSPACE_CAST
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Convert a pointer to an address space to a pointer to another address space.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(p1) = G_ADDRSPACE_CAST %0:_(p0)
|
|
|
|
.. caution::
|
|
|
|
:ref:`i_addrspacecast` doesn't mention what happens if the cast is simply
|
|
invalid (i.e. if the address spaces are disjoint).
|
|
|
|
Scalar Operations
|
|
-----------------
|
|
|
|
G_EXTRACT
|
|
^^^^^^^^^
|
|
|
|
Extract a register of the specified size, starting from the block given by
|
|
index. This will almost certainly be mapped to sub-register COPYs after
|
|
register banks have been selected.
|
|
|
|
.. code-block:: none
|
|
|
|
%3:_(s32) = G_EXTRACT %2:_(s64), 32
|
|
|
|
G_INSERT
|
|
^^^^^^^^
|
|
|
|
Insert a smaller register into a larger one at the specified bit-index.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(s64) = G_INSERT %0:(_s64), %1:_(s32), 0
|
|
|
|
G_MERGE_VALUES
|
|
^^^^^^^^^^^^^^
|
|
|
|
Concatenate multiple registers of the same size into a wider register.
|
|
The input operands are always ordered from lowest bits to highest:
|
|
|
|
.. code-block:: none
|
|
|
|
%0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
|
|
%bits_16_23:(s8), %bits_24_31:(s8)
|
|
|
|
G_UNMERGE_VALUES
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Extract multiple registers of the specified size, starting from blocks given by
|
|
indexes. This will almost certainly be mapped to sub-register COPYs after
|
|
register banks have been selected.
|
|
The output operands are always ordered from lowest bits to highest:
|
|
|
|
.. code-block:: none
|
|
|
|
%bits_0_7:(s8), %bits_8_15:(s8),
|
|
%bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
|
|
|
|
G_BSWAP
|
|
^^^^^^^
|
|
|
|
Reverse the order of the bytes in a scalar.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_BSWAP %0:_(s32)
|
|
|
|
G_BITREVERSE
|
|
^^^^^^^^^^^^
|
|
|
|
Reverse the order of the bits in a scalar.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_BITREVERSE %0:_(s32)
|
|
|
|
G_SBFX, G_UBFX
|
|
^^^^^^^^^^^^^^
|
|
|
|
Extract a range of bits from a register.
|
|
|
|
The source operands are registers as follows:
|
|
|
|
- Source
|
|
- The least-significant bit for the extraction
|
|
- The width of the extraction
|
|
|
|
G_SBFX sign-extends the result, while G_UBFX zero-extends the result.
|
|
|
|
.. code-block:: none
|
|
|
|
; Extract 5 bits starting at bit 1 from %x and store them in %a.
|
|
; Sign-extend the result.
|
|
;
|
|
; Example:
|
|
; %x = 0...0000[10110]1 ---> %a = 1...111111[10110]
|
|
%lsb_one = G_CONSTANT i32 1
|
|
%width_five = G_CONSTANT i32 5
|
|
%a:_(s32) = G_SBFX %x, %lsb_one, %width_five
|
|
|
|
; Extract 3 bits starting at bit 2 from %x and store them in %b. Zero-extend
|
|
; the result.
|
|
;
|
|
; Example:
|
|
; %x = 1...11111[100]11 ---> %b = 0...00000[100]
|
|
%lsb_two = G_CONSTANT i32 2
|
|
%width_three = G_CONSTANT i32 3
|
|
%b:_(s32) = G_UBFX %x, %lsb_two, %width_three
|
|
|
|
Integer Operations
|
|
-------------------
|
|
|
|
G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SDIV, G_UDIV, G_SREM, G_UREM
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These each perform their respective integer arithmetic on a scalar.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(s32) = G_ADD %0:_(s32), %1:_(s32)
|
|
|
|
G_SDIVREM, G_UDIVREM
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Perform integer division and remainder thereby producing two results.
|
|
|
|
.. code-block:: none
|
|
|
|
%div:_(s32), %rem:_(s32) = G_SDIVREM %0:_(s32), %1:_(s32)
|
|
|
|
G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT, G_SSHLSAT, G_USHLSAT
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Signed and unsigned addition, subtraction and left shift with saturation.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(s32) = G_SADDSAT %0:_(s32), %1:_(s32)
|
|
|
|
G_SHL, G_LSHR, G_ASHR
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Shift the bits of a scalar left or right inserting zeros (sign-bit for G_ASHR).
|
|
|
|
G_ROTR, G_ROTL
|
|
^^^^^^^^^^^^^^
|
|
|
|
Rotate the bits right (G_ROTR) or left (G_ROTL).
|
|
|
|
G_ICMP
|
|
^^^^^^
|
|
|
|
Perform integer comparison producing non-zero (true) or zero (false). It's
|
|
target specific whether a true value is 1, ~0U, or some other non-zero value.
|
|
|
|
G_SELECT
|
|
^^^^^^^^
|
|
|
|
Select between two values depending on a zero/non-zero value.
|
|
|
|
.. code-block:: none
|
|
|
|
%5:_(s32) = G_SELECT %4(s1), %6, %2
|
|
|
|
G_PTR_ADD
|
|
^^^^^^^^^
|
|
|
|
Add a scalar offset in addressible units to a pointer. Addressible units are
|
|
typically bytes but this may vary between targets.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(p0) = G_PTR_ADD %0:_(p0), %1:_(s32)
|
|
|
|
.. caution::
|
|
|
|
There are currently no in-tree targets that use this with addressable units
|
|
not equal to 8 bit.
|
|
|
|
G_PTRMASK
|
|
^^^^^^^^^^
|
|
|
|
Zero out an arbitrary mask of bits of a pointer. The mask type must be
|
|
an integer, and the number of vector elements must match for all
|
|
operands. This corresponds to `i_intr_llvm_ptrmask`.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(p0) = G_PTRMASK %0, %1
|
|
|
|
G_SMIN, G_SMAX, G_UMIN, G_UMAX
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Take the minimum/maximum of two values.
|
|
|
|
.. code-block:: none
|
|
|
|
%5:_(s32) = G_SMIN %6, %2
|
|
|
|
G_ABS
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Take the absolute value of a signed integer. The absolute value of the minimum
|
|
negative value (e.g. the 8-bit value `0x80`) is defined to be itself.
|
|
|
|
.. code-block:: none
|
|
|
|
%1:_(s32) = G_ABS %0
|
|
|
|
G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_SMULO, G_UMULO
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Perform the requested arithmetic and produce a carry output in addition to the
|
|
normal result.
|
|
|
|
.. code-block:: none
|
|
|
|
%3:_(s32), %4:_(s1) = G_UADDO %0, %1
|
|
|
|
G_UADDE, G_SADDE, G_USUBE, G_SSUBE
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Perform the requested arithmetic and consume a carry input in addition to the
|
|
normal input. Also produce a carry output in addition to the normal result.
|
|
|
|
.. code-block:: none
|
|
|
|
%4:_(s32), %5:_(s1) = G_UADDE %0, %1, %3:_(s1)
|
|
|
|
G_UMULH, G_SMULH
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Multiply two numbers at twice the incoming bit width (signed) and return
|
|
the high half of the result.
|
|
|
|
.. code-block:: none
|
|
|
|
%3:_(s32) = G_UMULH %0, %1
|
|
|
|
G_CTLZ, G_CTTZ, G_CTPOP
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Count leading zeros, trailing zeros, or number of set bits.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
|
|
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1
|
|
%2:_(s33) = G_CTPOP %1
|
|
|
|
G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Count leading zeros or trailing zeros. If the value is zero then the result is
|
|
undefined.
|
|
|
|
.. code-block:: none
|
|
|
|
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
|
|
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1
|
|
|
|
Floating Point Operations
|
|
-------------------------
|
|
|
|
G_FCMP
|
|
^^^^^^
|
|
|
|
Perform floating point comparison producing non-zero (true) or zero
|
|
(false). It's target specific whether a true value is 1, ~0U, or some other
|
|
non-zero value.
|
|
|
|
G_FNEG
|
|
^^^^^^
|
|
|
|
Floating point negation.
|
|
|
|
G_FPEXT
|
|
^^^^^^^
|
|
|
|
Convert a floating point value to a larger type.
|
|
|
|
G_FPTRUNC
|
|
^^^^^^^^^
|
|
|
|
Convert a floating point value to a narrower type.
|
|
|
|
G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Convert between integer and floating point.
|
|
|
|
G_FABS
|
|
^^^^^^
|
|
|
|
Take the absolute value of a floating point value.
|
|
|
|
G_FCOPYSIGN
|
|
^^^^^^^^^^^
|
|
|
|
Copy the value of the first operand, replacing the sign bit with that of the
|
|
second operand.
|
|
|
|
G_FCANONICALIZE
|
|
^^^^^^^^^^^^^^^
|
|
|
|
See :ref:`i_intr_llvm_canonicalize`.
|
|
|
|
G_FMINNUM
|
|
^^^^^^^^^
|
|
|
|
Perform floating-point minimum on two values.
|
|
|
|
In the case where a single input is a NaN (either signaling or quiet),
|
|
the non-NaN input is returned.
|
|
|
|
The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
|
|
|
|
G_FMAXNUM
|
|
^^^^^^^^^
|
|
|
|
Perform floating-point maximum on two values.
|
|
|
|
In the case where a single input is a NaN (either signaling or quiet),
|
|
the non-NaN input is returned.
|
|
|
|
The return value of (FMAXNUM 0.0, -0.0) could be either 0.0 or -0.0.
|
|
|
|
G_FMINNUM_IEEE
|
|
^^^^^^^^^^^^^^
|
|
|
|
Perform floating-point minimum on two values, following the IEEE-754 2008
|
|
definition. This differs from FMINNUM in the handling of signaling NaNs. If one
|
|
input is a signaling NaN, returns a quiet NaN.
|
|
|
|
G_FMAXNUM_IEEE
|
|
^^^^^^^^^^^^^^
|
|
|
|
Perform floating-point maximum on two values, following the IEEE-754 2008
|
|
definition. This differs from FMAXNUM in the handling of signaling NaNs. If one
|
|
input is a signaling NaN, returns a quiet NaN.
|
|
|
|
G_FMINIMUM
|
|
^^^^^^^^^^
|
|
|
|
NaN-propagating minimum that also treat -0.0 as less than 0.0. While
|
|
FMINNUM_IEEE follow IEEE 754-2008 semantics, FMINIMUM follows IEEE 754-2018
|
|
draft semantics.
|
|
|
|
G_FMAXIMUM
|
|
^^^^^^^^^^
|
|
|
|
NaN-propagating maximum that also treat -0.0 as less than 0.0. While
|
|
FMAXNUM_IEEE follow IEEE 754-2008 semantics, FMAXIMUM follows IEEE 754-2018
|
|
draft semantics.
|
|
|
|
G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Perform the specified floating point arithmetic.
|
|
|
|
G_FMA
|
|
^^^^^
|
|
|
|
Perform a fused multiply add (i.e. without the intermediate rounding step).
|
|
|
|
G_FMAD
|
|
^^^^^^
|
|
|
|
Perform a non-fused multiply add (i.e. with the intermediate rounding step).
|
|
|
|
G_FPOW
|
|
^^^^^^
|
|
|
|
Raise the first operand to the power of the second.
|
|
|
|
G_FEXP, G_FEXP2
|
|
^^^^^^^^^^^^^^^
|
|
|
|
Calculate the base-e or base-2 exponential of a value
|
|
|
|
G_FLOG, G_FLOG2, G_FLOG10
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Calculate the base-e, base-2, or base-10 respectively.
|
|
|
|
G_FCEIL, G_FCOS, G_FSIN, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These correspond to the standard C functions of the same name.
|
|
|
|
G_INTRINSIC_TRUNC
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
Returns the operand rounded to the nearest integer not larger in magnitude than the operand.
|
|
|
|
G_INTRINSIC_ROUND
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
Returns the operand rounded to the nearest integer.
|
|
|
|
Vector Specific Operations
|
|
--------------------------
|
|
|
|
G_CONCAT_VECTORS
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Concatenate two vectors to form a longer vector.
|
|
|
|
G_BUILD_VECTOR, G_BUILD_VECTOR_TRUNC
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Create a vector from multiple scalar registers. No implicit
|
|
conversion is performed (i.e. the result element type must be the
|
|
same as all source operands)
|
|
|
|
The _TRUNC version truncates the larger operand types to fit the
|
|
destination vector elt type.
|
|
|
|
G_INSERT_VECTOR_ELT
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
Insert an element into a vector
|
|
|
|
G_EXTRACT_VECTOR_ELT
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Extract an element from a vector
|
|
|
|
G_SHUFFLE_VECTOR
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Concatenate two vectors and shuffle the elements according to the mask operand.
|
|
The mask operand should be an IR Constant which exactly matches the
|
|
corresponding mask for the IR shufflevector instruction.
|
|
|
|
Vector Reduction Operations
|
|
---------------------------
|
|
|
|
These operations represent horizontal vector reduction, producing a scalar result.
|
|
|
|
G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The SEQ variants perform reductions in sequential order. The first operand is
|
|
an initial scalar accumulator value, and the second operand is the vector to reduce.
|
|
|
|
G_VECREDUCE_FADD, G_VECREDUCE_FMUL
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These reductions are relaxed variants which may reduce the elements in any order.
|
|
|
|
G_VECREDUCE_FMAX, G_VECREDUCE_FMIN
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
|
|
|
|
|
|
Integer/bitwise reductions
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
* G_VECREDUCE_ADD
|
|
* G_VECREDUCE_MUL
|
|
* G_VECREDUCE_AND
|
|
* G_VECREDUCE_OR
|
|
* G_VECREDUCE_XOR
|
|
* G_VECREDUCE_SMAX
|
|
* G_VECREDUCE_SMIN
|
|
* G_VECREDUCE_UMAX
|
|
* G_VECREDUCE_UMIN
|
|
|
|
Integer reductions may have a result type larger than the vector element type.
|
|
However, the reduction is performed using the vector element type and the value
|
|
in the top bits is unspecified.
|
|
|
|
Memory Operations
|
|
-----------------
|
|
|
|
G_LOAD, G_SEXTLOAD, G_ZEXTLOAD
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Generic load. Expects a MachineMemOperand in addition to explicit
|
|
operands. If the result size is larger than the memory size, the
|
|
high bits are undefined, sign-extended, or zero-extended respectively.
|
|
|
|
Only G_LOAD is valid if the result is a vector type. If the result is larger
|
|
than the memory size, the high elements are undefined (i.e. this is not a
|
|
per-element, vector anyextload)
|
|
|
|
G_INDEXED_LOAD
|
|
^^^^^^^^^^^^^^
|
|
|
|
Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
|
|
If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
|
|
then the value is loaded from $newaddr.
|
|
|
|
G_INDEXED_SEXTLOAD
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
|
|
|
|
G_INDEXED_ZEXTLOAD
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
|
|
|
|
G_STORE
|
|
^^^^^^^
|
|
|
|
Generic store. Expects a MachineMemOperand in addition to explicit
|
|
operands. If the stored value size is greater than the memory size,
|
|
the high bits are implicitly truncated. If this is a vector store, the
|
|
high elements are discarded (i.e. this does not function as a per-lane
|
|
vector, truncating store)
|
|
|
|
G_INDEXED_STORE
|
|
^^^^^^^^^^^^^^^
|
|
|
|
Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
|
|
|
|
G_ATOMIC_CMPXCHG_WITH_SUCCESS
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Generic atomic cmpxchg with internal success check. Expects a
|
|
MachineMemOperand in addition to explicit operands.
|
|
|
|
G_ATOMIC_CMPXCHG
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
|
|
operands.
|
|
|
|
G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND, G_ATOMICRMW_NAND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MAX, G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
|
|
operands.
|
|
|
|
G_FENCE
|
|
^^^^^^^
|
|
|
|
.. caution::
|
|
|
|
I couldn't find any documentation on this at the time of writing.
|
|
|
|
Control Flow
|
|
------------
|
|
|
|
G_PHI
|
|
^^^^^
|
|
|
|
Implement the φ node in the SSA graph representing the function.
|
|
|
|
.. code-block:: none
|
|
|
|
%1(s8) = G_PHI %7(s8), %bb.0, %3(s8), %bb.1
|
|
|
|
G_BR
|
|
^^^^
|
|
|
|
Unconditional branch
|
|
|
|
G_BRCOND
|
|
^^^^^^^^
|
|
|
|
Conditional branch
|
|
|
|
G_BRINDIRECT
|
|
^^^^^^^^^^^^
|
|
|
|
Indirect branch
|
|
|
|
G_BRJT
|
|
^^^^^^
|
|
|
|
Indirect branch to jump table entry
|
|
|
|
G_JUMP_TABLE
|
|
^^^^^^^^^^^^
|
|
|
|
.. caution::
|
|
|
|
I found no documentation for this instruction at the time of writing.
|
|
|
|
G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Call an intrinsic
|
|
|
|
The _W_SIDE_EFFECTS version is considered to have unknown side-effects and
|
|
as such cannot be reordered across other side-effecting instructions.
|
|
|
|
.. note::
|
|
|
|
Unlike SelectionDAG, there is no _VOID variant. Both of these are permitted
|
|
to have zero, one, or multiple results.
|
|
|
|
Variadic Arguments
|
|
------------------
|
|
|
|
G_VASTART
|
|
^^^^^^^^^
|
|
|
|
.. caution::
|
|
|
|
I found no documentation for this instruction at the time of writing.
|
|
|
|
G_VAARG
|
|
^^^^^^^
|
|
|
|
.. caution::
|
|
|
|
I found no documentation for this instruction at the time of writing.
|
|
|
|
Other Operations
|
|
----------------
|
|
|
|
G_DYN_STACKALLOC
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
Dynamically realigns the stack pointer to the specified size and alignment.
|
|
An alignment value of `0` or `1` means no specific alignment.
|
|
|
|
.. code-block:: none
|
|
|
|
%8:_(p0) = G_DYN_STACKALLOC %7(s64), 32
|
|
|
|
Optimization Hints
|
|
------------------
|
|
|
|
These instructions do not correspond to any target instructions. They act as
|
|
hints for various combines.
|
|
|
|
G_ASSERT_SEXT, G_ASSERT_ZEXT
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
This signifies that the contents of a register were previously extended from a
|
|
smaller type.
|
|
|
|
The smaller type is denoted using an immediate operand. For scalars, this is the
|
|
width of the entire smaller type. For vectors, this is the width of the smaller
|
|
element type.
|
|
|
|
.. code-block:: none
|
|
|
|
%x_was_zexted:_(s32) = G_ASSERT_ZEXT %x(s32), 16
|
|
%y_was_zexted:_(<2 x s32>) = G_ASSERT_ZEXT %y(<2 x s32>), 16
|
|
|
|
%z_was_sexted:_(s32) = G_ASSERT_SEXT %z(s32), 8
|
|
|
|
G_ASSERT_SEXT and G_ASSERT_ZEXT act like copies, albeit with some restrictions.
|
|
|
|
The source and destination registers must
|
|
|
|
- Be virtual
|
|
- Belong to the same register class
|
|
- Belong to the same register bank
|
|
|
|
It should always be safe to
|
|
|
|
- Look through the source register
|
|
- Replace the destination register with the source register
|