GCC发出ARM idiv指令

aus*_*len 9 gcc arm

我如何指示gcc发出idiv(整数除法udivsdiv)指令arm application processors

到目前为止,我能想出的唯一方法是使用-mcpu=cortex-a15gcc 4.7.

$cat idiv.c
int test_idiv(int a, int b) {
    return a / b;
}
Run Code Online (Sandbox Code Playgroud)

在gcc 4.7上(与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
Run Code Online (Sandbox Code Playgroud)

idiv.c:1:0: warning: switch -mcpu=cortex-a15 conflicts with -march=armv7-a switch [enabled by default]如果你在-march=armv7-a旁边添加-mcpu=cortex-a15并且不发出idiv指令,那么即使这个也给出了.

$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}
Run Code Online (Sandbox Code Playgroud)

在gcc 4.6(与Android NDK r8e捆绑在一起)它根本不发出idiv指令但是识别-mcpu=cortex-a15也不会抱怨-mcpu=cortex-a15 -march=armv7-a组合.

Afaik idiv是可选的armv7,所以应该有一个更清晰的方式来指示gcc发出它们但是如何?

art*_*ise 5

如果指令不在机器描述中,那么我怀疑它gcc会发出代码.注1

如果编译器不支持,您可以始终使用inline-assembler来获取指令.注意2 由于您op-code的资源相当罕见/特定于机器,因此在gcc源代码中可能没有那么多努力.特别是,有archtune/cpu标志.该调/ CPU是一个更具体的机器,但是假设允许所有的机器在这个架构.op-code如果我明白的话,这似乎打破了这条规则.

对于gcc4.6.2,看起来像thumb2cortex-r4是使用这些指令的提示,正如您在gcc4.7.2中所述,似乎添加了cortex-a15以使用这些指令.使用gcc4.7.2,thumb2.md文件不再具有udiv/ sdiv.但是,它可能包含在其他地方; 我不是100%熟悉所有的机器描述语言.似乎皮质-a7,皮质-a15皮质-r5也可以使用4.7.2来实现这些指令.注3

这不直接回答问题,但它确实提供了一些信息/路径来得到答案.您可以使用编译模块-mcpu=cortex-r4,尽管这可能会产生链接器问题.此外,还int my_idiv(int a, int b) __attribute__ ((__target__ ("arch=cortexe-r4")));可以在每个函数的基础上指定代码生成器使用的机器描述.我自己没有使用过这些,但它们只是尝试的可能性.通常,您不希望保留错误的机器,因为它可能会生成次优(也可能是非法)操作码.你将不得不进行实验,然后才能提供真正的答案.

注1:这是针对股票 gcc 4.6.2和4.7.2.我不知道你的Android编译器是否有补丁.

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")]
Run Code Online (Sandbox Code Playgroud)
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"))
Run Code Online (Sandbox Code Playgroud)

注2:请参见预处理器汇编如果gcc正在通过选项来gas阻止使用的udiv/sdiv指示.例如,你可以使用asm(" .long <opcode>\n");其中的操作码是一些象征性的粘贴字符串化寄存器编码的宏输出.此外,您可以注释汇编程序以指定更改machine.所以你可以暂时说谎并说你有皮质-r4等.

注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"
Run Code Online (Sandbox Code Playgroud)