Next: , Previous: Insns, Up: RTL


10.20 函数调用insns的RTL表示

调用子程序的Insn具有RTL表达式代码call_insn。这些insn必须满足特别的规则,并且它们的主体必须使用特定的RTL表达式代码call

call表达式有两个操作数,如下:

     (call (mem:fm addr) nbytes)

这里nbytes操作数表示传递给子程序的参数的字节数,fm是一个机器模式(其必须与在机器描述中定义的FUNCTION_MODE相等),addr表示子程序的地址。

对于子程序没有返回值的,上面所示的call表达式是insn的整个主体,除了insn可能还会包含useclobber表达式。

对于子程序返回不是BLKmode模式的值的,值通过硬件寄存器返回。如果该寄存器号为r,则call insn的主体看起来是这样的:

     (set (reg:m r)
          (call (mem:fm addr) nbytes))

该RTL表达式很清楚的说明了(对于优化阶段),在该insn中有一个适当的寄存器用来接受一个有用的值。

当子程序返回BLKmode值时,将会通过传递给子程序用来存储返回值的地址来处理。因次,call insn本身不返回任何值,具有和没有返回值一样的RTL。

在一些机器上,调用指令本身会破坏一些寄存器,例如包含了返回地址。这些机器上的call_insn应该有一个parallel主体,包含了call表达式和clobber表达式,用来指示哪些寄存器会被破坏。类似的,如果调用指令需要栈指针之外的一些寄存器,并且没有在其RTL中显示提到的,则应该用use子表达式来指出。

被调用的函数被假设为会修改列在配置宏CALL_USED_REGISTERS(参见Register Basics)中的所有寄存器,并且除了const函数和库函数调用外,被假设为会修改所有的内存。

直接在call_insn之前的只是包含了use表达式的insn,用来指示哪些寄存器用来存放函数的输入。类似的,如果不在CALL_USED_REGISTERS中那些寄存器会被所调用的函数破坏,紧跟在call之后的包含了单独的clobber的insn,用来指出这些寄存器。