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, nds32] Committed: Fix inaccurate alignment checking when passing BLKmode argument.


Hi, all,

There is a problem in nds32.h to determine available register number
for passing BLKmode argument.  The original checking only refers to
NDS32_NEED_N_REGS_FOR_ARG macro but that is not sufficient to make
decision of using odd or even register number.  It is supposed to
further check the type alignment.

We define a new macro NDS32_MODE_TYPE_ALIGN and rewrite
NDS32_AVAILABLE_REGNUM_FOR_ARG definition.

The patch for nds32.c and nds32.h is as follow:


Index: gcc/config/nds32/nds32.h
===================================================================
--- gcc/config/nds32/nds32.h	(revision 206139)
+++ gcc/config/nds32/nds32.h	(working copy)
@@ -126,6 +126,11 @@
 #define NDS32_SINGLE_WORD_ALIGN_P(value) (((value) & 0x03) == 0)
 #define NDS32_DOUBLE_WORD_ALIGN_P(value) (((value) & 0x07) == 0)
 
+/* Get alignment according to mode or type information.
+   When 'type' is nonnull, there is no need to look at 'mode'.  */
+#define NDS32_MODE_TYPE_ALIGN(mode, type) \
+  (type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode))
+
 /* Round X up to the nearest double word.  */
 #define NDS32_ROUND_UP_DOUBLE_WORD(value)  (((value) + 7) & ~7)
 
@@ -142,12 +147,18 @@
 /* This macro is used to return the register number for passing argument.
    We need to obey the following rules:
      1. If it is required MORE THAN one register,
-        make sure the register number is a even value.
+        we need to further check if it really needs to be
+        aligned on double words.
+          a) If double word alignment is necessary,
+             the register number must be even value.
+          b) Otherwise, the register number can be odd or even value.
      2. If it is required ONLY one register,
         the register number can be odd or even value.  */
-#define NDS32_AVAILABLE_REGNUM_FOR_ARG(reg_offset, mode, type) \
-  ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1)                \
-   ? (((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM + 1) & ~1)    \
+#define NDS32_AVAILABLE_REGNUM_FOR_ARG(reg_offset, mode, type)  \
+  ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1)                 \
+   ? ((NDS32_MODE_TYPE_ALIGN (mode, type) > PARM_BOUNDARY)      \
+      ? (((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM + 1) & ~1)  \
+      : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM))            \
    : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM))
 
 /* This macro is to check if there are still available registers

Index: gcc/config/nds32/nds32.c
===================================================================
--- gcc/config/nds32/nds32.c	(revision 206139)
+++ gcc/config/nds32/nds32.c	(working copy)
@@ -1438,8 +1438,8 @@
 {
   unsigned int align;
 
-  /* When 'type' is nonnull, there is no need to look at 'mode'.  */
-  align = (type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode));
+  /* Pick up the alignment according to the mode or type.  */
+  align = NDS32_MODE_TYPE_ALIGN (mode, type);
 
   return (align > PARM_BOUNDARY);
 }
@@ -1853,10 +1853,10 @@
   if (NDS32_ARG_PASS_IN_REG_P (cum->reg_offset, mode, type))
     {
       /* Pick up the next available register number.  */
-      return gen_rtx_REG (mode,
-			  NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset,
-							  mode,
-							  type));
+      unsigned int regno;
+
+      regno = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type);
+      return gen_rtx_REG (mode, regno);
     }
   else
     {


And the gcc/ChangeLog is as below:

+2013-12-20  Chung-Ju Wu  <jasonwucj@gmail.com>
+
+	* config/nds32/nds32.h (NDS32_MODE_TYPE_ALIGN): New macro.
+	(NDS32_AVAILABLE_REGNUM_FOR_ARG): Use more accurate alignment checking
+	to determine available register number.
+	* config/nds32/nds32.c (nds32_needs_double_word_align): Use new
+	macro NDS32_MODE_TYPE_ALIGN.
+	(nds32_function_arg): Refine code layout.
+
 2013-12-19  Jeff Law  <law@redhat.com>

	* doc/invoke.texi: (dump-rtl-ree): Fix typo and clarify ree


Bootstrapped and tested on nds32le-elf/nds32be-elf target.
Committed as Rev.206142:
  http://gcc.gnu.org/r206142


Best regards,
jasonwucj


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