On Wed, Jan 27, 2016 at 4:10 PM, Thorsten Otto <halg...@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 <deb...@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 > > > >