gcc 为 MIPS 64 使用的默认代码模型的名称是什么?
What is the name of the default code model used by gcc for MIPS 64?
MIPS 64 的 gcc 使用复杂的方法来定位和调用编译单元中不存在的函数。此代码模型的名称是什么(记录在何处)?我搜索但没有发现它即将到来。它涉及 </code>/<code>$gp
和 </code>/<code>$t9
作为传递给被调用函数的某种参数。
而且,此翻译中是否存在错误(在代码生成或文本输出中)?
以下代码序列:
extern int g(int);
int f(int x)
{
return g(x) + 2;
}
生成此输出:
daddiu $sp,$sp,-16
sd ,0($sp)
lui ,%hi(%neg(%gp_rel(f(int))))
daddu ,, <--- sourcing /$t9
daddiu ,,%lo(%neg(%gp_rel(f(int))))
ld ,%call16(_Z1gi)()
sd ,8($sp)
nop <--- where is the function call??
ld ,8($sp)
ld ,0($sp)
addiu ,,2
j
daddiu $sp,$sp,16
在我上面的第二个 <-- 标记处,我希望看到一个间接函数调用,但那里只有一个 nop
(这可能是用于调用的延迟槽指令,否则无法解释)。
(在我的第一个标记处,它获取了 25 美元,所以这一定是提供给 f
的某种参数;f
似乎也可能为 g
设置了 25 美元作为嗯。)
https://godbolt.org/z/11n9nxs63
将 -msym32
添加到上述命令行选项(告诉它假设所有符号都有一个 32 位地址),代码通过 jal
.[=23 使用直接函数调用=]
对“是否存在错误”部分的部分回答,不是 MIPS64 ABI 中代码模型的名称。
事实证明 [compiler-explorer] 标签毕竟是相关的:它隐藏了一个
1: jalr
在nop
之前(确实在分支延迟槽中),这是上一行.reloc 1f,R_MIPS_JALR,g
的目标。 Uncheck "hide unused labels";我想过滤错误地假定标签不会与指令在同一行,而 MIPS 则不是这种情况。
所以是的,确实,这是从 GOT 加载一个指针到 </code> 并跳过它。</p>
<p>显然 <code>
作为函数自身的地址作为 ABI/calling 约定的一部分,以启用与位置无关的代码(显然 Linux MIPS 总是需要,即使我认为直到最近 ADDIUPC
的 MIPS 修订版之前,MIPS 无法非常有效地做到这一点。)
MIPS 64 的 gcc 使用复杂的方法来定位和调用编译单元中不存在的函数。此代码模型的名称是什么(记录在何处)?我搜索但没有发现它即将到来。它涉及 </code>/<code>$gp
和 </code>/<code>$t9
作为传递给被调用函数的某种参数。
而且,此翻译中是否存在错误(在代码生成或文本输出中)?
以下代码序列:
extern int g(int);
int f(int x)
{
return g(x) + 2;
}
生成此输出:
daddiu $sp,$sp,-16
sd ,0($sp)
lui ,%hi(%neg(%gp_rel(f(int))))
daddu ,, <--- sourcing /$t9
daddiu ,,%lo(%neg(%gp_rel(f(int))))
ld ,%call16(_Z1gi)()
sd ,8($sp)
nop <--- where is the function call??
ld ,8($sp)
ld ,0($sp)
addiu ,,2
j
daddiu $sp,$sp,16
在我上面的第二个 <-- 标记处,我希望看到一个间接函数调用,但那里只有一个 nop
(这可能是用于调用的延迟槽指令,否则无法解释)。
(在我的第一个标记处,它获取了 25 美元,所以这一定是提供给 f
的某种参数;f
似乎也可能为 g
设置了 25 美元作为嗯。)
https://godbolt.org/z/11n9nxs63
将 -msym32
添加到上述命令行选项(告诉它假设所有符号都有一个 32 位地址),代码通过 jal
.[=23 使用直接函数调用=]
对“是否存在错误”部分的部分回答,不是 MIPS64 ABI 中代码模型的名称。
事实证明 [compiler-explorer] 标签毕竟是相关的:它隐藏了一个
1: jalr
在nop
之前(确实在分支延迟槽中),这是上一行.reloc 1f,R_MIPS_JALR,g
的目标。 Uncheck "hide unused labels";我想过滤错误地假定标签不会与指令在同一行,而 MIPS 则不是这种情况。
所以是的,确实,这是从 GOT 加载一个指针到 </code> 并跳过它。</p>
<p>显然 <code>
作为函数自身的地址作为 ABI/calling 约定的一部分,以启用与位置无关的代码(显然 Linux MIPS 总是需要,即使我认为直到最近 ADDIUPC
的 MIPS 修订版之前,MIPS 无法非常有效地做到这一点。)