go - 如何在golang中编写asm代码 "bsrl"

标签 go assembly

我需要用 golang 编写一些 asm 代码。我读了这个问题 Is it possible to include inline assembly in Google Go code? ,但看不到怎么写。 谁能帮帮我?谢谢。

asm ("bsrl %1, %0;"
           :"=r"(bits)            /* output */
           :"r"(value) );         /* input */

最佳答案

the question you found 上的所有答案说不可能在 Go 中以任何语法使用 inline-asm。 GNU C 内联汇编语法没有帮助。

但幸运的是,bsr 不需要内联汇编(它找到最高设置位的位索引)。 Go 1.9 有一个用于位运算的内在/内置函数,这些函数足够接近,应该可以高效地编译。


使用math.bits.LeadingZeros32得到 lzcnt(x),对于非零 x,它是 31-bsr(x)。这可能会花费额外的指令,尤其是在仅支持 bsr 而不是 lzcnt 的 CPU 上。 (例如 Intel pre-Haswell)。

或使用 Len32(x) - 1

Len32(x) 返回表示 x 所需的位数。它为 x=0 返回 0,并且大概它为 x=1 返回 1,所以它是 bsr(x) + 1,具有为 0 定义的行为(因此可能会花费额外的指令)。希望 Len32(x) - 1 可以直接编译成 bsr

当然,如果您真正想要的是lzcnt,那么首先使用LeadingZeros32


请注意 bsr对于输入 = 0,保留目标寄存器不变。 Intel 的文档只说了一个未定义的值,因此编译器可能不会利用 AMD 文档和 Intel 在硬件中提供的这种保证。

不过,至少在理论上,如果编译器可以证明 xLen32(x) - 1 可以编译为单个 bsr 指令> 非零。

关于go - 如何在golang中编写asm代码 "bsrl",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49704245/

相关文章:

go - Jmoiron SQLX Golang通用接口(interface)

assembly - 当像这样访问堆栈帧时 <dword ptr [ebp-8]> 是否被认为是弹出的?

linux - “inline assembly”代码的返回值是多少?

debugging - 如何在 ASM 中调试? (Ubuntu)

json - 将Go结构转换为JSON

go - 运行 go mod vendor 更新我的库

string - strings.Contains()始终返回false

c - Linux下编译C文件时出现汇编错误

c++ - 如何启动我的简单 hello world 程序?

go - 映射作为方法接收者