Я пытаюсь использовать макрос сборки (ARM) для умножения с фиксированной запятой:
#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 '
(Вы можете игнорировать все, что ниже этого, если цените свое время, но было бы неплохо, если бы вы посмотрели на него, основной вопрос здесь заключается в том, как заставить вышеуказанное работать)
Я пробовал это:
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; }
Это компилируется, но, похоже, есть проблема, потому что когда я использую константы ex: MULT (65536,65536), это работает, но когда я использую переменные, кажется, что 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):
0,0,-1411346156
65536,65536,65536,440
-2134820096,65536,0,-1345274311
0,65536,22,220
65536,196608,131072,65536
Когда правильный результат будет (очевидно, много мусора в приведенном выше):
0,0,0
65536,0,0,0
0,65536,0,0
0,0,65536,0
0,0,0,65536