[gccsdk] long long parameter + module code + tail calls + -Os generates broken stack code

Rob Kendrick rjek at rjek.com
Wed Feb 3 01:49:56 PST 2021


I have a problem where if I change any of the four things mentioned in the
subject (ie, use a 32 bit int, don't pass -mmodule, use -O0 or -O2, etc) it
vanishes.  With the combination, the code generated stacks every register in
the preamble, but never unstacks them.  gas also complains that the writeback
register is in the list (with good reason!)

Might be some sort of bitmap signedness problem somewhere in the code
generator?

(The actual function I identified this on is much longer.  The only other
simplification I could make and still produce the problem is to remove the
final return statement, but that is included here.)

rjek at trite:~$ cat testcase.c
int write_long(long long d) {
  if (d >= 0)
   return write_uinteger(d);
  if (d >= -32)
    return write_nfix(d);
  return write_int(d);
}
rjek at trite:~$ arm-unknown-riscos-gcc -mmodule -Os -S testcase.c && cat testcase.s
	.file	"testcase.c"
	.text
	.align	2
	.global	write_long
	.ascii	"write_long\000"
	.align	2
	.word	4278190092
	.type	write_long, %function
write_long:
	@ args = 0, pretend = 0, frame = 0, outgoing = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	stmfd	sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}
	mov	r2, r0
	mov	r3, r1
	cmp	r2, #0
	sbcs	ip, r3, #0
	blt	.L2
	ldmfd	sp!, {r4, r5, lr}
	b	write_uinteger
.L2:
	mvn	r4, #31
	mvn	r5, #0
	cmp	r2, r4
	sbcs	ip, r3, r5
	blt	.L3
	ldmfd	sp!, {r4, r5, lr}
	b	write_nfix
.L3:
	ldmfd	sp!, {r4, r5, lr}
	b	write_int
	.size	write_long, .-write_long
	.ident	"GCC: (GCCSDK GCC 4.7.4 Release 5) 4.7.4"
rjek at trite:~$ 


B.



More information about the gcc mailing list