逻辑左移两个 numbers/registers 之和?

Left Shift Logical by sum of two numbers/registers?

有没有办法通过两个相加来执行逻辑左移numbers/registers?

我正在考虑看起来像这样但实际上有效的东西:

mov r4, r1, lsl add, r7, #1

您需要两条指令(计算 tmp 寄存器中的移位计数)。

(除非两个数字都是常量。lsl r4, r1, #1 + #2 可以在 assemble 时计算为 lsl r4, r1, #3。)

寄存器 + 立即数或寄存器 + 寄存器在 ARM 机器代码中不可编码。只有少数位编码移位模式(左,右逻辑,右算术,右旋转。和立即数或寄存器计数)和移位计数(寄存器号或计数为立即数,但不是两者)。

ASM 源代码只是一种用文本描述机器代码指令的方式。它不像 C,您可以编写更复杂的表达式并将其编译为多条指令。因此,存在限制是因为机器代码编码限制,而不是因为 asm 语法/语言设计选择。

(ldr r0, =0x12345678 是一种伪指令,它对不止一条指令执行 assemble ,或者从附近的文字池中加载与 PC 相关的指令。但除了一些伪指令- 用于构造不适合作为一个 32 位 ARM 或 16 位 thumb/thumb2 指令的一部分的字段的较大值的指令,一个 asm 指令必须 assemble 到一个机器指令。)

根据https://www.scss.tcd.ie/John.Waldron/3d1/barrelshift.pdf,移位计数可以 5 位立即数,或指定为寄存器的底部字节。绝对不是两者。


我不认为您可以使用任何完全不同的说明。例如你只能移动一个操作数,所以你不能通过将两个输入左移到 add 相同的量来获得额外的逐一移动。


如果代码使用结果可以稍后应用移位的常量部分,您也许可以优化掉额外的立即移位。

我不确定使用桶形移位器是否会在某些 ARM uarches 上增加任何延迟,但如果是这样的话,在一个循环中有很多指令都做一个额外的移位,而不是一个是理想的将移位结果保存在寄存器中的额外指令。

当然,如果您想将它用于需要移位其他操作数的指令,则需要最终值。