ARM-PXA toolchain
Mircea Gherzan
mgherzan@gmail.com
Tue Nov 8 12:23:00 GMT 2011
Hi,
First of all thanks for your thorough analysis!
On Mon, Nov 07, 2011 at 02:16:01AM +0100, Yann E. MORIN wrote:
> The source file is: ports/sysdeps/arm/eabi/setjmp.S
> Here's the code (lines starting with 'YEM' are my comments):
>
> ---8<---
> 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]
> #else
> #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]
> #else
> ldr a3, Lhwcap
> ldr a3, [a3, #0]
> #endif
> #endif
> 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
> Lno_vfp:
>
> 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
> Lno_iwmmxt:
>
> /* 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
> Lrtld_local_ro:
> .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
> #else
> #ifdef PIC
> 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
> Lrtld_global_ro:
> .long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
> #else
> Lhwcap:
> .long C_SYMBOL_NAME(_dl_hwcap)
> #endif
> #endif
>
> END (__sigsetjmp)
> ---8<---
>
> 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'
I can't check the coding for I can't compile a simple:
void my_vstmia(void)
{
__asm__("stc p11, cr8, [ip], #64");
__asm__("vstmia ip!, {d8 - d51}");
}
With -march=armv7-a -mcpu=cortex-a9 -mfpu=vfpv3-d16 -mhard-float I get:
"VFP single precision register expected -- `vstmia ip!,{d8-d51}'"
With -march=armv7-a -mcpu=cortex-a9 -mfpu=vfpv3-d16 -msoft-float I get:
"selected processor does not support ARM mode `vstmia ip!,{d8-d51}'"
> 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.
Qemu is also my guess. I've filed a bug report [1].
> Did you try on real hardware?
No, I don't have it.
Thanks,
Mircea
[1] https://bugs.launchpad.net/qemu/+bug/887516
--
For unsubscribe information see http://sourceware.org/lists.html#faq
More information about the crossgcc
mailing list