Вы можете сделать это для двух регистров, используя "long long", как указано в ссылке "Стандарт вызова процедур для архитектуры ARM", приведенной на этой странице.
long long test(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
long long ret;
ret = a+b;
ret <<= 32;
ret |= c + d;
return ret;
}
будет просто скомпилировано как:
0002dbb8 <test>:
2dbb8: 1841 adds r1, r0, r1
2dbba: 18d0 adds r0, r2, r3
2dbbc: 4770 bx lr
и ret & 0xFFFFFFFF
и ret >> 32
в вызывающей функции будут легко заменены на r0 и r1.
Можно даже сделать это для регистров r0-r3, используя "Containerized
векторы ":
typedef uint32_t uint32x4_t __attribute__ ((vector_size (16)));
uint32x4_t test2(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
uint32x4_t ret = { a + 1, b + 2, c + 3, d + 4};
// to access elements: ret[0], ret[1], ...
return ret;
}
, который составляется как:
0002dbb8 <test2>:
2dbb8: 3001 adds r0, #1
2dbba: 3102 adds r1, #2
2dbbc: 3203 adds r2, #3
2dbbe: 3304 adds r3, #4
2dbc0: 4770 bx lr
Обратите внимание, что в приведенном выше документе она упоминается как функция SIMD / NEON, но я только что достиг ее на Cortex M0 в режиме Thumb, без поддержки NEON.