繁体   English   中英

Linux内核上的64位除法

[英]64 bit division on linux kernel

我正在寻找64位除法算法,但不依赖于GPL许可证。

我在Hacker Delight书中找到了以下代码(图9-5):

unsigned long long udivdi3(unsigned long long u,
unsigned long long v) 
if (v >> 32 == 0) {
    if (u >> 32 < v)
        return DIVU(u, v) & 0xFFFFFFFF;
else {
.....
     }
}

问题是“ return DIVU”计算的是64/32的除法,所以这不是我想要的。 该怎么办?

这就是编译器-rt存在的原因。 这是 __udivdi3最终调用的C实现 ,但请注意,还使用了特定于平台的程序集版本,例如在x86上。

但是,实际上,没有必要避免使用libgcc-它已经更成熟了,支持更多平台,并且由于运行时库例外,GPL在很大程度上已损坏-而且您绝对不应该为此修改上游源,因此无需提供任何已修改的源代码。

在Linux内核代码中执行64位分割似乎很棘手。 我不确定您是否遇到了同样的问题,但这就是我所知道的。

看来指令集不能完全处理64位算术运算。 看起来gcc发出了对辅助函数的调用。 例如,在ARM上,如果我写

t /= 86400;

其中t是64位变量,我的内核构建失败,带有“ undefined reference to '__aeabi_ldivmod' ”。 显然,内核没有链接到存在诸如__aeabi_ldivmod函数的完整C库。

解决方案似乎是改为调用do_div do_div实际上不是一个函数; 它是在特定于体系结构的头文件中声明的宏。 (对于ARM,它在arch/arm/include/asm/div64.h有一个类似的文件。)

解决方案是将t /= 86400替换为

(void)do_div(t, 86400);

do_div将其第一个参数除以第二个参数就位,然后返回余数(在此示例中我将忽略)。

div64.h有一个很大的注释, div64.h告诉您有关do_div以及如何使用它的更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM