Код
typedef signed long fr32;
typedef signed long long fx64;
fr32 fr32_mul(fr32 arg1, fr32 arg2)
{
fr32 result;
asm
(
"smull ip, r3, %1, %2 \n"
"mov ip, ip, lsr #%a3 \n"
"orr %0, ip, r3, lsl #2 \n"
: "=r" (result)
: "r" (arg1), "r" (arg2), "I" (FR32_FRACTION_BITS)
: "r3", "ip"
);
return result;
}
typedef signed long long fx64;
fr32 fr32_mul(fr32 arg1, fr32 arg2)
{
fr32 result;
asm
(
"smull ip, r3, %1, %2 \n"
"mov ip, ip, lsr #%a3 \n"
"orr %0, ip, r3, lsl #2 \n"
: "=r" (result)
: "r" (arg1), "r" (arg2), "I" (FR32_FRACTION_BITS)
: "r3", "ip"
);
return result;
}
В нём аргумены и результат ("=r" (result), "r" (arg1), "r" (arg2)) 32-битные, а как описать 64-битные данные непонятно?
Код
fx64 fx64_mul(fx64 arg1, fx64 arg2)
{
fx64 result;
asm
(
...
: "=r" (result) // <- Какие модификатор тут должны быть ?
: "r" (arg1), "r" (arg2) // <- Какие модификатор тут должны быть ?
);
return result;
}
{
fx64 result;
asm
(
...
: "=r" (result) // <- Какие модификатор тут должны быть ?
: "r" (arg1), "r" (arg2) // <- Какие модификатор тут должны быть ?
);
return result;
}
Есть, конечно, вариант реализовать аргументы и результат через объединение:
Код
union
{
fx64 value;
struct
{
signed long msw;
unsigned long lsw;
} words;
};
{
fx64 value;
struct
{
signed long msw;
unsigned long lsw;
} words;
};
Но может, есть способ проще?
К слову сказать для msp430 gcc существуют модификаторы:
Код
• %A[tag] acts as %[tag] for a register or address constant operand, or wraps an integer value as #llo(). #llo is an
assembler macro, which extracts the lower 16 bits of the value.
• %B[tag] adds 1 to a register number, or 2 to an address constant, or substitutes #lhi() for an integer constant.
• %C[tag] adds 2 to a register number, or 4 to an address constant, or substitutes #hlo() for an integer constant.
• %D[tag] adds 3 to a register number, 6 to an address constant, or substitutes #hhi() for an integer constant.
#define LONGVAL 0x12345678l
{
long a, b;
...
asm("mov %A2, %A0 \n\t"
"mov %B2, %B0 \n\t"
"mov %A2, %A1 \n\t"
"mov %B2, %B1 \n\t"
: "=r"((long)a), "=m"((long)b)
: "i"((long)LONGVAL) );
...
}
assembler macro, which extracts the lower 16 bits of the value.
• %B[tag] adds 1 to a register number, or 2 to an address constant, or substitutes #lhi() for an integer constant.
• %C[tag] adds 2 to a register number, or 4 to an address constant, or substitutes #hlo() for an integer constant.
• %D[tag] adds 3 to a register number, 6 to an address constant, or substitutes #hhi() for an integer constant.
#define LONGVAL 0x12345678l
{
long a, b;
...
asm("mov %A2, %A0 \n\t"
"mov %B2, %B0 \n\t"
"mov %A2, %A1 \n\t"
"mov %B2, %B1 \n\t"
: "=r"((long)a), "=m"((long)b)
: "i"((long)LONGVAL) );
...
}
А вот для arm gcc, я что-то подобного не нашёл.