海湾合作委员会发出的ARM指令IDIV [英] GCC to emit ARM idiv instructions
问题描述
我怎么能指示 GCC
发出 IDIV
(整数除法, UDIV
和 SDIV
)的 ARM应用处理器的指令
?
How can I instruct gcc
to emit idiv
(integer division, udiv
and sdiv
) instructions for arm application processors
?
到目前为止,只有我能想出的办法是使用 -mcpu =的Cortex-A15
用gcc 4.7。
So far only way I can come up with is to use -mcpu=cortex-a15
with gcc 4.7.
$cat idiv.c
int test_idiv(int a, int b) {
return a / b;
}
在GCC 4.7(捆绑的Android NDK R8E )
On gcc 4.7 (bundled with Android NDK r8e)
$gcc -O2 -mcpu=cortex-a15 -c idiv.c
$objdump -S idiv.o
00000000 <test_idiv>:
0: e710f110 sdiv r0, r0, r1
4: e12fff1e bx lr
甚至这个人给 idiv.c:1:0:警告:开关-mcpu =的Cortex-A15与-march =的ARMv7-A开关[默认启用]冲突
如果您添加 -march =的ARMv7-A
旁边的 -mcpu =的Cortex-A15
和不发射 IDIV
指令。
Even this one gives idiv.c:1:0: warning: switch -mcpu=cortex-a15 conflicts with -march=armv7-a switch [enabled by default]
if you add -march=armv7-a
next to -mcpu=cortex-a15
and doesn't emit idiv
instruction.
$gcc -O2 -mcpu=cortex-a15 -march=armv7-a -c idiv.c
idiv.c:1:0: warning: switch -mcpu=cortex-a15 conflicts with -march=armv7-a switch [enabled by default]
$objdump -S idiv.o
00000000 <test_idiv>:
0: e92d4008 push {r3, lr}
4: ebfffffe bl 0 <__aeabi_idiv>
8: e8bd8008 pop {r3, pc}
在GCC 4.6(与Android NDK R8E捆绑),它不发射 IDIV
指示不惜一切,但承认 -mcpu =的Cortex-A15
也没有抱怨 -mcpu =的Cortex-A15 -march =的ARMv7-A
组合。
On gcc 4.6 (bundled with Android NDK r8e) it doesn't emit idiv
instructions at all but recognizes -mcpu=cortex-a15
also doesn't complain to -mcpu=cortex-a15 -march=armv7-a
combination.
据我所知 IDIV
是可选的的ARMv7
,所以应该有指示GCC发出他们一个更清洁的方式,但怎么样?
Afaik idiv
is optional on armv7
, so there should be a cleaner way to instruct gcc to emit them but how?
推荐答案
如果该指令不是在机器描述的,那么我怀疑 GCC
将发出code。 注1
If the instruction is not in the machine descriptions, then I doubt that gcc
will emit code. Note1
您可以随时使用的内联汇编的以得到指令,如果编译器不支持它。注2 由于您的选项$ C $ ç
是相当罕见/该机的具体,有可能是没有这么多的努力,得到它在<code> GCC 来源。尤其是还有的拱的和的调/ CPU 的标志。在调/ CPU 的是一个更具体的机器,但是的拱的是假设允许该架构所有的机的。这选项code
似乎打破这个规则,如果我没有理解。
You can always use inline-assembler to get the instruction if the compiler is not supporting it.Note2 Since your op-code
is fairly rare/machine specific, there is probably not so much effort to get it in the gcc
source. Especially, there are arch and tune/cpu flags. The tune/cpu is for a more specific machine, but the arch is suppose to allow all machines in that architecture. This op-code
seems to break that rule, if I understand.
有关 GCC
4.6.2,它看起来像的 thumb2 和的Cortex-R4 的有线索使用这些说明正如你曾与 GCC
4.7.2,注意到的的Cortex-A15 的似乎要添加到使用这些指令。随着 GCC
4.7.2,在 thumb2.md 的文件不再具有 UDIV
/ SDIV
。但是,它可能还包含其它地方;我熟悉所有的机器描述的语言不是100%。这也似乎的的Cortex-A7 的的Cortex-A15 和的Cortex-R5 的可实现与4.7.2这些说明。 注3
For gcc
4.6.2, it looks like thumb2 and cortex-r4 are cues to use these instructions and as you have noted with gcc
4.7.2, the cortex-a15 seems to be added to use these instructions. With gcc
4.7.2, the thumb2.md file no longer has udiv
/sdiv
. However, it might be included somewhere else; I am not 100% familiar with all the machine description language. It also seems that cortex-a7, cortex-a15, and cortex-r5 may enable these instructions with 4.7.2. Note3
这并没有直接回答这个问题,但它确实给一些资料/路径得到答案。你可以编译 -mcpu =的Cortex-R4
模块,虽然这可能会产生问题的链接。此外,还有 INT my_idiv(int类型的,INT B)__attribute__((__target__(弓= cortexe-R4)));
,在那里你可以在每个指定 - 函数基础上的机器的描述的由code发电机使用。我没有使用任何这些我自己,但它们毕竟只是可能性尝试。一般来说,你不想保持误机,因为它可能产生次优的(也可能是非法的)OP-codeS。你将不得不尝试,也许然后提供的真正的答案。
This doesn't answer the question directly, but it does give some information/path to get the answer. You can compile the module with -mcpu=cortex-r4
, although this may produce linker issues. Also, there is int my_idiv(int a, int b) __attribute__ ((__target__ ("arch=cortexe-r4")));
, where you can specify on a per-function basis the machine-description used by the code generator. I haven't used any of these myself, but they are only possibilities to try. Generally you don't want to keep the wrong machine as it could generate sub-optimal (and possibly illegal) op-codes. You will have to experiment and maybe then provide the real answer.
注1:这是一个的股票的 GCC
4.6.2和4.7.2。我不知道,如果你的Android编译器的补丁。
Note1: This is for a stock gcc
4.6.2 and 4.7.2. I don't know if your Android compiler has patches.
gcc-4.6.2/gcc/config/arm$ grep [ius]div *.md
arm.md: "...,sdiv,udiv,other"
cortex-r4.md:;; We guess that division of A/B using sdiv or udiv, on average,
cortex-r4.md:;; This gives a latency of nine for udiv and ten for sdiv.
cortex-r4.md:(define_insn_reservation "cortex_r4_udiv" 9
cortex-r4.md: (eq_attr "insn" "udiv"))
cortex-r4.md:(define_insn_reservation "cortex_r4_sdiv" 10
cortex-r4.md: (eq_attr "insn" "sdiv"))
thumb2.md: "sdiv%?\t%0, %1, %2"
thumb2.md: (set_attr "insn" "sdiv")]
thumb2.md:(define_insn "udivsi3"
thumb2.md: (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
thumb2.md: "udiv%?\t%0, %1, %2"
thumb2.md: (set_attr "insn" "udiv")]
gcc-4.7.2/gcc/config/arm$ grep -i [ius]div *.md
arm.md: "...,sdiv,udiv,other"
arm.md: "TARGET_IDIV"
arm.md: "sdiv%?\t%0, %1, %2"
arm.md: (set_attr "insn" "sdiv")]
arm.md:(define_insn "udivsi3"
arm.md: (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
arm.md: "TARGET_IDIV"
arm.md: "udiv%?\t%0, %1, %2"
arm.md: (set_attr "insn" "udiv")]
cortex-a15.md:(define_insn_reservation "cortex_a15_udiv" 9
cortex-a15.md: (eq_attr "insn" "udiv"))
cortex-a15.md:(define_insn_reservation "cortex_a15_sdiv" 10
cortex-a15.md: (eq_attr "insn" "sdiv"))
cortex-r4.md:;; We guess that division of A/B using sdiv or udiv, on average,
cortex-r4.md:;; This gives a latency of nine for udiv and ten for sdiv.
cortex-r4.md:(define_insn_reservation "cortex_r4_udiv" 9
cortex-r4.md: (eq_attr "insn" "udiv"))
cortex-r4.md:(define_insn_reservation "cortex_r4_sdiv" 10
cortex-r4.md: (eq_attr "insn" "sdiv"))
注2:查看<一个href=\"http://stackoverflow.com/questions/15465958/using-gccs-$p$p-processor-as-an-assembler\">$p$p-processor作为汇编如果 GCC
是传递选项气体
是prevent使用<$ C的$ C> UDIV / SDIV 的说明。例如,你可以使用 ASM(。长&LT; OP code&GT; \\ n);
其中的运算code 的是一些象征性的粘贴字符串化注册EN code宏输出。此外,您还可以注释你的汇编指定在机
的变化。所以,你可以暂时的谎言的,说你有一个的的Cortex-R4 的等。
Note2: See pre-processor as Assembler if gcc
is passing options to gas
that prevent use of the udiv/sdiv
instructions. For example, you can use asm(" .long <opcode>\n");
where opcode is some token pasted stringified register encode macro output. Also, you can annotate your assembler to specify changes in the machine
. So you can temporarily lie and say you have a cortex-r4, etc.
注3:
gcc-4.7.2/gcc/config/arm$ grep -E 'TARGET_IDIV|arm_arch_arm_hwdiv|FL_ARM_DIV' *
arm.c:#define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */
arm.c:int arm_arch_arm_hwdiv;
arm.c: arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
arm-cores.def:ARM_CORE("cortex-a7", cortexa7, 7A, ... FL_ARM_DIV
arm-cores.def:ARM_CORE("cortex-a15", cortexa15, 7A, ... FL_ARM_DIV
arm-cores.def:ARM_CORE("cortex-r5", cortexr5, 7R, ... FL_ARM_DIV
arm.h: if (TARGET_IDIV) \
arm.h:#define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv) \
arm.h:extern int arm_arch_arm_hwdiv;
arm.md: "TARGET_IDIV"
arm.md: "TARGET_IDIV"
这篇关于海湾合作委员会发出的ARM指令IDIV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!