切换实现;手臂;汇编器; aarch64; arm64
switch implementation; arm; assembler; aarch64; arm64
我对在 aarch64 汇编器上实现 'switch' 运算符的方法很感兴趣。
在 arm32 平台上,我使用了类似
ldr pc, [pc, ta, LSL#2]
nop // alignment
.int .L.case1
.int .L.case2
...
.int .L.caseN
但是由于64位版本对'pc'寄存器的使用有很多限制,这样的实现不再有效了。
似乎最简单的方法是使用一对比较和分支操作,例如
cmp ta, #1
b.eq .L.case1
cmp ta, #2
b.eq .L.case2
...
但有时会有多达十几个案例,这会导致在到达最后一个 'case' 之前出现明显的延迟。
能否分享一下如何在 aarch64 上实现快速切换的想法。
谢谢:)
我没有 64 位 ARM 汇编器来测试这个,但我相信你会做类似下面的事情来实现跳转 table:
adr x0, jmp_table
ldr x0, [x0, x1, LSL#3]
br x0
jmp_table:
.quad .L.case1
.quad .L.case2
.quad .L.case3
第一条指令,ADR, loads the address of a label into a register. The last instruction, BR,跳转到寄存器中存储的地址。
如果您正在创建共享库或独立于位置的执行程序table,您可以尝试如下操作:
adr x0, jmp_table
add x0, x0, x1, LSL#2
br x0
jmp_table:
b .L.case1
b .L.case2
b .L.case3
备用 PIC 示例
adr x0, jmp_table
ldr w1, [x0, x1, LSL#2]
add x0, x0, x1
br x0
jmp_table:
.int .L.case1 - jmp_table
.int .L.case2 - jmp_table
.int .L.case3 - jmp_table
我对在 aarch64 汇编器上实现 'switch' 运算符的方法很感兴趣。 在 arm32 平台上,我使用了类似
ldr pc, [pc, ta, LSL#2]
nop // alignment
.int .L.case1
.int .L.case2
...
.int .L.caseN
但是由于64位版本对'pc'寄存器的使用有很多限制,这样的实现不再有效了。
似乎最简单的方法是使用一对比较和分支操作,例如
cmp ta, #1
b.eq .L.case1
cmp ta, #2
b.eq .L.case2
...
但有时会有多达十几个案例,这会导致在到达最后一个 'case' 之前出现明显的延迟。
能否分享一下如何在 aarch64 上实现快速切换的想法。
谢谢:)
我没有 64 位 ARM 汇编器来测试这个,但我相信你会做类似下面的事情来实现跳转 table:
adr x0, jmp_table
ldr x0, [x0, x1, LSL#3]
br x0
jmp_table:
.quad .L.case1
.quad .L.case2
.quad .L.case3
第一条指令,ADR, loads the address of a label into a register. The last instruction, BR,跳转到寄存器中存储的地址。
如果您正在创建共享库或独立于位置的执行程序table,您可以尝试如下操作:
adr x0, jmp_table
add x0, x0, x1, LSL#2
br x0
jmp_table:
b .L.case1
b .L.case2
b .L.case3
备用 PIC 示例
adr x0, jmp_table
ldr w1, [x0, x1, LSL#2]
add x0, x0, x1
br x0
jmp_table:
.int .L.case1 - jmp_table
.int .L.case2 - jmp_table
.int .L.case3 - jmp_table