This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
m32c: pointer math vs sizetype again
- From: DJ Delorie <dj at redhat dot com>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 19 Sep 2008 19:52:07 -0400
- Subject: 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