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中。