Next: Leaf Functions, Previous: Allocation Order, Up: Registers
这节讨论的宏,描述了每个寄存器可以存放哪类的值(明确的说, 是哪些机器模式的),以及对于给定的机器模式需要多少个连续的寄存器。
一个C表达式,为存放模式mode的值所需要的连续的硬件寄存器, 起始于寄存器编号regno。该宏不要返回0, 即使寄存器不能存放指定的mode —— 替代的, 使用HARD_REGNO_MODE_OK 和/或 CANNOT_CHANGE_MODE_CLASS。
在所有寄存器都是一个字大小的机器上,该宏的一个合适的定义为
#define HARD_REGNO_NREGS(REGNO, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ / UNITS_PER_WORD)
一个C表达式,为非0,如果模式为mode的值,存储在内存中, 并由padding结尾,这使得其占有更多的空间, 比在起始于寄存器编号regno的寄存器中。缺省的为0。
例如,如果浮点值存储在三个32位寄存器中,但是在内存中占有128位,则该宏应该为非0。
该宏只有当
subreg_get_info
会错误的确定一个subreg
可以通过寄存器编号的偏移量来表示, 而实际上这样的subreg
将会保存一些不应该被表示的padding时, 才需要被定义。
对于
HARD_REGNO_NREGS_HAS_PADDING
会返回非0的regno和mode的值, 其为一个C表达式,返回保存包括任何padding的值所需要的寄存器的最大数。 在上面的例子中,值将为4。
定义该宏,如果存放模式mode的值的寄存器的自然大小,不是word大小。 其为一个C表达式,对于指定的mode给出以字节为单位的自然的大小。 其被寄存器分配用于尝试优化它的结果。 例如这出现在SPARC 64位机器上,其浮点寄存器的自然大小仍然是32位。
一个C表达式,其为非0, 如果允许将一个mode模式的值存储在硬件寄存器编号regno (或者起始于它的多个寄存器)中。对于所有寄存器都是等价的机器上, 一个合适的定义为
#define HARD_REGNO_MODE_OK(REGNO, MODE) 1你不需要包含检查固定寄存器编号的代码, 因为分配机制总是认为它们已经被占用了。
在一些机器上,双精度值必须放在偶/奇寄存器对。 你可以通过定义该宏来拒绝这样模式的奇数寄存器编号。
对于一个模式可以放在寄存器中的最小需求为, ‘movmode’指令模式支持在寄存器和同一类别的其它硬件寄存器之间的移动, 并且将一个值移动到寄存器中并移动回来,而不会改变。
由于用于move
word_mode
的同一指令,也可以用于所有更窄的整数模式, 所以HARD_REGNO_MODE_OK
不必要在任何机器上对于这些模式都不同, 假定你定义了指令模式‘movhi’等。许多机器对于浮点算术具有特定的寄存器。 通常人们假设浮点机器模式只在浮点寄存器中被允许。这并不真实。 任何可以存放整数的寄存器都可以安全的存放一个浮点机器模式, 而不管是否可以在这些寄存器上进行浮点算术。 整数move指令可以用于移动这些值。
然而在一些机器上,定点机器模式不可以放在浮点寄存器中。 比如如果浮点寄存器对任何存储的值进行标准化, 因为存储一个非浮点值将会使值变得混淆。这种情况下,
HARD_REGNO_MODE_OK
应该拒绝定点机器模式放在浮点寄存器中。 但是,如果浮点寄存器不自动标准化, 如果你可以存储任何位的指令模式并无需改动的获得它, 则任何机器模式都可以放在浮点寄存器中,这样你可以定义该宏来表明可以这么做。当然,特定的浮点寄存器的主要意义是它们在浮点算术指令中可以使用。 但是,这根
HARD_REGNO_MODE_OK
没有关系。 你可以通过对那些执行写合适的约束来处理。在一些机器上,浮点寄存器访问起来特别慢,所以如果浮点算术没有完成前, 最好将值存在栈帧中,而不是在这样的寄存器中。 只要浮点寄存器不在
GENERAL_REGS
类别中,它们将不会被使用, 除非某个指令模式的约束要求这样。
一个C表达式,为非0, 如果可以将一个硬件寄存器from重命名为另一个寄存器to。
该宏的一个通用的用法是防止将一个寄存器重命名为另一个寄存器, 而其在中断处理函数的序言中没有被保存。
缺省总是为非0。
一个C表达式,其为非0,如果一个模式mode1的值, 不需要复制便可以按照模式mode2来访问。
如果
HARD_REGNO_MODE_OK (
r,
mode1)
和HARD_REGNO_MODE_OK (
r,
mode2)
对于任何r总是相同, 则MODES_TIEABLE_P (
mode1,
mode2)
应该为非0。 如果它们对于任何r都不同,则你应该定义该宏来返回0, 除非某个其它机制能够确保值可以按照更窄的模式来访问。你应该定义该宏来尽可能情况的返回非0, 因为这样会使得GCC执行更好的寄存器分配。
This target hook should return
true
if it is OK to use a hard register regno as scratch reg in peephole2. This target hook should returntrue
if it is OK to use a hard register regno as scratch reg in peephole2.One common use of this macro is to prevent using of a register that is not saved by a prologue in an interrupt handler.
The default version of this hook always returns
true
.