* [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
@ 2009-04-29 14:34 Georg-Johann Lay
2009-04-29 15:57 ` Ian Lance Taylor
0 siblings, 1 reply; 7+ messages in thread
From: Georg-Johann Lay @ 2009-04-29 14:34 UTC (permalink / raw)
To: gcc-help
Hi, I am working on a GCC 4.3.3 port for a 32-bit architecture.
The machine has dedicated data (D) resp. address (A) registers.
A function shall pass addresses in A-registers and other stuff in
D-registers, Pmode = SImode.
Everything works fine except that for libcalls the target macros
FUNCTION_ARG, FUNCTION_ARG_ADVANCE, TARGET_PASS_BY_REFERENCE et al. are
called with TYPE=NULL_TREE, so that is is not possible to destinguish
between pointers and non-pointers.
If the call of memmove is done explicitely from the C source, then there
is a prototype and TYPE!=NULL_TREE so that I can provide correct
behaviour for the target hooks mentioned above.
But, if memmove is called implicitely to copy function args like large
structs that are passed in memory, then TYPE==NULL_TREE and the hooks
have no information about what they have to do. Neigher choosing an
A-reg not choosing a D-reg will yield a consistend calling conventions
in every case.
Did I miss something? Is there a way to retrieve the necessary
information without hacking calls.c, function.c, etc?
Why is this essential information cancelled in calls.c?
Obviously, calls.c has that information but hides it from the backend.
I do not consider to introduce Pmode = PSImode because that would result
in an exact clone of the SImode support in the backend.
Thanks for any hints,
Georg-Johann
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-29 14:34 [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems Georg-Johann Lay
@ 2009-04-29 15:57 ` Ian Lance Taylor
2009-04-29 17:20 ` Georg-Johann Lay
2009-04-30 9:29 ` Richard Earnshaw
0 siblings, 2 replies; 7+ messages in thread
From: Ian Lance Taylor @ 2009-04-29 15:57 UTC (permalink / raw)
To: Georg-Johann Lay; +Cc: gcc-help
Georg-Johann Lay <avr@gjlay.de> writes:
> A function shall pass addresses in A-registers and other stuff in
> D-registers, Pmode = SImode.
How do varargs functions work?
> Everything works fine except that for libcalls the target macros
> FUNCTION_ARG, FUNCTION_ARG_ADVANCE, TARGET_PASS_BY_REFERENCE et
> al. are called with TYPE=NULL_TREE, so that is is not possible to
> destinguish between pointers and non-pointers.
>
> If the call of memmove is done explicitely from the C source, then
> there is a prototype and TYPE!=NULL_TREE so that I can provide correct
> behaviour for the target hooks mentioned above.
>
> But, if memmove is called implicitely to copy function args like large
> structs that are passed in memory, then TYPE==NULL_TREE and the hooks
> have no information about what they have to do. Neigher choosing an
> A-reg not choosing a D-reg will yield a consistend calling conventions
> in every case.
>
> Did I miss something? Is there a way to retrieve the necessary
> information without hacking calls.c, function.c, etc?
>
> Why is this essential information cancelled in calls.c?
> Obviously, calls.c has that information but hides it from the backend.
Yours is the first processor I have heard of which uses this sort of
calling convention. Differentiating on the basis of integer
vs. floating point is common, on the basis of integer vs. pointer is
not. I can see that you have a problem, but I'm not surprised that gcc
does not already address it. You are going to have to figure out what
is required to make it work. Modifying libcalls to be more like
ordinary functions sounds like a good approach; it is one that gcc has
been following, very slowly, for many years.
Ian
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-29 15:57 ` Ian Lance Taylor
@ 2009-04-29 17:20 ` Georg-Johann Lay
2009-04-29 17:31 ` Ian Lance Taylor
2009-04-30 9:29 ` Richard Earnshaw
1 sibling, 1 reply; 7+ messages in thread
From: Georg-Johann Lay @ 2009-04-29 17:20 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
[-- Attachment #1: Type: text/plain, Size: 3021 bytes --]
Ian Lance Taylor schrieb:
> Georg-Johann Lay <avr@gjlay.de> writes:
>
>> A function shall pass addresses in A-registers and other stuff in
>> D-registers, Pmode = SImode.
>
> How do varargs functions work?
Named arguments are passed as explained, and the unnamed ... portion
will be passed in memory. Perhapy everything will be passed via memory.
The ABI is in the flow as is the ISA, because there is no silicon
available yet.
For every function that is called from source level there must ba a
prototype. If there is no prototype for a called function, the behaviour
is unspecified.
>> Everything works fine except that for libcalls the target macros
>> FUNCTION_ARG, FUNCTION_ARG_ADVANCE, TARGET_PASS_BY_REFERENCE et
>> al. are called with TYPE=NULL_TREE, so that is is not possible to
>> destinguish between pointers and non-pointers.
>>
>> If the call of memmove is done explicitely from the C source, then
>> there is a prototype and TYPE!=NULL_TREE so that I can provide correct
>> behaviour for the target hooks mentioned above.
>>
>> But, if memmove is called implicitely to copy function args like large
>> structs that are passed in memory, then TYPE==NULL_TREE and the hooks
>> have no information about what they have to do. Neigher choosing an
>> A-reg not choosing a D-reg will yield a consistend calling conventions
>> in every case.
>>
>> Did I miss something? Is there a way to retrieve the necessary
>> information without hacking calls.c, function.c, etc?
>>
>> Why is this essential information cancelled in calls.c?
>> Obviously, calls.c has that information but hides it from the backend.
>
> Yours is the first processor I have heard of which uses this sort of
> calling convention. Differentiating on the basis of integer
> vs. floating point is common, on the basis of integer vs. pointer is
> not. I can see that you have a problem, but I'm not surprised that gcc
> does not already address it. You are going to have to figure out what
> is required to make it work. Modifying libcalls to be more like
> ordinary functions sounds like a good approach; it is one that gcc has
> been following, very slowly, for many years.
Several years ago -- before my time -- my company made a port for
Infineon TriCore. It works and is about to be SIL sertified. It uses a
similar ABI. I attached the patches. That are not very much changes, but
I don't like this kind of hacks and would prefer very much to keep the
frontend/middleend clean of backend issues.
Unfortunately, the TriCore is not an official port (not my decision) and
will never be a part of the official GCC because it contains many
non-standard hacks some customers payed for (bad idea, but it is/was not
my decision to implement hacks-for-money). Moreover, we simply don't
have the manpower to consider going into such a direction (again, not my
decision)...
At what place would you recommend to make such changes?
I intend to keep all of the port in the backend, in the place where it
belongs.
Georg-Johann
[-- Attachment #2: function.c-diff-1.1-1.2 --]
[-- Type: text/plain, Size: 1091 bytes --]
Index: function.c
===================================================================
RCS file: /data/CVS_Archive/gnu/gcc-3.4.5/gcc/function.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- function.c 13 Dec 2005 09:17:00 -0000 1.1
+++ function.c 9 Jan 2006 14:06:11 -0000 1.2
@@ -6831,11 +6831,11 @@
else
abort ();
emit_library_call (profile_function_entry_libfunc, LCT_NORMAL, VOIDmode,
- 2, fun, Pmode,
+ 2, fun, Pmode, ptr_type_node,
expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0,
hard_frame_pointer_rtx),
- Pmode);
+ Pmode, ptr_type_node);
}
if (current_function_profile)
@@ -7111,11 +7111,11 @@
else
abort ();
emit_library_call (profile_function_exit_libfunc, LCT_NORMAL, VOIDmode,
- 2, fun, Pmode,
+ 2, fun, Pmode, ptr_type_node,
expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0,
hard_frame_pointer_rtx),
- Pmode);
+ Pmode, ptr_type_node);
}
/* Let except.c know where it should emit the call to unregister
[-- Attachment #3: calls.c-diff-1.1-1.2 --]
[-- Type: text/plain, Size: 2791 bytes --]
Index: calls.c
===================================================================
RCS file: /data/CVS_Archive/gnu/gcc-3.4.5/gcc/calls.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- calls.c 13 Dec 2005 09:17:03 -0000 1.1
+++ calls.c 9 Jan 2006 14:06:15 -0000 1.2
@@ -3856,9 +3856,9 @@
argvec[count].mode = Pmode;
argvec[count].partial = 0;
- argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, NULL_TREE, 1);
+ argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, /*NULL_TREE*/ptr_type_node, 1);
#ifdef FUNCTION_ARG_PARTIAL_NREGS
- if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, Pmode, NULL_TREE, 1))
+ if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, Pmode, /*NULL_TREE*/ptr_type_node, 1))
abort ();
#endif
@@ -3883,6 +3883,7 @@
{
rtx val = va_arg (p, rtx);
enum machine_mode mode = va_arg (p, enum machine_mode);
+ tree arg_type = va_arg(p,tree);
/* We cannot convert the arg value to the mode the library wants here;
must do it earlier where we know the signedness of the arg. */
@@ -3899,13 +3900,13 @@
val = force_operand (val, NULL_RTX);
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
- if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
+ if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, /*NULL_TREE*/arg_type, 1))
{
rtx slot;
int must_copy = 1
#ifdef FUNCTION_ARG_CALLEE_COPIES
&& ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
- NULL_TREE, 1)
+ /*NULL_TREE*/arg_type, 1)
#endif
;
@@ -3964,23 +3965,23 @@
argvec[count].value = val;
argvec[count].mode = mode;
- argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
+ argvec[count].reg = FUNCTION_ARG (args_so_far, mode, /*NULL_TREE*/arg_type, 1);
#ifdef FUNCTION_ARG_PARTIAL_NREGS
argvec[count].partial
- = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, NULL_TREE, 1);
+ = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, /*NULL_TREE*/arg_type, 1);
#else
argvec[count].partial = 0;
#endif
- locate_and_pad_parm (mode, NULL_TREE,
+ locate_and_pad_parm (mode, /*NULL_TREE*/arg_type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
1,
#else
argvec[count].reg != 0,
#endif
argvec[count].partial,
- NULL_TREE, &args_size, &argvec[count].locate);
+ /*NULL_TREE*/arg_type, &args_size, &argvec[count].locate);
if (argvec[count].locate.size.var)
abort ();
@@ -3989,7 +3990,7 @@
|| reg_parm_stack_space > 0)
args_size.constant += argvec[count].locate.size.constant;
- FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
+ FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) /*NULL_TREE*/arg_type, 1);
}
#ifdef FINAL_REG_PARM_STACK_SPACE
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-29 17:20 ` Georg-Johann Lay
@ 2009-04-29 17:31 ` Ian Lance Taylor
2009-04-30 11:05 ` Georg-Johann Lay
0 siblings, 1 reply; 7+ messages in thread
From: Ian Lance Taylor @ 2009-04-29 17:31 UTC (permalink / raw)
To: Georg-Johann Lay; +Cc: gcc-help
Georg-Johann Lay <avr@gjlay.de> writes:
> Several years ago -- before my time -- my company made a port for
> Infineon TriCore. It works and is about to be SIL sertified. It uses a
> similar ABI. I attached the patches. That are not very much changes,
> but I don't like this kind of hacks and would prefer very much to keep
> the frontend/middleend clean of backend issues.
That is an admirable goal, but in this case I think you are going to
have to change the middle-end to make your port work. I recommend that
you contribute the patches back to gcc mainline for the benefit of other
users. Of course this will require a copyright assignment or
disclaimer.
The small patch you sent looks quite reasonable.
Ian
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-29 15:57 ` Ian Lance Taylor
2009-04-29 17:20 ` Georg-Johann Lay
@ 2009-04-30 9:29 ` Richard Earnshaw
2009-04-30 11:38 ` Georg-Johann Lay
1 sibling, 1 reply; 7+ messages in thread
From: Richard Earnshaw @ 2009-04-30 9:29 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: Georg-Johann Lay, gcc-help
On Wed, 2009-04-29 at 08:57 -0700, Ian Lance Taylor wrote:
> > Everything works fine except that for libcalls the target macros
> > FUNCTION_ARG, FUNCTION_ARG_ADVANCE, TARGET_PASS_BY_REFERENCE et
> > al. are called with TYPE=NULL_TREE, so that is is not possible to
> > destinguish between pointers and non-pointers.
> >
> > If the call of memmove is done explicitely from the C source, then
> > there is a prototype and TYPE!=NULL_TREE so that I can provide correct
> > behaviour for the target hooks mentioned above.
> >
> > But, if memmove is called implicitely to copy function args like large
> > structs that are passed in memory, then TYPE==NULL_TREE and the hooks
> > have no information about what they have to do. Neigher choosing an
> > A-reg not choosing a D-reg will yield a consistend calling conventions
> > in every case.
> >
> > Did I miss something? Is there a way to retrieve the necessary
> > information without hacking calls.c, function.c, etc?
> >
> > Why is this essential information cancelled in calls.c?
> > Obviously, calls.c has that information but hides it from the backend.
>
> Yours is the first processor I have heard of which uses this sort of
> calling convention. Differentiating on the basis of integer
> vs. floating point is common, on the basis of integer vs. pointer is
> not. I can see that you have a problem, but I'm not surprised that gcc
> does not already address it. You are going to have to figure out what
> is required to make it work. Modifying libcalls to be more like
> ordinary functions sounds like a good approach; it is one that gcc has
> been following, very slowly, for many years.
Hmm, the ARM port has something similar, which only comes to be
significant when the hard-float calling convention is implemented; in
this case, the calling convention for the ABI-specified support
functions remains unchanged even though the calling convention for
normal user calls can be different. The trick is that you have to find
out exactly which libcall is being used, essentially by name matching.
You can look at what I've done for this on the ARM/hard_vfp_4_4_branch
in the GCC SVN repository.
It's unfortunate that GCC doesn't synthesise a type node for libcalls;
that would probably make things much simpler...
R.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-29 17:31 ` Ian Lance Taylor
@ 2009-04-30 11:05 ` Georg-Johann Lay
0 siblings, 0 replies; 7+ messages in thread
From: Georg-Johann Lay @ 2009-04-30 11:05 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-help
Ian Lance Taylor schrieb:
> Georg-Johann Lay <avr@gjlay.de> writes:
>
>> Several years ago -- before my time -- my company made a port for
>> Infineon TriCore. It works and is about to be SIL sertified. It uses a
>> similar ABI. I attached the patches. That are not very much changes,
>> but I don't like this kind of hacks and would prefer very much to keep
>> the frontend/middleend clean of backend issues.
>
> That is an admirable goal, but in this case I think you are going to
> have to change the middle-end to make your port work. I recommend that
> you contribute the patches back to gcc mainline for the benefit of other
> users. Of course this will require a copyright assignment or
> disclaimer.
>
> The small patch you sent looks quite reasonable.
I must admit that I don't like this bulk of micro-patches. They do not
solve the very problem (no prototypes for support functions), may
confuse some backends because TYPE is no more NULL_TREE for libfunc in
FUNCTION_ARG et al., are beyond the backend's sandbox, and I am not sure
if it fixes all combinations of target hooks/makros one can think of.
I am still waiting for my copyright assignment, maybe one day I will get
one... who knows.
For now I am simply using INIT_CUMULATIVE_ARGS
(INIT_CUMULATIVE_LIBCALL_ARGS would do as well) and reconstruct the
prototype from the function's name in libname rtx. As far as I can
depict from libfuncs.h, only "memmove", "memcpy", "memset" and "memcmp"
need to be reconstructed, maybe some parts of the non-local-goto/eh
stuff, too.
The implementation is redundant as is recreates information which is
present in some corner of the universe, but at least I need not touch
the middle-end to get working code :-)
What I do not know is wether or not some optimizations use the return
value of some support function in the case it is a pointer. What I can
say is that TARGET_FUNCTION_VALUE is not called for the suppot functions
I saw so far.
Georg-Johann
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.
2009-04-30 9:29 ` Richard Earnshaw
@ 2009-04-30 11:38 ` Georg-Johann Lay
0 siblings, 0 replies; 7+ messages in thread
From: Georg-Johann Lay @ 2009-04-30 11:38 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: Ian Lance Taylor, gcc-help
Richard Earnshaw schrieb:
> On Wed, 2009-04-29 at 08:57 -0700, Ian Lance Taylor wrote:
>>> Everything works fine except that for libcalls the target macros
>>> FUNCTION_ARG, FUNCTION_ARG_ADVANCE, TARGET_PASS_BY_REFERENCE et
>>> al. are called with TYPE=NULL_TREE, so that is is not possible to
>>> destinguish between pointers and non-pointers.
>>>
>>> If the call of memmove is done explicitely from the C source, then
>>> there is a prototype and TYPE!=NULL_TREE so that I can provide correct
>>> behaviour for the target hooks mentioned above.
>>>
>>> But, if memmove is called implicitely to copy function args like large
>>> structs that are passed in memory, then TYPE==NULL_TREE and the hooks
>>> have no information about what they have to do. Neigher choosing an
>>> A-reg not choosing a D-reg will yield a consistend calling conventions
>>> in every case.
>>>
>>> Did I miss something? Is there a way to retrieve the necessary
>>> information without hacking calls.c, function.c, etc?
>>>
>>> Why is this essential information cancelled in calls.c?
>>> Obviously, calls.c has that information but hides it from the backend.
>> Yours is the first processor I have heard of which uses this sort of
>> calling convention. Differentiating on the basis of integer
>> vs. floating point is common, on the basis of integer vs. pointer is
>> not. I can see that you have a problem, but I'm not surprised that gcc
>> does not already address it. You are going to have to figure out what
>> is required to make it work. Modifying libcalls to be more like
>> ordinary functions sounds like a good approach; it is one that gcc has
>> been following, very slowly, for many years.
>
> Hmm, the ARM port has something similar, which only comes to be
> significant when the hard-float calling convention is implemented; in
> this case, the calling convention for the ABI-specified support
> functions remains unchanged even though the calling convention for
> normal user calls can be different. The trick is that you have to find
> out exactly which libcall is being used, essentially by name matching.
> You can look at what I've done for this on the ARM/hard_vfp_4_4_branch
> in the GCC SVN repository.
>
> It's unfortunate that GCC doesn't synthesise a type node for libcalls;
> that would probably make things much simpler...
Yes, definitely.
But optabs.c::init_one_libfunc() does not investigate in building a
proper SYMBOL_REF_DECL. It just creates a dummy tree to set some flags
like DECL_ARTIFICIAL and nullifies it afterwards. As a result,
SYMBOL_REF_DECL(LIBNAME) is NULL_TREE in FUNCTION_ARG et al.
What I do not understand is how the ABI can be different, because the
callee will expect the arguments in dedicated registers, regardless of
who calls it and of wether or not the caller issues a user call or a
support call.
As I read in
http://gcc.gnu.org/viewvc/branches/ARM/hard_vfp_4_4_branch/gcc/doc/tm.texi?r1=142586&r2=142592&diff_format=h
you solved the shortcomings of LIBCALL_VALUE, which are basically the
same as these of FUNCTION_ARG* if the target has ptr_mode=word_mode :-)
Will this get into the next official 4.3.x release? I hope so!
Georg-Johann
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-04-30 11:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-29 14:34 [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems Georg-Johann Lay
2009-04-29 15:57 ` Ian Lance Taylor
2009-04-29 17:20 ` Georg-Johann Lay
2009-04-29 17:31 ` Ian Lance Taylor
2009-04-30 11:05 ` Georg-Johann Lay
2009-04-30 9:29 ` Richard Earnshaw
2009-04-30 11:38 ` Georg-Johann Lay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).