通用操作码¶
注意
本文档尚未完全考虑向量。许多标量/整数/浮点运算也可以使用向量。
常量¶
G_IMPLICIT_DEF¶
一个未定义的值。
%0:_(s32) = G_IMPLICIT_DEF
G_CONSTANT¶
一个整数常量。
%0:_(s32) = G_CONSTANT i32 1
G_FCONSTANT¶
一个浮点常量。
%0:_(s32) = G_FCONSTANT float 1.0
G_FRAME_INDEX¶
栈帧中对象的地址。
%1:_(p0) = G_FRAME_INDEX %stack.0.ptr0
G_GLOBAL_VALUE¶
全局值的地址。
%0(p0) = G_GLOBAL_VALUE @var_local
G_PTRAUTH_GLOBAL_VALUE¶
全局值的签名地址。操作数:要签名的地址(指针),密钥(32 位立即数),用于地址区分的地址(如果不需要则为零)和一个额外的鉴别器(64 位立即数)。
%0:_(p0) = G_PTRAUTH_GLOBAL_VALUE %1:_(p0), s32, %2:_(p0), s64
G_BLOCK_ADDR¶
基本块的地址。
%0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
G_CONSTANT_POOL¶
常量池中对象的地址。
%0:_(p0) = G_CONSTANT_POOL %const.0
整数扩展和截断¶
G_ANYEXT¶
扩展操作的底层标量类型,将高位保持未指定状态。
%1:_(s32) = G_ANYEXT %0:_(s16)
G_SEXT¶
符号扩展操作的底层标量类型,将符号位复制到新创建的空间中。
%1:_(s32) = G_SEXT %0:_(s16)
G_SEXT_INREG¶
从任意位位置进行符号扩展值,将符号位复制到其上方的所有位。这等效于具有适当移位量的 shl + ashr 对。 $sz 是一个立即数 (MachineOperand::isImm() 返回 true),以允许目标具有一些合法的位宽和其他降低的位宽。如果目标具有比构成移位更便宜的符号扩展指令,则此操作码特别有用,因为优化器可以决定是保留 G_SEXT_INREG 还是降低它并优化各个移位。
%1:_(s32) = G_SEXT_INREG %0:_(s32), 16
G_ZEXT¶
零扩展操作的底层标量类型,将零位放入新创建的空间中。
%1:_(s32) = G_ZEXT %0:_(s16)
G_TRUNC¶
截断操作的底层标量类型。对于标量类型,这等效于 G_EXTRACT,但对向量按元素执行操作。
%1:_(s16) = G_TRUNC %0:_(s32)
类型转换¶
G_INTTOPTR¶
将整数转换为指针。
%1:_(p0) = G_INTTOPTR %0:_(s32)
G_PTRTOINT¶
将指针转换为整数。
%1:_(s32) = G_PTRTOINT %0:_(p0)
G_BITCAST¶
将值重新解释为新类型。这通常在不更改任何位的情况下完成,但由于 LLVM-IR Bitcast 指令 定义中的细微之处,情况并非总是如此。允许在大小相同但地址空间不同的指针之间进行位转换。
%1:_(s64) = G_BITCAST %0:_(<2 x s32>)
G_ADDRSPACE_CAST¶
将指向一个地址空间的指针转换为指向另一个地址空间的指针。
%1:_(p1) = G_ADDRSPACE_CAST %0:_(p0)
注意
‘addrspacecast .. to’ 指令 没有提及如果转换无效(即如果地址空间不相交)会发生什么。
标量运算¶
G_EXTRACT¶
从索引给定的块开始,提取指定大小的寄存器。在选择了寄存器组之后,这几乎肯定会映射到子寄存器 COPY。
%3:_(s32) = G_EXTRACT %2:_(s64), 32
G_INSERT¶
在指定的位索引处将较小的寄存器插入到较大的寄存器中。
%2:_(s64) = G_INSERT %0:(_s64), %1:_(s32), 0
G_MERGE_VALUES¶
将多个相同大小的寄存器连接成一个更宽的寄存器。输入操作数始终从最低位到最高位排序
%0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
%bits_16_23:(s8), %bits_24_31:(s8)
G_UNMERGE_VALUES¶
从索引给定的块开始,提取多个指定大小的寄存器。在选择了寄存器组之后,这几乎肯定会映射到子寄存器 COPY。输出操作数始终从最低位到最高位排序
%bits_0_7:(s8), %bits_8_15:(s8),
%bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
G_BSWAP¶
反转标量中字节的顺序。
%1:_(s32) = G_BSWAP %0:_(s32)
G_BITREVERSE¶
反转标量中位的顺序。
%1:_(s32) = G_BITREVERSE %0:_(s32)
G_SBFX, G_UBFX¶
从寄存器中提取一定范围的位。
源操作数是寄存器,如下所示
源
提取的最低有效位
提取的宽度
最低有效位 (lsb) 和宽度操作数的范围是
0 <= lsb < lsb + width <= source bitwidth, where all values are unsigned
G_SBFX 符号扩展结果,而 G_UBFX 零扩展结果。
; 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
整数运算¶
G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SDIV, G_UDIV, G_SREM, G_UREM¶
这些操作分别对标量执行各自的整数算术运算。
%dst:_(s32) = G_ADD %src0:_(s32), %src1:_(s32)
上面的示例将 %src1 添加到 %src0,并将结果存储在 %dst 中。
G_SDIVREM, G_UDIVREM¶
执行整数除法和余数运算,从而产生两个结果。
%div:_(s32), %rem:_(s32) = G_SDIVREM %0:_(s32), %1:_(s32)
G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT, G_SSHLSAT, G_USHLSAT¶
带饱和的符号和无符号加法、减法和左移。
%2:_(s32) = G_SADDSAT %0:_(s32), %1:_(s32)
G_SHL, G_LSHR, G_ASHR¶
将标量的位向左或向右移动,插入零(G_ASHR 为符号位)。
G_ROTR, G_ROTL¶
向右 (G_ROTR) 或向左 (G_ROTL) 旋转位。
G_ICMP¶
执行整数比较,产生非零值(真)或零值(假)。真值是 1、~0U 还是其他非零值取决于目标。
G_SCMP¶
执行有符号 3 向整数比较,产生 -1(较小)、0(相等)或 1(较大)。
%5:_(s32) = G_SCMP %6, %2
G_UCMP¶
执行无符号 3 向整数比较,产生 -1(较小)、0(相等)或 1(较大)。
%7:_(s32) = G_UCMP %2, %6
G_SELECT¶
根据零/非零值在两个值之间进行选择。
%5:_(s32) = G_SELECT %4(s1), %6, %2
G_PTR_ADD¶
将可寻址单元中的标量偏移量添加到指针。可寻址单元通常是字节,但这可能因目标而异。
%1:_(p0) = G_PTR_ADD %0:_(p0), %1:_(s32)
注意
目前没有树内目标将此用于可寻址单元不等于 8 位的情况。
G_PTRMASK¶
将指针的任意位掩码清零。掩码类型必须是整数,并且所有操作数的向量元素数量必须匹配。这对应于 i_intr_llvm_ptrmask。
%2:_(p0) = G_PTRMASK %0, %1
G_SMIN, G_SMAX, G_UMIN, G_UMAX¶
取两个值的最小值/最大值。
%5:_(s32) = G_SMIN %6, %2
G_ABS¶
取有符号整数的绝对值。最小负值(例如 8 位值 0x80)的绝对值定义为其自身。
%1:_(s32) = G_ABS %0
G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_SMULO, G_UMULO¶
执行请求的算术运算,并在正常结果之外产生一个进位输出。
%3:_(s32), %4:_(s1) = G_UADDO %0, %1
G_UADDE, G_SADDE, G_USUBE, G_SSUBE¶
执行请求的算术运算,并在正常输入之外消耗一个进位输入。还在正常结果之外产生一个进位输出。
%4:_(s32), %5:_(s1) = G_UADDE %0, %1, %3:_(s1)
G_UMULH, G_SMULH¶
将两个数字乘以传入位宽的两倍(无符号或有符号),并返回结果的高半部分。
%3:_(s32) = G_UMULH %0, %1
G_CTLZ, G_CTTZ, G_CTPOP¶
计数前导零、尾随零或设置位的数量。
%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¶
计数前导零或尾随零。如果值为零,则结果未定义。
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1
G_ABDS, G_ABDU¶
计算绝对差值(有符号和无符号),例如 abs(x-y)。
%0:_(s33) = G_ABDS %2, %3
%1:_(s33) = G_ABDU %4, %5
浮点运算¶
G_FCMP¶
执行浮点比较,产生非零值(真)或零值(假)。真值是 1、~0U 还是其他非零值取决于目标。
G_FNEG¶
浮点取反。
G_FPEXT¶
将浮点值转换为更大的类型。
G_FPTRUNC¶
将浮点值转换为更窄的类型。
G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP¶
在整数和浮点之间进行转换。
G_FPTOSI_SAT, G_FPTOUI_SAT¶
在整数和浮点之间进行饱和转换。
G_FABS¶
取浮点值的绝对值。
G_FCOPYSIGN¶
复制第一个操作数的值,并将符号位替换为第二个操作数的符号位。
G_FCANONICALIZE¶
G_IS_FPCLASS¶
测试第一个操作数(必须是浮点标量或向量)是否具有第二个操作数指定的浮点类。返回非零值(真)或零值(假)。真值是 1、~0U 还是其他非零值取决于目标。如果第一个操作数是向量,则返回值是相同长度的向量。
G_FMINNUM¶
对两个值执行浮点最小值运算。
在单个输入为 NaN(信令或静默)的情况下,将返回非 NaN 输入。
(FMINNUM 0.0, -0.0) 的返回值可以是 0.0 或 -0.0。
G_FMAXNUM¶
对两个值执行浮点最大值运算。
在单个输入为 NaN(信令或静默)的情况下,将返回非 NaN 输入。
(FMAXNUM 0.0, -0.0) 的返回值可以是 0.0 或 -0.0。
G_FMINNUM_IEEE¶
按照 IEEE-754 定义对两个值执行浮点最小值运算。这与 FMINNUM 在处理信令 NaN 方面有所不同。
如果一个输入是信令 NaN,则返回静默 NaN。这与 IEEE-754 2008 的 minnum/maxnum 对于信令 NaN(与 2019 年不同)相匹配。
这些将 -0 视为小于 +0 的有序值,与 IEEE-754 2019 的 minimumNumber/maximumNumber 的行为相匹配(在 2008 年未指定)。
G_FMAXNUM_IEEE¶
按照 IEEE-754 定义对两个值执行浮点最大值运算。这与 FMAXNUM 在处理信令 NaN 方面有所不同。
如果一个输入是信令 NaN,则返回静默 NaN。这与 IEEE-754 2008 的 minnum/maxnum 对于信令 NaN(与 2019 年不同)相匹配。
这些将 -0 视为小于 +0 的有序值,与 IEEE-754 2019 的 minimumNumber/maximumNumber 的行为相匹配(在 2008 年未指定)。
G_FMINIMUM¶
NaN 传播最小值,也将 -0.0 视为小于 0.0。虽然 FMINNUM_IEEE 遵循 IEEE 754-2008 语义,但 FMINIMUM 遵循 IEEE 754-2019 语义。
G_FMAXIMUM¶
NaN 传播最大值,也将 -0.0 视为小于 0.0。虽然 FMAXNUM_IEEE 遵循 IEEE 754-2008 语义,但 FMAXIMUM 遵循 IEEE 754-2019 语义。
G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM¶
执行指定的浮点算术运算。
G_FMA¶
执行融合乘加运算(即,不进行中间舍入步骤)。
G_FMAD¶
执行非融合乘加运算(即,进行中间舍入步骤)。
G_FPOW¶
将第一个操作数提升为第二个操作数的幂。
G_FEXP, G_FEXP2¶
计算值的以 e 或 2 为底的指数
G_FLOG, G_FLOG2, G_FLOG10¶
分别计算以 e、2 或 10 为底的对数。
G_FCEIL, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT¶
这些对应于同名的标准 C 函数。
G_FCOS, G_FSIN, G_FSINCOS, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH, G_FTANH¶
这些对应于同名的标准 C 三角函数。
G_INTRINSIC_TRUNC¶
返回操作数四舍五入到最接近的整数,该整数在幅度上不大于操作数。
G_INTRINSIC_ROUND¶
返回操作数四舍五入到最接近的整数。
G_LROUND, G_LLROUND¶
返回源操作数四舍五入到最接近的整数,与零方向相反。
有关行为的详细信息,请参阅 LLVM LangRef 中关于 ‘llvm.lround.*'
的条目。
%rounded_32:_(s32) = G_LROUND %round_me:_(s64)
%rounded_64:_(s64) = G_LLROUND %round_me:_(s64)
向量特定运算¶
G_VSCALE¶
将运行时 vscale
的值乘以源操作数中的值,并将结果放入目标寄存器中。这在确定向量中元素的实际运行时数量时很有用。
%0:_(s32) = G_VSCALE 4
G_INSERT_SUBVECTOR¶
将第二个源向量插入到第一个源向量中。索引操作数表示第二个源向量应插入到第一个源向量中的起始索引。
索引必须是第二个源向量的最小向量长度的常数倍数。如果向量是可缩放的,则索引首先按运行时缩放因子缩放。插入到源向量中的索引必须是该向量的有效索引。如果无法静态确定此条件,但在运行时为假,则结果向量未定义。
%2:_(<vscale x 4 x i64>) = G_INSERT_SUBVECTOR %0:_(<vscale x 4 x i64>), %1:_(<vscale x 2 x i64>), 0
G_EXTRACT_SUBVECTOR¶
从源向量中提取目标类型的向量。索引操作数表示从源向量中提取子向量的起始索引。
索引必须是源向量的最小向量长度的常数倍数。如果源向量是可缩放向量,则索引首先按运行时缩放因子缩放。从源向量中提取的索引必须是该向量的有效索引。如果无法静态确定此条件,但在运行时为假,则结果向量未定义。
不允许混合可缩放向量和固定向量。
%3:_(<vscale x 4 x i64>) = G_EXTRACT_SUBVECTOR %2:_(<vscale x 8 x i64>), 2
G_CONCAT_VECTORS¶
连接两个向量以形成更长的向量。
G_BUILD_VECTOR, G_BUILD_VECTOR_TRUNC¶
从多个标量寄存器创建向量。不执行隐式转换(即,结果元素类型必须与所有源操作数相同)
_TRUNC 版本截断较大的操作数类型以适合目标向量 elt 类型。
G_INSERT_VECTOR_ELT¶
将元素插入向量
G_EXTRACT_VECTOR_ELT¶
从向量中提取元素
G_SHUFFLE_VECTOR¶
连接两个向量,并根据掩码操作数对元素进行混洗。掩码操作数应为 IR 常量,该常量与 IR shufflevector 指令的相应掩码完全匹配。
G_SPLAT_VECTOR¶
创建一个向量,其中所有元素都是来自源操作数的标量。
操作数的类型必须等于或大于向量元素类型。如果操作数大于向量元素类型,则标量会隐式截断为向量元素类型。
G_STEP_VECTOR¶
创建一个可缩放向量,其中所有通道都是从 0 开始的线性序列,并具有给定的无符号步长。
操作数的类型必须等于向量元素类型。算术运算以元素的位宽为模执行。步长必须 > 0。否则向量为零。
%0:_(<vscale x 2 x s64>) = G_STEP_VECTOR i64 4
%1:_(<vscale x s32>) = G_STEP_VECTOR i32 4
0, 1*Step, 2*Step, 3*Step, 4*Step, ...
G_VECTOR_COMPRESS¶
给定一个输入向量、一个掩码向量和一个 passthru 向量,连续地将所有选定的(即,其中 mask[i] = true)输入通道放置在输出向量中。输出中的所有剩余通道都取自 passthru,passthru 可能是未定义的。
向量缩减运算¶
这些操作表示水平向量缩减,产生标量结果。
G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL¶
SEQ 变体按顺序执行缩减。第一个操作数是初始标量累加器值,第二个操作数是要缩减的向量。
G_VECREDUCE_FADD, G_VECREDUCE_FMUL¶
这些缩减是宽松的变体,可以以任何顺序缩减元素。
G_VECREDUCE_FMAX, G_VECREDUCE_FMIN, G_VECREDUCE_FMAXIMUM, G_VECREDUCE_FMINIMUM¶
FMIN/FMAX/FMINIMUM/FMAXIMUM 节点可以有标志,用于 NaN/NoNaN 变体。
整数/按位缩减¶
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
整数缩减的结果类型可能大于向量元素类型。但是,缩减是使用向量元素类型执行的,并且高位中的值未指定。
内存操作¶
G_LOAD, G_SEXTLOAD, G_ZEXTLOAD¶
通用加载。除了显式操作数外,还需要一个 MachineMemOperand。如果结果大小大于内存大小,则高位分别是未定义的、符号扩展的或零扩展的。
如果结果是向量类型,则仅 G_LOAD 有效。如果结果大于内存大小,则高元素是未定义的(即,这不是按元素、向量 anyextload)
与 SelectionDAG 不同,原子加载与常规加载使用相同的操作码表示。 G_LOAD、G_SEXTLOAD 和 G_ZEXTLOAD 可能都具有原子内存操作数。
G_INDEXED_LOAD¶
通用索引加载。将 GEP 与加载结合在一起。 $newaddr 设置为 $base + $offset。如果 $am 为 0(后索引),则从 $base 加载值;如果 $am 为 1(预索引),则从 $newaddr 加载值。
G_INDEXED_SEXTLOAD¶
与 G_INDEXED_LOAD 相同,但执行的加载操作是带符号扩展,如同 G_SEXTLOAD。
G_INDEXED_ZEXTLOAD¶
与 G_INDEXED_LOAD 相同,但执行的加载操作是零扩展,如同 G_ZEXTLOAD。
G_STORE¶
通用存储。除了显式操作数外,还需要一个 MachineMemOperand。如果存储的值大小大于内存大小,则高位将被隐式截断。如果这是向量存储,则高位元素将被丢弃(即,这不像每个通道的向量截断存储那样工作)。
G_INDEXED_STORE¶
将存储与 GEP 组合。有关索引行为,请参阅 G_INDEXED_LOAD 的描述。
G_ATOMIC_CMPXCHG_WITH_SUCCESS¶
带有内部成功检查的通用原子 cmpxchg。除了显式操作数外,还需要一个 MachineMemOperand。
G_ATOMIC_CMPXCHG¶
通用原子 cmpxchg。除了显式操作数外,还需要一个 MachineMemOperand。
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, G_ATOMICRMW_FMAX, G_ATOMICRMW_FMIN, G_ATOMICRMW_UINC_WRAP, G_ATOMICRMW_UDEC_WRAP, G_ATOMICRMW_USUB_COND, G_ATOMICRMW_USUB_SAT¶
通用 atomicrmw。除了显式操作数外,还需要一个 MachineMemOperand。
G_FENCE¶
通用 fence。第一个操作数是内存排序。第二个操作数是同步作用域。
有关更多详细信息,请参阅 LLVM LangRef 中关于 ‘fence'
指令的条目。
G_MEMCPY¶
通用 memcpy。除了显式操作数外,还需要两个 MachineMemOperand,分别涵盖存储和加载。
G_MEMCPY_INLINE¶
通用内联 memcpy。与 G_MEMCPY 类似,但保证此版本不会被降低为对外部函数的调用。目前,大小操作数需要评估为常量(而不是立即数),尽管当 llvm.memcpy.inline 被教导支持动态大小时,这种情况有望改变。
G_MEMMOVE¶
通用 memmove。与 G_MEMCPY 类似,但允许源内存范围和目标内存范围重叠。
G_MEMSET¶
通用 memset。除了显式操作数外,还需要一个 MachineMemOperand。
G_BZERO¶
通用 bzero。除了显式操作数外,还需要一个 MachineMemOperand。
控制流¶
G_PHI¶
实现 SSA 图中表示函数的 φ 节点。
%dst(s8) = G_PHI %src1(s8), %bb.<id1>, %src2(s8), %bb.<id2>
G_BR¶
无条件分支
G_BR %bb.<id>
G_BRCOND¶
条件分支
G_BRCOND %condition, %basicblock.<id>
G_BRINDIRECT¶
间接分支
G_BRINDIRECT %src(p0)
G_BRJT¶
间接分支到跳转表条目
G_BRJT %ptr(p0), %jti, %idx(s64)
G_JUMP_TABLE¶
生成指向源操作数指定的跳转表地址的指针。源操作数是跳转表索引。 G_JUMP_TABLE 可以与 G_BRJT 结合使用,以支持使用 GlobalISel 的跳转表代码生成。
%dst:_(p0) = G_JUMP_TABLE %jump-table.0
上面的示例生成指向源跳转表索引的指针。
G_INVOKE_REGION_START¶
一个标记指令,充当可能抛出异常的代码区域的伪终止符。作为终止符,它可以防止在诸如合法化之类的过程中在其后插入代码。这是必需的,因为对异常抛出例程的调用不会返回,因此任何必须在可执行路径上的代码都不能放置在抛出之后。
G_INTRINSIC, G_INTRINSIC_CONVERGENT¶
调用没有副作用的 intrinsic。
_CONVERGENT 变体对应于标记为 convergent 的 LLVM IR intrinsic。
注意
与 SelectionDAG 不同,没有 _VOID 变体。这两者都允许有零个、一个或多个结果。
G_INTRINSIC_W_SIDE_EFFECTS, G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS¶
调用被认为具有未知副作用的 intrinsic,因此不能跨其他具有副作用的指令重新排序。
_CONVERGENT 变体对应于标记为 convergent 的 LLVM IR intrinsic。
注意
与 SelectionDAG 不同,没有 _VOID 变体。这两者都允许有零个、一个或多个结果。
G_TRAP, G_DEBUGTRAP, G_UBSANTRAP¶
表示 llvm.trap、llvm.debugtrap 和 llvm.ubsantrap,它们生成目标相关的 trap 指令。
G_TRAP
G_DEBUGTRAP
G_UBSANTRAP 12
可变参数¶
G_VASTART¶
注意
在编写本文档时,我没有找到此指令的文档。
G_VAARG¶
注意
在编写本文档时,我没有找到此指令的文档。
其他操作¶
G_DYN_STACKALLOC¶
动态地将堆栈指针重新对齐到指定的大小和对齐方式。对齐值 0 或 1 表示没有特定的对齐方式。
%8:_(p0) = G_DYN_STACKALLOC %7(s64), 32
优化提示¶
这些指令不对应于任何目标指令。它们充当各种组合的提示。
G_ASSERT_SEXT, G_ASSERT_ZEXT¶
这表示寄存器的内容先前已从较小的类型扩展而来。
较小的类型使用立即操作数表示。对于标量,这是整个较小类型的宽度。对于向量,这是较小元素类型的宽度。
%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 和 G_ASSERT_ZEXT 的行为类似于复制,但有一些限制。
源寄存器和目标寄存器必须
是虚拟的
属于同一寄存器类
属于同一寄存器组
始终可以安全地
查看源寄存器
用源寄存器替换目标寄存器
杂项¶
G_CONSTANT_FOLD_BARRIER¶
此操作用作防止常量折叠的不透明屏障。组合和其他转换不应穿过它。这些没有其他语义,如果目标选择,可以安全地消除它们。
未列出:G_STACKSAVE, G_STACKRESTORE, G_FSHL, G_FSHR, G_SMULFIX, G_UMULFIX, G_SMULFIXSAT, G_UMULFIXSAT, G_SDIVFIX, G_UDIVFIX, G_SDIVFIXSAT, G_UDIVFIXSAT, G_FPOWI, G_FEXP10, G_FLDEXP, G_FFREXP, G_GET_FPENV, G_SET_FPENV, G_RESET_FPENV, G_GET_FPMODE, G_SET_FPMODE, G_RESET_FPMODE, G_INTRINSIC_FPTRUNC_ROUND, G_INTRINSIC_LRINT, G_INTRINSIC_LLRINT, G_INTRINSIC_ROUNDEVEN, G_READCYCLECOUNTER, G_READSTEADYCOUNTER, G_PREFETCH, G_READ_REGISTER, G_WRITE_REGISTER, G_STRICT_FADD, G_STRICT_FSUB, G_STRICT_FMUL, G_STRICT_FDIV, G_STRICT_FREM, G_STRICT_FMA, G_STRICT_FSQRT, G_STRICT_FLDEXP, G_ASSERT_ALIGN