4

I want to load the value of a double precision register (d8) into a C variable on ARM platform with a toolchain (gcc-4.6) that comes with the Google NDKv8b. My ARM machine is a Samsung Galaxy S2 (it has VFPv3 and NEON). The GCC documentation says that in order to use VFP double precision registers on inline assembly, the "w" constraint must be used. So I tried something like this (ok, don't look so much into the logic of the whole program):

#include <stdio.h>

int main()
{
    double dVar = 1.2345678;
    double dTmp;
    int i;
    for(i = 0; i < 100; i++ )
    {
        asm volatile(
            "vmov.f64 %[dTmp], d8\n"
            : [dTmp] "=w" (dTmp)
            :
            :
        );
        dVar *= 10.0;
        printf("d8 = %f\n", dTmp );
    }

    return 0;
}

Well, it doesn't even compile:

/tmp/cc9wQA1z.s: Assembler messages:
/tmp/cc9wQA1z.s:62: Internal error, aborting at /usr/local/google/home/andrewhsieh/ndk-andrewhsieh/src/build/../binutils/binutils-2.21/gas/config/tc-arm.c line 14709 in do_neon_mov

How can I achieve this?

Thanks!

Juan Gómez
  • 93
  • 1
  • 9
  • 1
    I don't think you can use vmov.f64 for moving data between VFP and ARM registers. You should use "vmov Rd, Rn, Dm", however I couldn't get it right with inline assembly. – auselen Sep 27 '12 at 11:02
  • Yes, indeed I cannot. This is cause I'm telling to the output constraint that dTmp must be a double precision register ready for writting (=w). AFAIK gcc should be using a "d" register from the range: d0-d31 for dTmp variable (cause the constraint). It must probably be a syntax error cause it doesn't even compile. – Juan Gómez Sep 27 '12 at 13:05
  • I upgraded to binutils-2.22, but the error is quite the same as it was with binutils-2.21. – Juan Gómez Sep 27 '12 at 22:32
  • Why don't you write the complete function in assembly ? Rest of the body is fairly trivial and should leverage you abilities to interleave instructions by hand (needs some skill) and easing register pressure by re-using some of them and doing optimizations based on what you know about your code (mostly more than compiler). – sgupta Sep 28 '12 at 06:02
  • This is just a test case, what I'm really trying to achieve is based on the ability to query a double precision register (d8) to retrieve it's value and copy it into a C variable. This C variable will be cheked for it's value to change, and if it's value is different from an arbitrary one, I'll do something (raise a SIGINT). I know I can achieve it using othe techniques, but what I really want to know is why I cannot use this inline. Where is the problem with it. – Juan Gómez Sep 28 '12 at 09:17

1 Answers1

4

I've changed the code part as below,

"vmov.f64 %P[dTmp2], d8\n"

after this I can compile. I didn't verify the produced code.

For P constraint please look at Hardwarebug / ARM inline asm secrets and this email thread.

auselen
  • 27,577
  • 7
  • 73
  • 114