c - GCC 编译器移植到新架构 : Call external library function

标签 c gcc compiler-construction porting cpu-architecture

我正在将 GCC 编译器移植到新的处理器架构。它类似于 v850 架构(“/gcc/config/v850”)并且几乎完成了。但是我在乘法算术运算中遇到了问题。体系结构仅支持无符号乘法。在签名的情况下,我必须使用 lib1funcs.asm 中的“__mulsi3”库函数。所以我需要在签名时调用库函数。执行“mulsi3”指令如下。有人知道如何从 {target}.md 文件或 {target}.c 文件调用任何库函数吗?帮帮我……

我遵循“sh”架构(“/gcc/config/sh”)并像 sh 架构一样实现。 GCC 构建正常。但是当我在目标上编译测试代码时,有一条错误消息。 (文件 => emit-rtl.c:862)


多路指令

    (define_insn "mulsi3"
        [(set (match_operand:SI 0 "register_operand" "=r,r")
            (mult:SI (match_operand:SI 1 "nonmemory_operand" "r,r")
                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
        ""
        "*
        {
        /* REG */
        if(GET_CODE (operands[2]) == REG)
        {
            return \"mul %0,%1,%2\";
        }
        /* IMMEDIATE */
        else
        {
            /* unsigned case */
            if(CONST_OK_FOR_M(INTVAL(operands[2])))
            {
                return \"muli %0,%1,%2\";
            }
            /* signed case */
            else
            {
                /******************************************/
                /* need to call __mulsi3 library function */
                /******************************************/
            }
        }
    }
    "
    [(set_attr "length" "6,6")
    (set_attr "cc" "none_0hit,none_0hit")
    (set_attr "type" "mult")])

最佳答案

mulsi3 是特殊名称。只有当它们非常简单时,你才可以将它赋予 insn 模式。

实际上在您的情况下 mulsi3 模式应该是 define_expand,然后您可以使其在某些分支上失败(使用显式 FAIL 语句)。当专门的扩展模式失败时,编译器应该生成 libgcc 调用。

但是还有两个更正:

1) 模式匹配优先于显式 if-else 内部模式。 IE。编写单独的 =r,r,r 和 =r,r,i 指令模式,通过谓词和约束限制到允许的范围。如果编译器也找不到合适的模式,它应该生成 libgcc 调用,您不需要(在大多数情况下这是个坏主意)显式地写 FAIL。

2) 注意谓词/约束匹配。 “非内存操作数”是“r,r”的极其糟糕的谓词。比如说,你这里有合法的常量,你的程序很大,重新加载找不到寄存器……一切都崩溃了。

我还建议您在 gcc@gcc.gnu.org 邮件列表中提出此类深入的问题。

关于c - GCC 编译器移植到新架构 : Call external library function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28844861/

相关文章:

c - 第一个 C 编译器是如何编写的?

c++ - 如何在不使用临时变量或算术运算的情况下交换两个数字?

c - 双变量右移

c++ - GCC在被杀死时创建带有随机后缀的目标文件

python - 使用 gcc/ubuntu 的 if 子句中的段错误

c# - 作为服务的 Mono 编译器可以在调试上下文中使用吗?

c# - lambdas 如何作用于局部变量?

c - 为什么 argc 和 argv 的地址相差 12 个字节?

c - 通过调用共享 DLL 在两个线程之间进行信息交换

c++ - 使用非 MSVC 编译器在 Windows 下打开带有 Unicode 文件名的文件的 fstream