Message ID | 1380209693.38971.YahooMailNeo@web162205.mail.bf1.yahoo.com |
---|---|
State | Rejected |
Headers | show |
Hello, On Thu, 26 Sep 2013 08:34:53 -0700 (PDT), adam hussein\(!\) wrote: > I've been building the at91rm9200ek configuration of buildroot to get > a toolchain I can use to build u-boot with some board specific > configuration. > > This is an ARM920T core chip with ARMv4T architecture - later ARM9 > series have ARMv5TE architecture (http://en.wikipedia.org/wiki/ARM9) > > When gcc is built, or perhaps specifically libgcc only, it seems the > selection of 920t/v4 architecture gets lost and v5 is used instead. > This means that when I use it to build u-boot, I find it has the > __udivsi3 function using the illegal (to v4) instruction CLZ (count > leading zeros). > > The easiest workaround for me is to specify arm7tdmi and be done with > it, but I'd like to try contributing a proper fix if possible. > > It turns out that this issue has been around for some time: > > e.g. 2006: http://www.mail-archive.com/oe@handhelds.org/msg02024.html > e.g. 2007: > http://permalink.gmane.org/gmane.comp.lib.uclibc.buildroot/3139 e.g. > 2007: > http://web.archive.org/web/20070815094037/http://bugs.busybox.net/view.php?id=1406 > (referred to in previous link) > > and then the last link has this patch: > http://web.archive.org/web/20070815094037/http://bugs.busybox.net/file_download.php?file_id=1059&type=bug > > ...which seems not to have made it into the main repo, and no longer > applies correctly; all the locations have changed. > > > So, here follows an up-to-date version of it. I hope someone finds it > useful and avoids repeating all my 'digging about'. > > And many thanks to 'bjdooks' for the original. Interesting. First, thanks for the investigation. When you select BR2_arm920t as the ARM processor, we are already passing --with-arch=armv4t to the gcc configure. So, gcc should already avoid the use of CLZ, since ARMv4T does not support it. Have you investigated why passing the --with-cpu argument is also needed, in addition to --with-arch? Thanks! Thomas
Thomas, Adam, All, On 2013-09-26 17:54 +0200, Thomas Petazzoni spake thusly: > Hello, > > On Thu, 26 Sep 2013 08:34:53 -0700 (PDT), adam hussein\(!\) wrote: > > I've been building the at91rm9200ek configuration of buildroot to get > > a toolchain I can use to build u-boot with some board specific > > configuration. > > > > This is an ARM920T core chip with ARMv4T architecture - later ARM9 > > series have ARMv5TE architecture (http://en.wikipedia.org/wiki/ARM9) > > > > When gcc is built, or perhaps specifically libgcc only, it seems the > > selection of 920t/v4 architecture gets lost and v5 is used instead. > > This means that when I use it to build u-boot, I find it has the > > __udivsi3 function using the illegal (to v4) instruction CLZ (count > > leading zeros). > > > > The easiest workaround for me is to specify arm7tdmi and be done with > > it, but I'd like to try contributing a proper fix if possible. > > > > It turns out that this issue has been around for some time: > > > > e.g. 2006: http://www.mail-archive.com/oe@handhelds.org/msg02024.html > > e.g. 2007: > > http://permalink.gmane.org/gmane.comp.lib.uclibc.buildroot/3139 e.g. > > 2007: > > http://web.archive.org/web/20070815094037/http://bugs.busybox.net/view.php?id=1406 > > (referred to in previous link) > > > > and then the last link has this patch: > > http://web.archive.org/web/20070815094037/http://bugs.busybox.net/file_download.php?file_id=1059&type=bug > > > > ...which seems not to have made it into the main repo, and no longer > > applies correctly; all the locations have changed. > > > > > > So, here follows an up-to-date version of it. I hope someone finds it > > useful and avoids repeating all my 'digging about'. > > > > And many thanks to 'bjdooks' for the original. > > Interesting. First, thanks for the investigation. > > When you select BR2_arm920t as the ARM processor, we are already > passing --with-arch=armv4t to the gcc configure. So, gcc should already > avoid the use of CLZ, since ARMv4T does not support it. > > Have you investigated why passing the --with-cpu argument is also > needed, in addition to --with-arch? In crosstool-Ng, we have this: http://crosstool-ng.org/hg/crosstool-ng/annotate/98b7806295cc/patches/gcc/4.4.5/210-arm-unbreak-armv4t.patch#l1 For gcc, if --with-cpu is not specified, then it defaults to TARGET_CPU_arm10tdmi which is an armv5 (as far as I understand it). The patch above downgrades the default CPU to an armv4t. Maybe worth a try. That, or passing --with-cpu=... as suggested by Adam. Regards, Yann E. MORIN.
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@free-electrons.com> writes:
Hi,
Thomas> Interesting. First, thanks for the investigation.
Thomas> When you select BR2_arm920t as the ARM processor, we are
Thomas> already passing --with-arch=armv4t to the gcc configure. So,
Thomas> gcc should already avoid the use of CLZ, since ARMv4T does not
Thomas> support it.
It indeed sounds quite strange, as I've run buildroot rootfs'es on the
mini2440 (which is arm920t) back in 2011 at least.
I don't have access to that hardware anymore though.
Dear Yann E. MORIN, On Thu, 26 Sep 2013 19:52:21 +0200, Yann E. MORIN wrote: > In crosstool-Ng, we have this: > http://crosstool-ng.org/hg/crosstool-ng/annotate/98b7806295cc/patches/gcc/4.4.5/210-arm-unbreak-armv4t.patch#l1 > > For gcc, if --with-cpu is not specified, then it defaults to > TARGET_CPU_arm10tdmi which is an armv5 (as far as I understand it). So even when --with-arch=armv7a, gcc will use --with-cpu=arm10tdmi? I'm not sure to understand what will be the effect of having --with-arch=armv7a and --with-cpu=arm10tdmi. > The patch above downgrades the default CPU to an armv4t. Maybe worth a > try. That, or passing --with-cpu=... as suggested by Adam. Ok. Thomas
>In crosstool-Ng, we have this: > http://crosstool-ng.org/hg/crosstool-ng/annotate/98b7806295cc/patches/gcc/4.4.5/210-arm-unbreak-armv4t.patch#l1 > >For gcc, if --with-cpu is not specified, then it defaults to >TARGET_CPU_arm10tdmi which is an armv5 (as far as I understand it). > >The patch above downgrades the default CPU to an armv4t. Maybe worth a >try. That, or passing --with-cpu=... as suggested by Adam. Hi, I have got a similar patch in: package/gcc/4.7.3/830-arm_unbreak_armv4t.patch ...to edit SUBTARGET_CPU_DEFAULT to use arm9tdmi instead of the arm5t arm10tdmi core. The file affected, gcc/config/arm/linux-eabi.h, has no equivalent to set the architecture to arm4t as default. I wonder if libgcc has no translation from the cpu/core to the architecture. Following back from the __udivsi3 libgcc function... My exception was at: 20127a2c: e16f3f10 clz r3, r0 which is in: 20127a10 <__udivsi3>: u-boot.map states: .text 0x20127a10 0x20c /opt/arm-2009q1/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/libgcc.a(_udivsi3.o) then in ../buildroot-2013.08.1/output/build/host-gcc-final-4.7.3/build/arm-buildroot-linux-uclibcgnueabi/libgcc/_udivsi3.dep _udivsi3.o: ../../../libgcc/config/arm/lib1funcs.S _udivsi3.vis \ ../../../libgcc/config/arm/ieee754-df.S \ ../../../libgcc/config/arm/ieee754-sf.S \ ../../../libgcc/config/arm/bpabi.S The assembler code at the start: 20127a10 <__udivsi3>: 20127a10: e2512001 subs r2, r1, #1 ; 0x1 20127a14: 012fff1e bxeq lr 20127a18: 3a000074 bcc 20127bf0 <__udivsi3+0x1e0> 20127a1c: e1500001 cmp r0, r1 20127a20: 9a00006b bls 20127bd4 <__udivsi3+0x1c4> 20127a24: e1110002 tst r1, r2 20127a28: 0a00006c beq 20127be0 <__udivsi3+0x1d0> matches an available version(within "#else /* ARM version/Thumb-2. */") This then uses the macro ARM_DIV_BODY, which sure enough gives the CLZ containing options. .macro ARM_DIV_BODY dividend, divisor, result, curbit #if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) #if defined (__thumb2__) clz \curbit, \dividend clz \result, \divisor ... #else clz \curbit, \dividend clz \result, \divisor ... #endif #else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ #if __ARM_ARCH__ >= 5 clz \curbit, \divisor clz \result, \dividend ... #else /* __ARM_ARCH__ < 5 */ ... So, we clearly have __ARM_ARCH__ >= 5. The value of this is defined at the beginning of the same file, in the absense of any of: __ARM_ARCH_2__, __ARM_ARCH_3__, __ARM_ARCH_3M__, __ARM_ARCH_4__ or __ARM_ARCH_4T__ ..being defined. I notice with a 'grep -r "__ARM_ARCH_" *" that 'libffi' does something similar. But, I can't find where this is set. Or rather, I don't think it is set in one piece. The file: gcc/config/arm/arm-cores.def ..seems to be a bridge from 'arm9tdmi', specifying '4T', presumably to append make up __ARM_ARCH_4T__ But the construction of this I unfortunately cannot find. Any of this jog a memory? Cheers, Adam
diff -ruN buildroot-2013.08.1-orig/arch/Config.in.arm buildroot-2013.08.1/arch/Config.in.arm --- buildroot-2013.08.1-orig/arch/Config.in.arm 2013-09-17 12:42:07.000000000 +0100 +++ buildroot-2013.08.1/arch/Config.in.arm 2013-09-25 15:42:16.923369027 +0100 @@ -117,6 +117,24 @@ bool "iwmmxt" endchoice +# what we pass to the --with-cpu= option to gcc +config BR2_ARM_gcc_cpu + string + default arm610 if BR2_arm610 + default arm710 if BR2_arm710 + default arm720t if BR2_arm720t + default arm920t if BR2_arm920t + default arm922t if BR2_arm922t + default arm926t if BR2_arm926t + default arm1136jf-s if BR2_arm1136jf_s + default arm1176Jz-s if BR2_arm1176jz_s + default arm1176jfz-s if BR2_arm1176jzf_s + default strongarm110 if BR2_sa110 + default strongarm1100 if BR2_sa1100 + default xscale if BR2_xscale + default iwmmxt if BR2_iwmmxt + + config BR2_arm1136jf_s bool default BR2_arm1136jf_s_r0 || BR2_arm1136jf_s_r1 diff -ruN buildroot-2013.08.1-orig/package/gcc/gcc.mk buildroot-2013.08.1/package/gcc/gcc.mk --- buildroot-2013.08.1-orig/package/gcc/gcc.mk 2013-09-17 12:42:07.000000000 +0100 +++ buildroot-2013.08.1/package/gcc/gcc.mk 2013-09-25 15:49:01.605600268 +0100 @@ -159,6 +160,13 @@ ifneq ($(call qstrip,$(BR2_GCC_TARGET_ABI)),) HOST_GCC_COMMON_CONF_OPT += --with-abi=$(BR2_GCC_TARGET_ABI) endif + +ifeq ($(BR2_arm),y) +ifeq ($(BR2_generic_arm),) +HOST_GCC_COMMON_CONF_OPT += --with-cpu=$(BR2_ARM_gcc_cpu) +endif +endif + # GCC doesn't support --with-cpu for bfin ifeq ($(BR2_bfin),) ifneq ($(call qstrip,$(BR2_GCC_TARGET_CPU)),)