On Wed, Jan 27, 2016 at 4:10 PM, Thorsten Otto <
halgara@yahoo.de> wrote:
>> 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.
We are trying to support
t.c
---
void *foo();
int bar()
{
return ((int (*)())foo) ();
}
t2.c
-----
int foo () { return 0; }
thus doing a direct call to a function with a (wrong) prototype via a function
pointer cast to the correct type and having a matching implementation of
that function elsewhere.
I think that's reasonable and what GHC expects - declare "there is a function
foo defined, no idea what prototype yet", unfortunately C requires to specify
a return type.
Richard.
>
> 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
>
>
>
>