海湾合作委员会发出的ARM指令IDIV [英] GCC to emit ARM idiv instructions

查看:412
本文介绍了海湾合作委员会发出的ARM指令IDIV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎么能指示 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(捆绑的Andr​​oid 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。我不知道,如果你的Andr​​oid编译器的补丁。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆