我正在尝试将应用程序移植到 ARM 的
arm-none-eabi-gcc
工具链。该应用程序旨在在裸机目标上运行。
在这种情况下,
-mabi
选项的唯一两个合适的值似乎是aapcs
和aapcs-linux
。从 Debian 文档 和 Embedded Linux from Source 我知道 aapcs-linux
使用固定的 4 字节枚举大小,而 aapcs
将枚举定义为“可变长度”。但是,我找不到任何有关可能存在其他差异(如果有)的信息。
有人知道这两个 ABI 选项之间的完整差异列表吗?
我已经下载了arm-none-eabi-gcc版本10.3-2021.10的源代码。
除了枚举大小之外,我还可以发现一个其他差异:
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS arm_init_libfuncs
...
/* Set up library functions unique to ARM. */
static void
arm_init_libfuncs (void)
{
machine_mode mode_iter;
/* For Linux, we have access to kernel support for atomic operations. */
if (arm_abi == ARM_ABI_AAPCS_LINUX)
init_sync_libfuncs (MAX_SYNC_LIBFUNC_SIZE);
所以从上面看来,额外的库函数是用
aapcs-linux
设置的。这是名为的函数:
void
init_sync_libfuncs (int max)
{
if (!flag_sync_libcalls)
return;
init_sync_libfuncs_1 (sync_compare_and_swap_optab,
"__sync_val_compare_and_swap", max);
init_sync_libfuncs_1 (sync_lock_test_and_set_optab,
"__sync_lock_test_and_set", max);
init_sync_libfuncs_1 (sync_old_add_optab, "__sync_fetch_and_add", max);
init_sync_libfuncs_1 (sync_old_sub_optab, "__sync_fetch_and_sub", max);
init_sync_libfuncs_1 (sync_old_ior_optab, "__sync_fetch_and_or", max);
init_sync_libfuncs_1 (sync_old_and_optab, "__sync_fetch_and_and", max);
init_sync_libfuncs_1 (sync_old_xor_optab, "__sync_fetch_and_xor", max);
init_sync_libfuncs_1 (sync_old_nand_optab, "__sync_fetch_and_nand", max);
init_sync_libfuncs_1 (sync_new_add_optab, "__sync_add_and_fetch", max);
init_sync_libfuncs_1 (sync_new_sub_optab, "__sync_sub_and_fetch", max);
init_sync_libfuncs_1 (sync_new_ior_optab, "__sync_or_and_fetch", max);
init_sync_libfuncs_1 (sync_new_and_optab, "__sync_and_and_fetch", max);
init_sync_libfuncs_1 (sync_new_xor_optab, "__sync_xor_and_fetch", max);
init_sync_libfuncs_1 (sync_new_nand_optab, "__sync_nand_and_fetch", max);
}
我还没有对此进行足够深入的研究,不知道在什么情况下
flag_sync_libcalls
可能是真的,在什么情况下它可能是假的。
也就是说,我的搜索没有显示任何对
arm_init_libfuncs
的直接调用,或使用 TARGET_INIT_LIBFUNCS
宏进行的调用,所以我不知道这种差异在实践中是否真的有什么意义。