LLVM asm with constraints, and 2 operands
kinke
noone at nowhere.com
Mon Jul 19 10:21:58 UTC 2021
On Sunday, 18 July 2021 at 16:32:46 UTC, Basile B. wrote:
> - **=x** says "returns in whatever is has to"
> - **x** (1) is the constraint for input `a`, which is passed as
> operand **$0**
> - **x** (2) is the constraint for input `b`, which is passed as
> operand **$1**
$0 is actually the output operand, $1 is `a`, and $2 is `b`.
The official docs are here, but IMO not very user-friendly:
https://llvm.org/docs/LangRef.html#inline-assembler-expressions
I recommend using GDC/GCC inline asm instead, where you'll find
more examples. For the given paddd example, I'd have gone with
```
int4 _mm_add_int4(int4 a, int4 b)
{
asm { "paddd %1, %0" : "=*x" (a) : "x" (b); }
// the above is equivalent to:
// __asm!void("paddd $1, $0","=*x,x", &a, b);
return a;
}
```
but the produced asm is rubbish (apparently an LLVM issue):
```
movaps %xmm1, -24(%rsp)
paddd %xmm0, %xmm0 // WTF?
movaps %xmm0, -24(%rsp)
retq
```
What works reliably is a manual mov:
```
int4 _mm_add_int4(int4 a, int4 b)
{
int4 r;
asm { "paddd %1, %2; movdqa %2, %0" : "=x" (r) : "x" (a), "x"
(b); }
return r;
}
```
=>
```
paddd %xmm1, %xmm0
movdqa %xmm0, %xmm0 // useless but cannot be optimized away
retq
```
Note: inline asm syntax and resulting asm in AT&T syntax, *not*
Intel syntax.
More information about the Digitalmars-d-learn
mailing list