GCC ARM Assembly Preprocessor Macro

I am trying to use assembly macro (ARM) for fixed point multiplication:

    #define MULT(a,b) __asm__ __volatile__ ( \
        "SMULL r2, r3, %0, %1\n\t" \
        "ADD r2, r2, #0x8000\n\t" \
        "ADC r3, r3, #0\n\t" \
        "MOV %0, r2, ASR#16\n\t" \
        "ORR %0, %0, r3, ASL#16" \
        : "=r" (a) : "0"(a), "1"(b) : "r2", "r3" );

but when I try to compile I get the error (s): expected expression before asm '

(You can ignore anything below this if you value your time, but it would be nice if you looked at it, the main question here is how to do the above work)

I tried this:

    static inline GLfixed MULT(GLfixed a, GLfixed b){
       asm volatile(
        "SMULL r2, r3, %[a], %[b]\n"
        "ADD r2, r2, #0x8000\n"
        "ADC r3, r3, #0\n"
        "MOV %[a], r2, ASR#16\n"
        "ORR %[a], %[a], r3, ASL#16\n"
        : "=r" (a)
        : [a] "r" (a), [b] "r" (b)
        : "r2", "r3");
     return a; }

This compiles, but it seems that the problem arises because when I use the ex: MULT constants (65536,65536), it works, but when I use the variables, it seems f ** k up:

GLfixed m[16];
m[0]=costab[player_ry];//1(65536 integer representation)
m[5]=costab[player_rx];//1(65536 integer representation)
m[6]=-sintab[player_rx];//0
m[8]=-sintab[player_ry];//0
LOG("%i,%i,%i",m[6],m[8],MULT(m[6],m[8]));
m[1]=MULT(m[6],m[8]);
m[2]=MULT(m[5],-m[8]);
m[9]=MULT(-m[6],m[0]);
m[10]=MULT(m[5],m[0]);
m[12]=MULT(m[0],0)+MULT(m[8],0);
m[13]=MULT(m[1],0)+MULT(m[5],0)+MULT(m[9],0);
m[14]=MULT(m[2],0)+MULT(m[6],0)+MULT(m[10],0);
m[15]=0x00010000;//1(65536 integer representation)

int i=0;
while(i<16)
{
    LOG("%i,%i,%i,%i",m[i],m[i+1],m[i+2],m[i+3]);
    i+=4;
}

The above code will print (LOG as printf here):

0,0,-1411346156
65536,65536,65536,440
-2134820096,65536,0,-1345274311
0,65536,22,220
65536,196608,131072,65536

When the correct result is obtained (obviously, a lot of garbage in the above example):

0,0,0
65536,0,0,0
0,65536,0,0
0,0,65536,0
0,0,0,65536
+5
2

C- ? GCC 4.5.3 , , :

int mul (int a, int b)
{
  long long x = ((long long)a * b + 0x8000);
  return x>>16;
}

asm-:

# input: r0, r1
mov    r3, #32768
mov    r4, #0
smlal  r3, r4, r0, r1
mov    r0, r3, lsr #16
orr    r0, r0, r4, asl #16
# result in r0

( epilog )

, , mov r3, # 32768.

+3

: , __asm__ , .

GCC , - - :

#define MULT(a,b) \
  ({ \
    __asm__ __volatile__ ( \
      /* ... asm stuff here ... */
    ); \
    a; \
  })

. , . :

: "=r" (a) : "0"(a), "1"(b) : "r2", "r3"

  • a ( 0);
  • a , 0, ( 1);
  • b , 1, .. ( 2).

"r"(b) %2.

:

: "=r" (a) : [a] "r" (a), [b] "r" (b) : "r2", "r3"

a, a b ,

  • - ;
  • asm ( , asm %0).

: "=r" (a) : "0" (a), "r" (b) : "r2", "r3"

a %0 %1, b %2.

​​ :

: [a] "=r" (a) : "[a]" (a), [b] "r" (b) : "r2", "r3"

%[a] %[b].

, -

: [arg_a] "=r" (a) : "[arg_a]" (a), [arg_b] "r" (b) : "r2", "r3"

( %[arg_a] %[arg_b]), a b [a] [b].

: ( a), [a] - , ( a), : "[a]".

+5

All Articles