[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: RFC: Support non-standard extension (call via casted function pointer)



> This frobbing of a pointer return value in %d0 only happens in the
> outgoing case already now, because in the non-outgoing case,
> m68k_function_value is (unverified claim) only called from expand_call,
> which replaces the PARALLEL rtx by the first list element, i.e. %a0. (or
> %d0 if !POINTER_TYPE_P(valtype) after my patch).

Wether pointer values are returned in d0 or a0 only depend on the ABI, not the machine type.

BTW what does ghc expect on x86-64? The ABIs on linux and e.g Win64 are also quite different with respect to which registers are used to pass/ parameters.

And in the m68k-case, you will have similar problems with double values. Depending on the ABI, they are returned in either fp0 or d0/d1.

You can try the following example:

extern void *test1(void);

extern char a[100];

__attribute__((noinline)) void *test2(void)
{
    return a;
}

extern void *p1;
extern void *p2;

void test3(void)
{
    p1 = test1();
    p2 = test2();
}

extern double test4(void);

extern double d;

__attribute__((noinline)) double test5(void)
{
    return d;
}

extern double d1;
extern double d2;

void test6(void)
{
    d1 = test4();
    d2 = test5();
}

m68k-atari-linux-gcc produces the following code:

        .globl  test2
        .type   test2, @function
test2:
        lea a,%a0
        move.l %a0,%d0
        rts
        .size   test2, .-test2
        .align  2
        .globl  test3
        .type   test3, @function
test3:
        jsr test1
        move.l %a0,p1
        jsr test2
        move.l %a0,p2
        rts
        .size   test3, .-test3
        .align  2
        .globl  test5
        .type   test5, @function
test5:
        fmove.d d,%fp0
        rts
        .size   test5, .-test5
        .align  2
        .globl  test6
        .type   test6, @function
test6:
        jsr test4
        fmove.d %fp0,d1
        jsr test5
        fmove.d %fp0,d2
        rts

You see that test2() puts the return value in both a0 and d0, and that test3() expects the return value in a0 in both calls of test1() and test2().

The same code compiled with m68k-atari-mint-gcc produces:

        .globl  _test2
_test2:
        move.l #_a,%d0
        rts
        .even
        .globl  _test3
_test3:
        jsr _test1
        move.l %d0,_p1
        jsr _test2
        move.l %d0,_p2
        rts
        .even
        .globl  _test5
_test5:
        move.l _d,%a1
        move.l _d+4,%a0
        move.l %a1,%d0
        move.l %a0,%d1
        rts
        .even
        .globl  _test6
_test6:
        jsr _test4
        move.l %d0,_d1
        move.l %d1,_d1+4
        jsr _test5
        move.l %d0,_d2
        move.l %d1,_d2+4
        rts

In this case, test2() puts the return value only in d0, and test3() expects the return value in d0 in both calls of test1() and test2().
(BTW strange code that is produced in test5() to return the double in d0/d1; why is it loaded into address registers first?)

Conclusion: IMHO, If ghc fetches the return value from the wrong register, then ghc is broken, not gcc.


Michael Karcher <debian@mkarcher.dialup.fu-berlin.de> schrieb am 20:21 Dienstag, 26.Januar 2016:


On 26.01.2016 16:40, Richard Biener wrote:
> No, the patch looks somewhat broken to me.  A complete fix would replace
> the target macro FUNCTION_VALUE implementation by implementing the
> function_value hook instead (to also receive the function type called if no
> decl is available and to be able to distinguish caller vs. callee).
>
> I also don't see how changing the called function code will fix anything.
I definitely agree that the approach to move from the FUNCTION_VALUE
macro to the function_value hook is the most clean way to do it. If
there is a consensus among the gcc developers that a patch to support
this non-conforming code should be applied, I would be willing to
prepare a patch as suggested.

The current patch does not change the called code at all. The only time
at which my suggested patch changes gcc behaviour is if a function
declaration is given, that declaration has a pointer type as return
type, but valtype is no pointer type. This (unverified claim) can not
happen in the callee, as the valtype when compiling the return statement
or assembling the epilogue is taken from the function declaration.

> In fact the frobbing of the return value into %d0 should only happen
> if the 'outgoing' arg is true (in the hook implementation) and in the
> 'outgoing' == false case simply disregard 'func' and always use
> 'valtype'.
This frobbing of a pointer return value in %d0 only happens in the
outgoing case already now, because in the non-outgoing case,
m68k_function_value is (unverified claim) only called from expand_call,
which replaces the PARALLEL rtx by the first list element, i.e. %a0. (or
%d0 if !POINTER_TYPE_P(valtype) after my patch).


> So, hookize and change to
>
>  if (outgoing && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (func))))
>    ...
>  else if (POINTER_TYPE_P (valtype))
>    ...
>  else

>    ...
Looks good and clean to me, but I expect my patch to have the same effect.

Regards,
  Michael Karcher





Reply to: