Android GCC发出ARM idiv指令(续)
我想知道这是否适用于Krait 400 CPU。我采纳了一些建议 当我使用mcpu=cortexa15编译时,代码就会编译,并且在程序集转储中有效地看到udiv指令 不过,我想知道:Android GCC发出ARM idiv指令(续),android,gcc,arm,Android,Gcc,Arm,我想知道这是否适用于Krait 400 CPU。我采纳了一些建议 当我使用mcpu=cortexa15编译时,代码就会编译,并且在程序集转储中有效地看到udiv指令 不过,我想知道: 有可能让它与march=armv7-a一起工作吗?(未指定cpu;这是我最初使用它的方式) 我曾尝试使用mcpu=krait2,但由于我没有使用snapdragon llvm(我还不知道需要付出多大的努力),它无法识别它。是否可以从llvm获取cpu定义,并以某种方式使其可用于我的编译器 还有其他方法/补丁/技巧
/development/android-ndk-r8e/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc -DANDROID -DNEON -fexceptions -Wno-psabi --sysroot=/development/android-ndk-r8e/platforms/android-14/arch-arm -fpic -funwind-tables -funswitch-loops -finline-limit=300 -fsigned-char -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=neon -fdata-sections -ffunction-sections -Wa,--noexecstack -marm -fomit-frame-pointer -fstrict-aliasing -O3 -DNDEBUG
我得到的错误是:
Error: selected processor does not support ARM mode `udiv r1,r1,r3'
作为旁注,我必须说,我刚刚开始了解整个计划,因此我想把它放在一小步中,以了解我在做什么
提前谢谢
编辑1:
我尝试编译一个单独的模块,只包含udiv指令。该模块使用-mcpu=cortex-a15参数编译,而应用程序的其余部分使用-march=armv7-a参数编译。结果是(不知何故)函数调用开销影响了应用程序的时间性能。我无法获取内联代码,因为尝试内联会导致与我最初遇到的错误相同的错误。在尝试重新发明轮子之前,我将切换到Snapdragon,看看是否有更好的性能。谢谢大家的回答和提示
idiv
-可选Cortex-A指令支持汞合金,表示支持sdiv
和udiv
。Cortex-a的支持可通过ID\u ISAR0
cp15寄存器查询,以位为单位[27:24]
/* Get idiv support. */
unsigned int ISAR0;
int idiv;
__asm ("mrc 15, 0, %0, c0, c2, 0" :"=r" (ISAR0));
#ifdef __thumb2__
idiv = (ISAR0 & 0xf000000UL) ? 1 : 0;
#else
idiv = (ISAR0 & 0xf000000UL) == 0x2000000UL ? 1 : 0;
#endif
如果只有thumb2支持udiv
和sdiv
指令,则位[27:24]为0001
。如果位[27:24]为0010
,则两种模式都支持指令
由于gcc标志-march=armv7-a
等意味着代码应该在该类型的所有CPU上工作,并且该指令是可选的,因此gcc发出该指令将是错误的
您可以使用不同的标志编译不同的模块,例如
gcc -march=armv7-a -o general.o -c general.c
gcc -mcpu=cortex-a15 -D_USE_IDIV_=1 -o fast_idiv.o -c fast_div.c
这些模块可以链接在一起,上面的代码可以用于在运行时选择适当的例程。例如,两个文件可能都有
#include "fir_template.def"
这个文件可能有
#ifdef _USE_IDIV_
#define _FUNC(x) idiv_ ## x
#else
#define _FUNC(x) x
#endif
int _FUNC(fir8)(FILTER8 *filter, SAMPLE *data,)
{
....
}
如果您知道您的代码将仅在Cortex-a15上运行,则使用-mcpu
选项。如果您想让它运行得更快如果它可以并且是通用的(支持所有armv7-a CPU),那么您必须如上所述标识CPU并动态选择代码
附录:上述文件(general.c和fast_idiv.c)可以使用相同的API放在单独的共享库中。然后询问
/proc/cpuinfo
,查看是否支持idiv
。将LD\u库路径
(或dlopen()
)设置为适当的版本。选择将取决于所涉及的代码量。还有很多其他方法可以做到这一点。将来,gcc
可能支持ARM上的调谐函数别名;但我认为这目前仅在x86上可用。然而,这个想法总是有效的;在运行时使用两组函数和ID。cortex-a5可能是最好的,因为它支持idiv,并且是最低的公分母。还有其他可选的指令需要处理fast_idiv.c不会发出的问题。请参阅其他问题以了解可能的cpu.Err。你有一个;你将不得不根据链接以另一种方式识别它。我想知道你是否可以用你自己的“u aeabi_idiv”实现欺骗gcc,并期望链接时间优化能够完美地修复它。所以我要说的是使用armv7a开关并提供你自己的包含硬件分区的idiv,您能否获得使用hw div支持编译的最终二进制文件。@auselen使用multi-lib时,您可能能够将\uuuu-aeabi\u-idiv
链接到类似udiv r0、r1、r2\n bx lr\n
的例程,但使用idiv
直接调用函数的优点是无需函数调用或寄存器杂耍。我想可能会更好;但我认为我在上面提出的方法在目前的工具状态下是最快的。如果你使用ndk,你不能进行这样的黑客攻击,并期望它能与许多目标协同工作。如果你想玩krait,就用a15。这将是最简单的。@auselen感谢您注意到它是Android。对于查询idiv
支持,我给出了一个简单的答案;如果您有Linux,/proc/cpuinfo是最好的信息源。当我有时间时,我会尝试删除ISAR0并将所有评论合并到我的答案中…谢谢@auselen和artless noise。我理解,如果实现了这一点,那么代码(可能)只能与支持idiv的Armv7-a CPU一起工作。当你说:“如果你想玩krait,那就用a15吧。”你的意思是说它最容易编译?(即切换gcc的标志)。我有点担心生成的代码是为我实际上没有的CPU定制的。目前,我无法评估这一变化的影响。我想我也会寻找有关这方面的文献。