Reputation: 581
I'm trying out the new arm64 instructions on iOS and I'm having a peculiar issue. I hope someone can help me with this.
In particular this fails with 'Invalid operand for instruction'
void test()
{
register long long signed int r=0,c=0,d=0;
register signed int a=0,b=0,e=0,f=0;
// this fails
asm volatile("smaddl %0, %1, %2, %3" : "=r"(r) : "r"(a), "r"(b), "r"(c));
};
I'm not sure what I'm doing wrong, to the best that I can tell, I'm following the instruction and syntax correctly. Here's how it is defined in the docs:
"SMADDL Xd, Wn, Wm, Xa Signed Multiply-Add Long: Xd = Xa + (Wn × Wm), treating source operands as signed."
where X denotes a 64bit register and W denotes a 32 bit one.
Any help will be appreciated.
Thx
Upvotes: 4
Views: 5438
Reputation: 25268
I was able to fix it by using recommendation in this post:
asm volatile("smaddl %x0, %w1, %w2, %x3" : "=r"(r) : "r"(a), "r"(b), "r"(c));
This produces the following assembly:
_test: ; @test
; BB#0:
sub sp, sp, #48
movz w8, #0
movz x9, #0
stp x9, x9, [sp, #32]
str x9, [sp, #24]
stp w8, w8, [sp, #16]
stp w8, w8, [sp, #8]
ldp w10, w8, [sp, #16]
ldr x9, [sp, #32]
; InlineAsm Start
smaddl x9, w8, w10, x9
; InlineAsm End
str x9, [sp, #40]
add sp, sp, #48
ret lr
It seems you need to use 'w' to specifically mark 32-bit registers.
See also aarch64-inline-asm.c for a few more inline asm examples.
Upvotes: 2