Next: , Previous: CC0 Condition Codes, Up: Condition Code


17.16.2 Representation of condition codes using registers

— Macro: SELECT_CC_MODE (op, x, y)

On many machines, the condition code may be produced by other instructions than compares, for example the branch can use directly the condition code set by a subtract instruction. However, on some machines when the condition code is set this way some bits (such as the overflow bit) are not set in the same way as a test instruction, so that a different branch instruction must be used for some conditional branches. When this happens, use the machine mode of the condition code register to record different formats of the condition code register. Modes can also be used to record which compare instruction (e.g. a signed or an unsigned comparison) produced the condition codes.

If other modes than CCmode are required, add them to machine-modes.def and define SELECT_CC_MODE to choose a mode given an operand of a compare. This is needed because the modes have to be chosen not only during RTL generation but also, for example, by instruction combination. The result of SELECT_CC_MODE should be consistent with the mode used in the patterns; for example to support the case of the add on the SPARC discussed above, we have the pattern

          (define_insn ""
            [(set (reg:CC_NOOV 0)
                  (compare:CC_NOOV
                    (plus:SI (match_operand:SI 0 "register_operand" "%r")
                             (match_operand:SI 1 "arith_operand" "rI"))
                    (const_int 0)))]
            ""
            "...")

together with a SELECT_CC_MODE that returns CC_NOOVmode for comparisons whose argument is a plus:

          #define SELECT_CC_MODE(OP,X,Y) \
            (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT          \
             ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode)    \
             : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS    \
                 || GET_CODE (X) == NEG) \
                ? CC_NOOVmode : CCmode))

Another reason to use modes is to retain information on which operands were used by the comparison; see REVERSIBLE_CC_MODE later in this section.

你应该定义该宏,当且仅当你在machine-modes.def中定义了额外的CC机器模式。

— Macro: CANONICALIZE_COMPARISON (code, op0, op1)

在一些机器上,并不是所有可能的比较都被定义, 但你可以将一个无效的比较转换为一个有效的。例如,Alpha没有GT比较, 但你可以使用LT比较来替代,并且交换操作数的顺序。

在一些机器上,定义该宏为一条C语句来做任何需要的转换。 code为初始化比较代码,op0op1为比较的左,右操作数。 你应该根据需要来修改codeop0op1

GCC将不假设该宏的比较结果为有效的, 但会查看结果insn是否匹配md文件中的指令模式。

你不需要定义该宏,如果其不会改变比较代码或者操作数。

— Macro: REVERSIBLE_CC_MODE (mode)

一个C表达式,其值为1,如果总是可以安全的将模式为mode的比较运算逆转。 如果SELECT_CC_MODE可以为浮点不等于比较返回mode, 则REVERSIBLE_CC_MODE (mode)必须为0。

你不需要定义该宏,如果其总是返回0, 或者如果浮点格式不是IEEE_FLOAT_FORMAT。 例如,这是在SPARC上的定义,其中浮点不等于比较总是为CCFPEmode

          #define REVERSIBLE_CC_MODE(MODE)  ((MODE) != CCFPEmode)
— Macro: REVERSE_CONDITION (code, mode)

一个C表达式,其值为按照CC_MODE模式进行比较的条件码的逆转。 宏只用于REVERSIBLE_CC_MODE (mode)为非0的情况。 当机器具有某种非标准的方式来反转特定条件时,定义该宏。 例如,当所有浮点条件为非陷阱的,编译器可以自由的转换未排序的比较为排序的。 则定义可以为:

          #define REVERSE_CONDITION(CODE, MODE) \
             ((MODE) != CCFPmode ? reverse_condition (CODE) \
              : reverse_condition_maybe_unordered (CODE))
— Target Hook: bool TARGET_FIXED_CONDITION_CODE_REGS (unsigned int *p1, unsigned int *p2)

On targets which do not use (cc0), and which use a hard register rather than a pseudo-register to hold condition codes, the regular CSE passes are often not able to identify cases in which the hard register is set to a common value. Use this hook to enable a small pass which optimizes such cases. This hook should return true to enable this pass, and it should set the integers to which its arguments point to the hard register numbers used for condition codes. When there is only one such register, as is true on most systems, the integer pointed to by p2 should be set to INVALID_REGNUM.

The default version of this hook returns false.

— Target Hook: enum machine_mode TARGET_CC_MODES_COMPATIBLE (enum machine_mode m1, enum machine_mode m2)

On targets which use multiple condition code modes in class MODE_CC, it is sometimes the case that a comparison can be validly done in more than one mode. On such a system, define this target hook to take two mode arguments and to return a mode in which both comparisons may be validly done. If there is no such mode, return VOIDmode.

The default version of this hook checks whether the modes are the same. If they are, it returns that mode. If they are different, it returns VOIDmode.