This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

m32c: pointer math vs sizetype again


m32c-elf-gcc -mcpu=m32c (16 bit ints, 24 bit pointers) miscompiles
this:

int *foo (int *a, int b)
{
  return a-b;
}

as this:

_foo:
	enter	#0		; 30	prologue_enter_24
	pushm	r1,r3,a0	; 31	pushm
	; end of prologue	; 32	prologue_end
	mov.w	12[fb],r0	; 27	movhi_op/1
	sha.w	#1,r0		; 7	ashlhi3_i/1
	neg.w	r0		; 8	neghi2/1
	mov.w	r0,a0		; 10	zero_extendhipsi2
	mov.l	8[fb],r3r1	; 28	movpsi_op/2
	add.l	a0,r3r1		; 16	addpsi3/3
	mov.l	r3r1,mem0	; 29	movpsi_op/2
	; start of epilogue	; 35	epilogue_start
	popm	r1,r3,a0	; 36	popm
	exitd			; 37	epilogue_exitd_24

The key instructions are - neg, zero_extend, add.  This breaks if the
original value is, say, 2.  Neg gives 0xfffe, zero_extend gives
0x00fffe, and you end up adding 65534 to the pointer.

If I change sizetype to "long unsigned int", it's bigger than a
pointer, and the front end leaves an unexpected nop_convert in various
expressions, which causes ICEs.

There is no standard integer type the same size as pointers (24 bit,
PSImode).  IIRC, last time I tried to shoehorn in a PSImode sizetype,
gcc wanted a full set of math operators for it, which the chip doesn't
have (they have to be done in HI or SI mode)

I tried making sizetype signed, that ICEd too.

What's the right thing to do?

If the front end either sign extended, or had a POINTER_MINUS_EXPR,
things would just work.

DJ


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]