ARM-PXA toolchain

Mon Nov 7 01:16:00 GMT 2011

Mircea, All,

On Sunday 06 November 2011 20:46:25 Mircea Gherzan wrote:
> Am 06.11.2011 17:55, schrieb Yann E. MORIN:
> > Looks like you are building with hardware floating point, and your
> > kernel does not have FP emulation.
> No, I was not building with hard FP.


> > Here are the related configuration items:
> >    CT_ARCH_ARCH="armv5te"
> >    CT_ARCH_CPU="xscale"
> >    CT_ARCH_TUNE="xscale"
> >    CT_ARCH_FPU=""
> I've tried this [1] but the still contains some VFP 
> instructions (objdump | grep vstm):
>   17f44:       	ecac8b10        vstmia  	ip!, {d8-d15}
>   538:   	4d2f4a16        vstmdbmi        pc!, {s8-s29}
> [1]

I've tried your .config, and get only one VFP instruction:

$ arm-unknown-linux-guneabi-objdump -d |grep vst
   17f74:       ecac8b10        vstmia  ip!, {d8-d15}

Looking at the dump, it is in the sigsetjmp function:

00017f50 <__GI___sigsetjmp>:
   17f50:       e1a0c000        mov     ip, r0
   17f54:       e8ac6ff0        stmia   ip!, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
   17f58:       e59f2044        ldr     r2, [pc, #68]   ; 17fa4 <Lno_iwmmxt+0x4>
YEM: above load sin r2 value at 0x17fa4, which has bit 7 unset (see below)
   17f5c:       e59f3044        ldr     r3, [pc, #68]   ; 17fa8 <Lrtld_local_ro>
   17f60:       e08f2002        add     r2, pc, r2
   17f64:       e0822003        add     r2, r2, r3
   17f68:       e5922040        ldr     r2, [r2, #64]   ; 0x40
   17f6c:       e3120040        tst     r2, #64 ; 0x40
YEM: Alas, r2 is now spoiled with pc and r3, so 
   17f70:       0a000002        beq     17f80 <Lno_vfp>
YEM: the insn above should jmp to Lno_vfp if your CPU does not have VFP
YEM: so the following vstmia should not happen:
   17f74:       ecac8b10        vstmia  ip!, {d8-d15}
   17f78:       eef13a10        vmrs    r3, fpscr
   17f7c:       e48c3004        str     r3, [ip], #4

00017f80 <Lno_vfp>:
   17f80:       e3120c02        tst     r2, #512        ; 0x200
   17f84:       0a000005        beq     17fa0 <Lno_iwmmxt>
YEM: ditto here for iwmmxt
   17f88:       ececa102        stfp    f2, [ip], #8
   17f8c:       ececb102        stfp    f3, [ip], #8
   17f90:       ececc102        stfp    f4, [ip], #8
   17f94:       ececd102        stfp    f5, [ip], #8
   17f98:       ecece102        stfp    f6, [ip], #8
   17f9c:       ececf102        stfp    f7, [ip], #8

00017fa0 <Lno_iwmmxt>:
   17fa0:       eafff80d        b       15fdc <__sigjmp_save>
   17fa4:       0000f098        .word   0x0000f098
YEM: 0x0000f098 has bit 7 unset.

00017fa8 <Lrtld_local_ro>:
   17fa8:       fffffdc8        .word   0xfffffdc8
   17fac:       e1a00000        .word   0xe1a00000

The source file is: ports/sysdeps/arm/eabi/setjmp.S
Here's the code (lines starting with 'YEM' are my comments):

ENTRY (__sigsetjmp)
        mov     ip, r0

        /* Save registers */
        stmia   ip!, {v1-v6, sl, fp, sp, lr}

        /* Check if we have a VFP unit.  */
#ifdef IS_IN_rtld
        ldr     a3, 1f
        ldr     a4, Lrtld_local_ro
0:      add     a3, pc, a3
        add     a3, a3, a4
        ldr     a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#ifdef PIC
        ldr     a3, 1f
        ldr     a4, Lrtld_global_ro
0:      add     a3, pc, a3
        ldr     a3, [a3, a4]
        ldr     a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
        ldr     a3, Lhwcap
        ldr     a3, [a3, #0]
        tst     a3, #HWCAP_ARM_VFP
        beq     Lno_vfp

YEM: pay attention to the following comment!
        /* Store the VFP registers.
           Don't use VFP instructions directly because this code
           is used in non-VFP multilibs.  */
        /* Following instruction is vstmia ip!, {d8-d15}.  */
        stc     p11, cr8, [ip], #64
YEM: Aha! The instruction above *is* vstmia!
        /* Store the floating-point status register.  */
        /* Following instruction is vmrs a4, fpscr.  */
        mrc     p10, 7, a4, cr1, cr0, 0
YEM: See also how the above is in fact vmrs
        str     a4, [ip], #4

        tst     a3, #HWCAP_ARM_IWMMXT
        beq     Lno_iwmmxt

        /* Save the call-preserved iWMMXt registers.  */
        /* Following instructions are wstrd wr10, [ip], #8 (etc.)  */
        stcl    p1, cr10, [r12], #8
        stcl    p1, cr11, [r12], #8
        stcl    p1, cr12, [r12], #8
        stcl    p1, cr13, [r12], #8
        stcl    p1, cr14, [r12], #8
        stcl    p1, cr15, [r12], #8

        /* Make a tail call to __sigjmp_save; it takes the same args.  */
        B       PLTJMP(C_SYMBOL_NAME(__sigjmp_save))

#ifdef IS_IN_rtld
1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
        .long   C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
#ifdef PIC
1:      .long   _GLOBAL_OFFSET_TABLE_ - 0b - 8
        .long   C_SYMBOL_NAME(_rtld_global_ro)(GOT)
        .long   C_SYMBOL_NAME(_dl_hwcap)

END (__sigsetjmp)

OK, so why is the 'stc' instruction shown as being 'vstmia'?
There are two probable reasons:
 - 'as' tries to be smart, and notices that the 'stc' is in fact an 'stmia'
   so it translates that 'stc' to the (faster?) 'vstmia'
 - this specific 'stc' and 'vstmia' are coded the same, so 'objdump' gets
   confused, and decodes the insn as being 'vstmia'

Notice however, that the vstmia should not be executed on a CPU that does
not have a VFP (see the test above).

So, maybe qemu-user improperly handles that situation, not emulating VFP,
but exposing its presence.

So, here's my line of thought:
 - the code is assembly, so gcc is not at fault in any way
   --> 99% sure
 - there is an issue in binutils, with as smartery and/or objdump confusion
   --> probably not
 - eglibc-2.14 can't run on no-VFP CPU
   --> probably not
 - qemu-user mis-behaves
   --> probably

Did you try on real hardware?

BTW, here is the full list of libraries with vstmia in them:
---- arm-462-linux-gnueabi/arm-462-linux-gnueabi/sysroot/lib/
   17f74:       ecac8b10        vstmia  ip!, {d8-d15}
---- arm-462-linux-gnueabi/arm-462-linux-gnueabi/sysroot/lib/
    2874:       ec800b20        vstmia  r0, {d0-d15}
    2884:       ecc00b20        vstmia  r0, {d16-d31}
---- arm-462-linux-gnueabi/arm-462-linux-gnueabi/sysroot/lib/
   2cbd4:       ecac8b10        vstmia  ip!, {d8-d15}
---- arm-462-linux-gnueabi/arm-462-linux-gnueabi/sysroot/usr/lib/
    2874:       ec800b20        vstmia  r0, {d0-d15}
    2884:       ecc00b20        vstmia  r0, {d16-d31}

What's interesting is that in libc, vstmia is also in sigsetjmp.
Also, there are vldmia in longjmp.

Sorry, I can't help much more here... :-/

Yann E. MORIN.

|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |

For unsubscribe information see

More information about the crossgcc mailing list