Next: , Previous: Regs and Memory, Up: RTL


10.9 RTL算术运算表达式

除非其它规定,所有算术表达式的操作数必须对模式m有效。一个操作数对模式m有效,是指当它具有模式m,或者如果它是一个const_int或者const_double,并且m是一个MODE_INT类的模式。

对于可交换的二进制操作,常量应该放到第二个操作数的位置。

(plus:m x y)
(ss_plus:m x y)
(us_plus:m x y)
这三个表达式都表示xy所表示的值的和,机器模式为m。它们在整数机器模式的溢出方面有所不同。plusm的宽度求模进行环绕;ss_plus饱和为m可表示的有符号最大值;us_plus饱和为无符号最大值。


(lo_sum:m x y)
该表达式表示xy低位的和。其跟high (参见Constants)一起使用,来表示在RISC机器中通常使用的两个指令序列,来引用一个全局内存位置。

低位的位数是机器相关的,但通常为Pmode中的位数减去high所设置的位数。

m应该为Pmode


(minus:m x y)
(ss_minus:m x y)
(us_minus:m x y)
这三个表达式表示从x中减去y的结果,机器模式为m。在溢出方面的行为与plus的三种版本相同(参见上面)。


(compare:m x y)
表示从x中减去y的结果,用于进行比较。计算结果不产生溢出,就好像是有无限的精度一样。

当然,机器不会真的进行无限精度的减法。然而,它们可以假定这样做,当只使用结果的正负符号时,这样情况下,结果被存放在条件代码中。并且,这是这种表达式唯一可以被使用的方式:作为值存储在条件代码中,或者(cc0),或者一个寄存器。参见Comparisons.

机器模式mxy的机器模式没有关联,而是条件代码值的机器模式。如果使用(cc0),则为VOIDmode,否则为类别MODE_CC中的某个模式,通常为CCmode。参见Condition Code. 如果mVOIDmode或者CCmode,则运算会返回足够的信息,使得任何比较运算符可以被应用到COMPARE运算的结果上。对于类别MODE_CC中的其它机器模式,运算只返回信息的子集。

通常,xy必须具有相同的机器模式。否则,compare只有当x的机器模式在类别MODE_INT中,并且y为一个机器模式为VOIDmodeconst_int或者const_double,这时才有效。x的机器模式决定了比较按照什么机器模式进行;因此其不能为VOIDmode

如果其中一个操作数为常量,则其应该被放在第二个操作数的位置,并且相应的调整比较代码。

指定两个VOIDmode常量的compare是无效的,因为无法知道比较要按照什么机器模式进行;比较必须或者在编译过程中被折叠,或者第一个操作数必须被加载到机器模式已知的寄存器中。


(neg:m x)
(ss_neg:m x)
(us_neg:m x)
这两个表达式表示x所表示的值的负数(零减去该值),机器模式为m。它们在整数机器模式的溢出行为上有所不同。对于neg,操作数的负数可以为无法用机器模式m表示的数,这种情况下,其被截取为mss_negus_neg确保超出边界的结果饱和为最大或者最小的有符号或者无符号值。


(mult:m x y)
(ss_mult:m x y)
(us_mult:m x y)
表示xy所表示的值的有符号乘积,机器模式为mss_multus_mult确保超出边界的结果饱和为最大或者最小的有符号或者无符号值。

一些机器支持产生比操作数更宽的乘积。则指令模式可以写成

          (mult:m (sign_extend:m x) (sign_extend:m y))

其中mxy的机器模式更宽。

对于无符号的加宽的乘法,使用相同的语句,只不过把sign_extend替换成zero_extend


(div:m x y)
(ss_div:m x y)
表示x有符号除以y的商,机器模式为m。如果m为一个浮点机器模式,则表示确切的商;否则为整数化的商。ss_div确保超出边界的结果饱和为最大或者最小的有符号值。

一些机器具有的除法指令,其操作数和商的宽度不全相同;你应该使用truncatesign_extend来表示这样的指令,

          (truncate:m1 (div:m2 x (sign_extend:m2 y)))


(udiv:m x y)
(us_div:m x y)
类似div,不过表示无符号除法。us_div确保超出边界的结果饱和为最大或者最小的无符号值。


(mod:m x y)
(umod:m x y)
类似divudiv,不过表示余数。


(smin:m x y)
(smax:m x y)
表示xy的较小值(smin)或者较大值(smax),按照机器模式为m的有符号值解析。当用于浮点,如果两个操作数都为零,或者其中一个为NaN,则没有规定哪一个操作数被作为结果返回。


(umin:m x y)
(umax:m x y)
类似sminsmax,不过值被解析为无符号整数。


(not:m x)
表示对x所表示的值进行按位求补,机器模式为m,且必须为一个定点机器模式。


(and:m x y)
表示对xy所表示的值按位进行逻辑与,机器模式为m,且必须为一个定点机器模式。


(ior:m x y)
表示对xy所表示的值按位进行逻辑或,机器模式为m,且必须为一个定点机器模式。


(xor:m x y)
表示对xy所表示的值按位进行逻辑异或,机器模式为m,且必须为一个定点机器模式。


(ashift:m x c)
(ss_ashift:m x c)
(us_ashift:m x c)
这三个表达式用来表示对x进行向左算术移位c。它们在整数机器模式的溢出方面有所不同。ashift运算是一个普通的移位,当符号位有改变时,其没有特殊的行为;ss_ashiftus_ashift,饱和为可表示的最小或者最大值,如果任何被移出的位与最终的符号位不同。

x具有机器模式m,一个定点机器模式。c为一个定点机器模式或者一个模式为VOIDmode的常量。


(lshiftrt:m x c)
(ashiftrt:m x c)
类似于ashift,不过是向右移位。不像向左移位的情况,这两种运算是有区别的。


(rotate:m x c)
(rotatert:m x c)
类似的,只不过是表示向左和向右旋转。如果c为常量,则使用rotate


(abs:m x)
表示x的绝对值,按照机器模式m来计算。


(sqrt:m x)
表示x的平方根,按照机器模式m来计算。m通常为浮点机器模式。


(ffs:m x)
表示在x中,最低有效,位为1的索引加上1,为一个模式m的整数。(如果x为零,则值为零。)x的机器模式不需要为m;取决于目标机器,可以有不同的机器模式的组合。


(clz:m x)
CLZ_DEFINED_VALUE_AT_ZERO (参见Misc). Note that this is one of 表示x中,从最高有效位开始,起始处为0的位数,为一个模式m的整数。如果x为零,则值由CLZ_DEFINED_VALUE_AT_ZERO (参见Misc)来确定。注意,。x的机器模式通常为一个整数模式。


(ctz:m x)
表示x中,从最低有效位开始,结尾处为0的位数,为一个模式m的整数。如果x为零,则值由CTZ_DEFINED_VALUE_AT_ZERO (参见Misc)来确定。除此之外,ctz(x)等价于ffs(x) - 1x的机器模式通常为一个整数模式。


(popcount:m x)
表示x中为1的位数,为一个模式m的整数。x的机器模式通常为一个整数模式。


(parity:m x)
表示x中为1的位数对2进行求模,为一个模式m的整数。x的机器模式通常为一个整数模式。


(bswap:m x)
表示将x值的字节顺序进行反转,结果为m机器模式,其必须为一个定点机器模式。