Reputation: 21
I'm trying to compile a small program for arm7tdmi
(i.e. armv4t
), using the command arm-linux-gnueabi-gcc -march=armv4t -mcpu=arm7tdmi -nostartfiles -static test.c -o test
on Debian (gcc version 10.2.1, Debian 10.2.1-6). However, GCC seems to ignore the cpu and arch flags, and generates instructions that are unsupported on armv4t
, e.g. clz
, as shown by objdump
:
104f4: 0a000071 beq 106c0 <.divsi3_skip_div0_test+0x1f0>
104f8: e16f2f13 clz r2, r3
104fc: e16f0f11 clz r0, r1
10500: e0402002 sub r2, r0, r2
10504: e272201f rsbs r2, r2, #31
I also checked the binary using readelf
, and it shows the architecture is actually armv5te
:
File Attributes
Tag_CPU_name: "5TE"
Tag_CPU_arch: v5TE
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
May I ask what's going on here? Why is GCC ignoring the -mcpu
and -march
flags?
Here's the content of test.c
:
#include <stdint.h>
#include <stddef.h>
void _start() {
const size_t len = 8;
uint8_t arr[8] = {10, 12, 8, 5, 0, 2, 3, 55};
uint8_t *data = arr;
uint16_t a = 1, b = 0, m = 7;
for(int i=0; i<len; i++) {
a = (a + data[i]) % m;
b = (a + b) % m;
}
uint32_t res = (uint32_t)b << 16 | (uint32_t)a;
}
Upvotes: 2
Views: 457
Reputation: 22420
You also need to add '-nostdlib' or it will drag in files that have been compiled with Armv5. The 'arm-linux' kernel does not support ARMv4 CPUs as they do not have an MMU. You are viewing assembler from the gcc library which is compiled for Armv5.
The example label divsi3, shows that you are using division operation and this is coded in libgcc, which will link with the code. It is brought in by your % m
code.
You can code and supply your own divsi3, or get a compiler library that supports Armv4. The libgcc.a must be generated (downgraded) to support that CPU. Gcc's backend is capable of generating code for all members of the ARM32/Thumb family, but not support libraries (without multi-lib support).
There is no bug in the compiler. If you look at the assembler for _start, it will not contain clz
. If the % 7
could be % 8
, you can downgrade to a &7
and the divsi3 would not be needed.
You can see why here.
It is a variation on this question. The issue is that the linker 'gnu ld' has no flag to say, reject Armv5 code.
divsi3
configured with Armv4.divsi3
with a Division algorithm.&
).Upvotes: 2