This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [target.h] FUNCTION_ARG et al. called with type=NULL_TREE causes problems.


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
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
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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]