GCC ARM 汇编预处理器宏 [英] GCC ARM Assembly Preprocessor Macro

查看:38
本文介绍了GCC ARM 汇编预处理器宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用程序集(ARM)宏进行定点乘法:

I am trying to use an assembly(ARM) macro 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" );

但是在尝试编译时出现错误:asm"之前的预期表达式

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

(如果你珍惜你的时间,你可以忽略下面的所有内容,但如果你看看它会很好,这里的主要问题是如何使上述工作)

(You can ignore everything below this if you value your time but it would be nice if you took a look at it, the main question here is how to make the above work)

我试过了:

    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; }

这可以编译,但似乎有问题,因为当我使用常量时,例如:MULT(65536,65536) 它可以工作,但是当我使用变量时,它似乎很糟糕:

This compiles but there seems to be a problem because when I use constants ex: MULT(65536,65536) it works but when I use variables it seems to 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;
}

上面的代码会打印出来(LOG就像这里的printf):

The above code will print(LOG is like 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 would be(obviously alot of junk in the above):

0,0,0
65536,0,0,0
0,65536,0,0
0,0,65536,0
0,0,0,65536

推荐答案

您是否尝试过简单的 C 代码而不是汇编?在我的 GCC 4.5.3 系统上,编译器生成的代码至少与您的手写汇编器一样好:

Have you tried simple C-code instead of assembly? On my system with GCC 4.5.3 the compiler generates code that is at least as good as your hand written assembler:

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

编译为以下汇编代码:

# 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

(删除函数调用结语和序言)

(Function call epilog and prolog removed)

如果在单个函数中有多个乘法,代码会变得更好,因为编译器会删除多余的 mov r3, #32768 指令.

The code becomes even better if you have multiple multiplications in a single function because the compiler will remove the redundant mov r3, #32768 instructions.

这篇关于GCC ARM 汇编预处理器宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆