This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: m32c: pointer math vs sizetype again
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "DJ Delorie" <dj at redhat dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Sat, 20 Sep 2008 10:51:49 +0200
- Subject: Re: m32c: pointer math vs sizetype again
- References: <200809192352.m8JNq7Xs003011@greed.delorie.com>
On Sat, Sep 20, 2008 at 1:52 AM, DJ Delorie <dj@redhat.com> wrote:
>
> 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.
I think this is one of the reasons sizetype constants(!!) are always
sign-extended.
Of course this makes less sense if non-constants are not ;)
Does the following fix it?
Index: expr.c
===================================================================
--- expr.c (revision 140433)
+++ expr.c (working copy)
@@ -8336,8 +8336,12 @@ expand_expr_real_1 (tree exp, rtx target
{
tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0));
enum machine_mode innermode = TYPE_MODE (op0type);
- bool zextend_p = TYPE_UNSIGNED (op0type);
+ bool zextend_p;
bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0));
+ if (code == POINTER_PLUS_EXPR)
+ zextend_p = false;
+ else
+ zextend_p = TYPE_UNSIGNED (op0type)
if (sat_p == 0)
this_optab = zextend_p ? umadd_widen_optab : smadd_widen_optab;
else
This would affect only targets where the precision of sizetype is not equal to
that of a pointer where it would now sign-extend instead of zero-extending for
C and sign-extending for Ada.
Richard.
> DJ
>