iosobjective-cxcodeassembly

Using inline assembler in iOS aarch64 application


I tried to compile some inline assembler for 64-bit iOS application.

Here's an example:

   int roundff(float _value) {
       int res;
       float temp;
       asm("vcvtr.s32.f32 %[temp], %[value] \n vmov %[res], %[temp]" : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value));
       return res;
   }

and I have this errors:

Unrecognized instruction mnemonic.

But this code compiles fine:

__asm__ volatile(
                 "add %[result], %[b], %[a];"
                 : [result] "=r" (result)
                 : [a] "r" (a), [b] "r" (b), [c] "r" (c)
                 );

Than I founded that in aarch64 I have to use fcvt instead of vcvt. Because

int a = (int)(10.123);

compiles into

fcvtzs w8, s8

but I don't know how to write it in inline assembler. Something like this

int roundff(float _value)
{
    int res;
    asm("fcvtzs %[res], %[value]" : [res] "=r" (res) : [value] "w" (_value));
    return res;
}

also doesn't work and generates this errors:

Instruction 'fcvtz' can not set flags, but 's' suffix specified.

Invalid operand for instruction.

Also I need round instead of trim. (fcvtns)

Any help? Where I can read something more about arm(32/64) asm?

UPDATE Ok. This: float res = nearbyintf(v) compiles into nice instruction frinti s0 s0. But why my inline assembler does not work on iOS using clang compiler?


Solution

  • Here is how you do it:

    -(int) roundff:(float)a {
        int y;
        __asm__("fcvtzs %w0, %s1\n\t" : "=r"(y) : "w"(a));
        return y;
    }
    

    Take care,

    /A