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]

fix Xtensa ABI for structures returned in registers


I just discovered a case where GCC doesn't match the Xtensa ABI for big-endian processors. The ABI allows up to 4 registers to be used for a return value. If the structure is smaller than a word, it is correctly passed in the least-significant part of the first register. For structures bigger than a word, however, GCC pads at the wrong end. The padding is supposed to go in the least-significant bytes of the last register used, i.e., the value is supposed to go in the most-significant bytes. This is the same padding scheme used for passing structures as arguments in registers on Xtensa.

I've tested this with an xtensa-elf target. I also ran the compat testsuite with Tensilica's compiler set as the alternate compiler. I've committed the patch on the mainline and the 3.4 branch.

Tomorrow I will work on a patch for the 3.4 changes.html file to describe this ABI change. (There may also be another minor patch needed to comply with the Xtensa ABI.) My inclination is to include a short description in the section on changes for Xtensa, as opposed to adding a whole new file as was done for SPARC and MIPS ABI change descriptions.


2004-03-04 Bob Wilson <bob.wilson@acm.org>


	* config/xtensa/xtensa.c (xtensa_return_in_msb): New function.
	(TARGET_RETURN_IN_MSB): Define to xtensa_return_in_msb.


Index: xtensa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.c,v
retrieving revision 1.51
diff -u -r1.51 xtensa.c
--- xtensa.c	10 Feb 2004 01:35:53 -0000	1.51
+++ xtensa.c	5 Mar 2004 01:04:14 -0000
@@ -200,6 +200,7 @@
 static rtx fixup_subreg_mem (rtx);
 static enum machine_mode xtensa_find_mode_for_size (unsigned);
 static struct machine_function * xtensa_init_machine_status (void);
+static bool xtensa_return_in_msb (tree);
 static void printx (FILE *, signed int);
 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
 static rtx xtensa_builtin_saveregs (void);
@@ -254,6 +255,9 @@
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
 
+#undef TARGET_RETURN_IN_MSB
+#define TARGET_RETURN_IN_MSB xtensa_return_in_msb
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -1812,6 +1816,15 @@
     cfun->machine->need_a7_copy = true;
 
   return gen_rtx_REG (mode, regno);
+}
+
+
+static bool
+xtensa_return_in_msb (tree valtype)
+{
+  return (TARGET_BIG_ENDIAN
+	  && AGGREGATE_TYPE_P (valtype)
+	  && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
 }
 
 

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