This is the mail archive of the gcc-patches@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]

PATCH: Fix justification for small aggregates on hppa64


This patch uses a PARALLEL to obtain left-justified function return values
for small aggregates on hppa64 as per the ABI specification.

Tested on hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu with no regressions.

Will be applied to main if approval is received to correct problems in
returning PARALLELs in core code.

Thanks to Steve Ellcey for pointing out this problem and for providing
an initial patch.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2002-11-24  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa-protos.h (function_value): New prototype.
	* pa.c (function_value): Use a PARALLEL to return small aggregates on
	TARGET_64BIT.
	* pa.h (FUNCTION_VALUE): Use function_value.
	* pa.md (call_value_internal_symref, call_value_internal_reg_64bit,
	call_value_internal_reg, sibcall_value_internal_symref,
	sibcall_value_internal_symref_64bit): Remove =rf constraint on return
	value.

Index: config/pa/pa-protos.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa-protos.h,v
retrieving revision 1.19
diff -u -3 -p -r1.19 pa-protos.h
--- config/pa/pa-protos.h	31 Oct 2002 03:13:43 -0000	1.19
+++ config/pa/pa-protos.h	22 Nov 2002 01:07:40 -0000
@@ -158,6 +158,7 @@ extern int reloc_needed PARAMS ((tree));
 #ifdef RTX_CODE
 extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
 				 tree, int, int));
+extern rtx function_value PARAMS ((tree, tree));
 #endif
 extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
 					       enum machine_mode,
Index: config/pa/pa.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.186
diff -u -3 -p -r1.186 pa.c
--- config/pa/pa.c	10 Nov 2002 01:14:47 -0000	1.186
+++ config/pa/pa.c	22 Nov 2002 01:07:41 -0000
@@ -7677,6 +7677,57 @@ insn_refs_are_delayed (insn)
 	   && get_attr_type (insn) == TYPE_MILLI));
 }
 
+/* On the HP-PA the value is found in register(s) 28(-29), unless
+   the mode is SF or DF. Then the value is returned in fr4 (32).
+
+   This must perform the same promotions as PROMOTE_MODE, else
+   PROMOTE_FUNCTION_RETURN will not work correctly.
+
+   Small structures must be returned in a PARALLEL on PA64 in order
+   to match the HP Compiler ABI.  */
+
+rtx
+function_value (valtype, func)
+    tree valtype;
+    tree func ATTRIBUTE_UNUSED;
+{
+  enum machine_mode valmode;
+
+  /* Aggregates with a size less than or equal to 128 bits are returned
+     in GR 28(-29).  They are left justified.  The pad bits are undefined.
+     Larger aggregates are returned in memory.  */
+  if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype))
+    {
+      rtx loc[2];
+      int i, offset = 0;
+      int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+
+      for (i = 0; i < ub; i++)
+	{
+	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+				      gen_rtx_REG (DImode, 28 + i),
+				      GEN_INT (offset));
+	  offset += 8;
+	}
+
+      return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
+    }
+
+  if ((INTEGRAL_TYPE_P (valtype)
+       && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+      || POINTER_TYPE_P (valtype))
+    valmode = word_mode;
+  else
+    valmode = TYPE_MODE (valtype);
+
+  if (TREE_CODE (valtype) == REAL_TYPE
+      && TYPE_MODE (valtype) != TFmode
+      && !TARGET_SOFT_FLOAT)
+    return gen_rtx_REG (valmode, 32);
+
+  return gen_rtx_REG (valmode, 28);
+}
+
 /* Return the location of a parameter that is passed in a register or NULL
    if the parameter has any component that is passed in memory.
 
@@ -7813,12 +7864,10 @@ function_arg (cum, mode, type, named, in
 	     or returning a DImode REG results in left justified data.  */
 	  if (mode == BLKmode)
 	    {
-	      rtx loc[1];
-
-	      loc[0] = gen_rtx_EXPR_LIST (VOIDmode,
-					  gen_rtx_REG (DImode, gpr_reg_base),
-					  const0_rtx);
-	      return gen_rtx_PARALLEL (mode, gen_rtvec_v (1, loc));
+	      rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
+					   gen_rtx_REG (DImode, gpr_reg_base),
+					   const0_rtx);
+	      return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc));
 	    }
 	}
       else
Index: config/pa/pa.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.175
diff -u -3 -p -r1.175 pa.h
--- config/pa/pa.h	10 Nov 2002 01:14:47 -0000	1.175
+++ config/pa/pa.h	22 Nov 2002 01:07:41 -0000
@@ -730,19 +730,7 @@ extern struct rtx_def *hppa_pic_save_rtx
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.  */
 
-/* On the HP-PA the value is found in register(s) 28(-29), unless
-   the mode is SF or DF. Then the value is returned in fr4 (32).  */
-
-/* This must perform the same promotions as PROMOTE_MODE, else
-   PROMOTE_FUNCTION_RETURN will not work correctly.  */
-#define FUNCTION_VALUE(VALTYPE, FUNC)					\
-  gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE)				\
-		 && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)		\
-		|| POINTER_TYPE_P (VALTYPE))				\
-	        ? word_mode : TYPE_MODE (VALTYPE),			\
-	       (TREE_CODE (VALTYPE) == REAL_TYPE			\
-		&& TYPE_MODE (VALTYPE) != TFmode			\
-		&& !TARGET_SOFT_FLOAT) ? 32 : 28)
+#define FUNCTION_VALUE(VALTYPE, FUNC) function_value (VALTYPE, FUNC)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
Index: config/pa/pa.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.114
diff -u -3 -p -r1.114 pa.md
--- config/pa/pa.md	31 Oct 2002 03:13:43 -0000	1.114
+++ config/pa/pa.md	22 Nov 2002 01:07:41 -0000
@@ -6121,7 +6121,7 @@
 }")
 
 (define_insn "call_value_internal_symref"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand 1 "call_operand_address" ""))
 	      (match_operand 2 "" "i")))
    (clobber (reg:SI 1))
@@ -6138,7 +6138,7 @@
    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
 
 (define_insn "call_value_internal_reg_64bit"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
          (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
 	       (match_operand 2 "" "i")))
    (clobber (reg:SI 2))
@@ -6154,7 +6154,7 @@
    (set (attr "length") (const_int 12))])
 
 (define_insn "call_value_internal_reg"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
 	(call (mem:SI (reg:SI 22))
 	      (match_operand 1 "" "i")))
    (clobber (reg:SI 1))
@@ -6376,7 +6376,7 @@
 }")
 
 (define_insn "sibcall_value_internal_symref"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand 1 "call_operand_address" ""))
 	      (match_operand 2 "" "i")))
    (clobber (reg:SI 1))
@@ -6392,7 +6392,7 @@
    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
 
 (define_insn "sibcall_value_internal_symref_64bit"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand 1 "call_operand_address" ""))
 	      (match_operand 2 "" "i")))
    (clobber (reg:SI 1))


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