Next: Expander Definitions, Previous: Looping Patterns, Up: Machine Desc
经常会有多个RTL表达式可以表示由单个机器指令所执行的运算。该情况对于逻辑, 分支和乘累加指令最常见。对于这样的情况, 编译器尝试将这些多个RTL表达式转换为一个规范的形式, 以减少对insn指令模式的需求数。
除了进行代数简化以外,还执行了下面的规范化:
plus
,
只有它的左操作数本身可以为一个plus
。当应用到整数时,
and
, ior
, xor
, plus
, mult
, smin
,
smax
, umin
和umax
为可结合的,对于浮点,这些有时为可结合的。
neg
, not
,mult
, plus
或
minus
表达式的操作数,则其将为第一个操作数。
neg
, mult
, plus
和minus
的组合中,
neg
操作(如果存在)将被尽可能的移到内部。
例如(neg (mult A B))
将被规范为(mult (neg A) B)
,
但是(plus (mult (neg A) B) C)
将被规范为(minus A (mult B C))
。
compare
运算符,在使用cc0
(参见Jump Patterns)的机器上,
常量总是为第二个操作数。 在其它机器上,极少的情况下,
编译器可能想使用常量作为第一个操作数来构建compare
。但是,
这些情况并不常见,所以不值得来提供匹配常量作为第一个操作数的指令模式,
除非机器确实具有这样的指令。
在与上面条件相同的情况下,neg
, not
, mult
, plus
或
minus
的操作数被作为第一个操作数。
(ltu (plus
a b)
b)
被转换为
(ltu (plus
a b)
a)
。
同样,使用geu
来替换ltu
。
(minus
x (const_int
n))
被转换为
(plus
x (const_int
-n))
。
mem
中),左移操作被转换为与合适的2的幂相乘。
not
表达式的唯一的操作数,则其为第一个。
具有执行按位‘逻辑与’,且其中一个操作数为一个按位求反的机器, 应该为该指令指定如下的指令模式
(define_insn "" [(set (match_operand:m 0 ...) (and:m (not:m (match_operand:m 1 ...)) (match_operand:m 2 ...)))] "..." "...")
类似的,“NAND”指令的指令模式应给被写为
(define_insn "" [(set (match_operand:m 0 ...) (ior:m (not:m (match_operand:m 1 ...)) (not:m (match_operand:m 2 ...))))] "..." "...")
对于这两种情况,都没必要包含许多逻辑上相同的RTL表达式。
(xor:
m x y)
和(not:
m (xor:
m x y))
。
(plus:m (plus:m x y) constant)
cc0
的机器上,
(compare
x (const_int 0))
将被转换为x。
zero_extract
,
而不是等价的and
或者sign_extract
运算。
更多的规范化规则都定义在gcc/rtlanal.c里的函数commutative_operand_precedence
中。