ARMv7 gcc选项强制进行自然除法

时间:2018-10-08 18:53:53

标签: gcc arm

我正在使用GCC为支持本机划分的ARMv7内核构建裸机应用程序。我删除了所有库依赖项。

GCC C编译器有时会引用__aeabi_uidiv()。其他时候,它将选择使用硬件除法(用于无符号整数除法)。我一直找不到能够迫使其使用硬件除法器(而不是__aeabi_ * lib调用)的编译器标志。有人知道这样的标志吗?

编辑:我应该澄清一下,我为i.MX6ULL使用了编译器标志-mtune = cortex-a7和-march = armv7-a。

示例错误:

uint32_t GenerateError(uint32_t num, uint32_t den) {
    return num / den; //generates undefined reference to __aeabi_uidiv
}

2 个答案:

答案 0 :(得分:1)

gcc就是这样的编译器。

uint8_t fun_u8 ( uint8_t a, uint8_t b )
{
    return(a/b);
}
uint16_t fun_u16 ( uint16_t a, uint16_t b )
{
    return(a/b);
}
uint32_t fun_u32 ( uint32_t a, uint32_t b )
{
    return(a/b);
}
uint64_t fun_u64 ( uint64_t a, uint64_t b )
{
    return(a/b);
}

int8_t fun_s8 ( int8_t a, int8_t b )
{
    return(a/b);
}
int16_t fun_s16 ( int16_t a, int16_t b )
{
    return(a/b);
}
int32_t fun_s32 ( int32_t a, int32_t b )
{
    return(a/b);
}
int64_t fun_s64 ( int64_t a, int64_t b )
{
    return(a/b);
}

构建

arm-none-eabi-gcc -O2 -mcpu = cortex-a7 -c so.c -o so.o

结果

00000000 <fun_u8>:
   0:   e730f110    udiv    r0, r0, r1
   4:   e12fff1e    bx  lr

00000008 <fun_u16>:
   8:   e730f110    udiv    r0, r0, r1
   c:   e12fff1e    bx  lr

00000010 <fun_u32>:
  10:   e730f110    udiv    r0, r0, r1
  14:   e12fff1e    bx  lr

00000018 <fun_u64>:
  18:   e92d4010    push    {r4, lr}
  1c:   ebfffffe    bl  0 <__aeabi_uldivmod>
  20:   e8bd8010    pop {r4, pc}

00000024 <fun_s8>:
  24:   e730f110    udiv    r0, r0, r1
  28:   e12fff1e    bx  lr

0000002c <fun_s16>:
  2c:   e710f110    sdiv    r0, r0, r1
  30:   e6bf0070    sxth    r0, r0
  34:   e12fff1e    bx  lr

00000038 <fun_s32>:
  38:   e710f110    sdiv    r0, r0, r1
  3c:   e12fff1e    bx  lr

00000040 <fun_s64>:
  40:   e92d4010    push    {r4, lr}
  44:   ebfffffe    bl  0 <__aeabi_ldivmod>
  48:   e8bd8010    pop {r4, pc}

根据正确的arm文档,最大支持32位/ 32位的硬件。除此之外,您必须调用一个库(乘积也是如此)以确认期望值可以添加:

uint8_t fun_m8 ( uint32_t a, uint8_t b )
{
    return(a/b);
}
uint16_t fun_m16 ( uint32_t a, uint16_t b )
{
    return(a/b);
}
uint32_t fun_m32 ( uint32_t a, uint32_t b )
{
    return(a/b);
}

0000004c <fun_m8>:
  4c:   e730f110    udiv    r0, r0, r1
  50:   e6ef0070    uxtb    r0, r0
  54:   e12fff1e    bx  lr

00000058 <fun_m16>:
  58:   e730f110    udiv    r0, r0, r1
  5c:   e6ff0070    uxth    r0, r0
  60:   e12fff1e    bx  lr

00000064 <fun_m32>:
  64:   e730f110    udiv    r0, r0, r1
  68:   e12fff1e    bx  lr

在那里没有惊喜。

现在这是手臂模式,编译器通常会以拇指模式...

00000000 <fun_u8>:
   0:   fbb0 f0f1   udiv    r0, r0, r1
   4:   4770        bx  lr
   6:   bf00        nop

00000008 <fun_u16>:
   8:   fbb0 f0f1   udiv    r0, r0, r1
   c:   4770        bx  lr
   e:   bf00        nop

...

在此平台上,没有变化的thumb2也支持除法,因此其大于它所支持的编译代码要求的范围,该要求决定了是否可以使用硬件指令,并且对于该测试,gcc选择了所需的硬件指令,而不是一个gcclib调用(可能的话)。

如果希望编译器使用硬件指令,则指示编译器使用所需的指令集。并将您的代码保持在该指令集的功能范围内。并使用同样针对感兴趣的指令集编译的库,并且代码不会超出该指令集的范围。 (然后查看编译器是使用整个指令集还是至少使用感兴趣的指令,如果不使用,则使您自己的库函数进行汇编分割并调用它。)

答案 1 :(得分:1)

您要寻找的是-march=armv7ve。这将针对带有硬件除法指令的Armv7。 -mcpu=cortex-a15cortex-a7以此架构为目标,因此它们将生成除法指令。