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 无法非常有效地做到这一点。)