target/5828: gcc-3.0.4 on arm : floating point registers incorrectly reloaded

jeroen.dobbelaere@acunia.com jeroen.dobbelaere@acunia.com
Mon Mar 4 07:06:00 GMT 2002


>Number:         5828
>Category:       target
>Synopsis:       gcc-3.0.4 on arm : floating point registers incorrectly reloaded
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 04 07:06:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     jeroen.dobbelaere@acunia.com
>Release:        gcc-3.0.4 armv5l-unknown-linux-gnu
>Organization:
>Environment:
glibc-2.2.5
>Description:
Gcc generates incorrect code for reloading floating point values on arm-linux. (target cpu = xscale)

The reloading of the 4 fp registers starts at a wrong offset against the fp-register. (16 bytes wrong)
>How-To-Repeat:
Following program demonstrates the problem :

// *** floattest2.cpp ***
// compile : g++ -S -O2 floattest2.cpp
extern void* theP2(int a) throw(int);

void* thePointer(int a) throw(int)
{
  return theP2(a);
}
// *** end of floattest2.cpp ***

This results  in following assembler code :

root:/usr/src/build/tmp# g++ -v -O2 -S floattest2.cpp 
Reading specs from /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/specs
Configured with: ../gcc-3.0.4/configure --prefix=/usr --with-cpu=xscale
Thread model: posix
gcc version 3.0.4
 /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=4 -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__ELF__ -D__unix -D__linux -Asystem=unix -Asystem=posix -Acpu=arm -Amachine=arm -D__CHAR_UNSIGNED__ -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -D_GNU_SOURCE -D__ARM_ARCH_5TE__ -D__XSCALE__ -D__APCS_32__ -D__ARMEL__ -D__arm__ floattest2.cpp -D__GNUG__=3 -D__GXX_DEPRECATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -quiet -dumpbase floattest2.cpp -O2 -version -o floattest2.s
GNU CPP version 3.0.4 (cpplib) (ARM GNU/Linux with ELF)
GNU C++ version 3.0.4 (armv5l-unknown-linux-gnu)
	compiled by GNU C version 3.0.4.
ignoring nonexistent directory "/usr/armv5l-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/g++-v3
 /usr/include/g++-v3/armv5l-unknown-linux-gnu
 /usr/include/g++-v3/backward
 /usr/local/include
 /usr/lib/gcc-lib/armv5l-unknown-linux-gnu/3.0.4/include
 /usr/include
End of search list.

@ Generated by gcc 3.0.4 for ARM/elf
	.file	"floattest2.cpp"
	.text
	.align	2
	.global	_Z10thePointeri
	.type	_Z10thePointeri,function
_Z10thePointeri:
	@ args = 0, pretend = 0, frame = 52
	@ frame_needed = 1, current_function_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
	sfmfd	f4, 4, [sp]!
	ldr	r3, .L8
	sub	fp, ip, #4  *****NOTE1
	sub	sp, sp, #52
	str	r3, [fp, #-108]
	ldr	r3, .L8+4
	ldr	r2, .L8+8
	str	r0, [fp, #-140]
	str	r3, [fp, #-96]
	sub	r0, fp, #132
	sub	r3, fp, #88
	str	r3, [fp, #-100]
	str	r2, [fp, #-104]
	str	sp, [fp, #-92]
	bl	_Unwind_SjLj_Register
	mov	r3, #1
	ldr	r0, [fp, #-140]
	str	r3, [fp, #-128]
	bl	_Z5theP2i
	str	r0, [fp, #-136]
	sub	r0, fp, #132
	bl	_Unwind_SjLj_Unregister
	ldr	r0, [fp, #-136]
	lfm	f4, 4, [fp, #-104]  ****NOTE2
	ldmea	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
.L6:
	add	fp, fp, #88
	
	ldr	r3, [fp, #-120]
	ldr	r0, [fp, #-124]
	cmn	r3, #1
	bne	.L7
	str	r3, [fp, #-128]
	bl	__cxa_call_unexpected
.L7:
	mvn	r3, #0
	str	r3, [fp, #-128]
	bl	_Unwind_SjLj_Resume
.L9:
	.align	2
.L8:
	.word	__gxx_personality_sj0
	.word	.L6
	.word	.LLSDA0
.Lfe1:
	.size	_Z10thePointeri,.Lfe1-_Z10thePointeri
	.section .gcc_except_table,"aw"
	.align	2
.LLSDA0:
	.byte	0xff
	.byte	0x0
	.uleb128 .LLSDATT0-.LLSDATTD0
.LLSDATTD0:
	.byte	0x1
	.uleb128 .LLSDACSE0-.LLSDACSB0
.LLSDACSB0:
	.uleb128 0x0
	.uleb128 0x1
.LLSDACSE0:
	.byte	0x7f
	.byte	0x0
	.align	2
	.4byte	_ZTIi
.LLSDATT0:
	.byte	0x1
	.byte	0x0
	.text
	.ident	"GCC: (GNU) 3.0.4"




NOTE1 : xxx = sp at entry

        sp = xxx-92
        fp = xxx-4
        floating points at xxx-92 == fp-88 

NOTE2 : try to reload floats at fp-104 == xxx-108

Probably gcc thinks that saving a single float with sfm takes 4 words instead of 3
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list