OSDN Git Service

Back out these patches:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Jun 2003 17:22:05 +0000 (17:22 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Jun 2003 17:22:05 +0000 (17:22 +0000)
 2003-06-02  J"orn Rennecke <joern.rennecke@superh.com>
          * sh.h (OLD_ARG_MODE): New macro.
          (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
          (FUNCTION_ARG_1): Break out of:
          (FUNCTION_ARG).  Use OLD_ARG_MODE.
 2003-06-06  J"orn Rennecke <joern.rennecke@superh.com>
          * sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
          of the generated register.

* sh.h (FUNCTION_ARG_SCmode_WART): Define.
(FUNCTION_ARG): Unless FUNCTION_ARG_SCmode_WART is defined and
an even number of floating point regs are in use, use the same
sequence of argument passing registers for SCmode as would be
used for two SFmode values.
* sh.c (sh_va_arg): If FUNCTION_ARG_SCmode_WART is defined,
swap real / imaginary parts in incoming SCmode values passed
in registers.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68430 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h

index 53609e4..6b63396 100644 (file)
@@ -1,3 +1,24 @@
+2003-06-24  J"orn Rennecke <joern.rennecke@superh.com>
+
+       Back out these patches:
+        2003-06-02  J"orn Rennecke <joern.rennecke@superh.com>
+          * sh.h (OLD_ARG_MODE): New macro.
+          (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
+          (FUNCTION_ARG_1): Break out of:
+          (FUNCTION_ARG).  Use OLD_ARG_MODE.
+        2003-06-06  J"orn Rennecke <joern.rennecke@superh.com>
+          * sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
+          of the generated register.
+
+       * sh.h (FUNCTION_ARG_SCmode_WART): Define.
+       (FUNCTION_ARG): Unless FUNCTION_ARG_SCmode_WART is defined and
+       an even number of floating point regs are in use, use the same
+       sequence of argument passing registers for SCmode as would be 
+       used for two SFmode values.
+       * sh.c (sh_va_arg): If FUNCTION_ARG_SCmode_WART is defined,
+       swap real / imaginary parts in incoming SCmode values passed
+       in registers.
+
 2003-06-24  Falk Hueffner  <falk.hueffner@student.uni-tuebingen.de>
 
         PR target/11260
index 070e409..aab3c39 100644 (file)
@@ -5940,8 +5940,9 @@ sh_va_arg (valist, type)
   HOST_WIDE_INT size, rsize;
   tree tmp, pptr_type_node;
   rtx addr_rtx, r;
-  rtx result;
+  rtx result_ptr, result = NULL_RTX;
   int pass_by_ref = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
+  rtx lab_over;
 
   size = int_size_in_bytes (type);
   rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
@@ -5955,7 +5956,7 @@ sh_va_arg (valist, type)
       tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
       tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack;
       int pass_as_float;
-      rtx lab_false, lab_over;
+      rtx lab_false;
 
       f_next_o = TYPE_FIELDS (va_list_type_node);
       f_next_o_limit = TREE_CHAIN (f_next_o);
@@ -5973,6 +5974,16 @@ sh_va_arg (valist, type)
       next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
                          valist, f_next_stack);
 
+      /* Structures with a single member with a distinct mode are passed
+        like their member.  This is relevant if the latter has a REAL_TYPE
+        or COMPLEX_TYPE type.  */
+      if (TREE_CODE (type) == RECORD_TYPE
+         && TYPE_FIELDS (type)
+         && TREE_CODE (TYPE_FIELDS (type)) == FIELD_DECL
+         && (TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == REAL_TYPE
+             || TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == COMPLEX_TYPE)
+          && TREE_CHAIN (TYPE_FIELDS (type)) == NULL_TREE)
+       type = TREE_TYPE (TYPE_FIELDS (type));
       if (TARGET_SH4)
        {
          pass_as_float = ((TREE_CODE (type) == REAL_TYPE && size <= 8)
@@ -5989,6 +6000,9 @@ sh_va_arg (valist, type)
       lab_false = gen_label_rtx ();
       lab_over = gen_label_rtx ();
 
+      tmp = make_tree (pptr_type_node, addr_rtx);
+      valist = build1 (INDIRECT_REF, ptr_type_node, tmp);
+
       if (pass_as_float)
        {
          int first_floatreg
@@ -6018,6 +6032,37 @@ sh_va_arg (valist, type)
          if (r != addr_rtx)
            emit_move_insn (addr_rtx, r);
 
+#ifdef FUNCTION_ARG_SCmode_WART
+         if (TYPE_MODE (type) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN)
+           {
+             rtx addr, real, imag, result_value, slot;
+             tree subtype = TREE_TYPE (type);
+
+             addr = std_expand_builtin_va_arg (valist, subtype);
+#ifdef POINTERS_EXTEND_UNSIGNED
+             if (GET_MODE (addr) != Pmode)
+               addr = convert_memory_address (Pmode, addr);
+#endif
+             imag = gen_rtx_MEM (TYPE_MODE (type), addr);
+             set_mem_alias_set (imag, get_varargs_alias_set ());
+
+             addr = std_expand_builtin_va_arg (valist, subtype);
+#ifdef POINTERS_EXTEND_UNSIGNED
+             if (GET_MODE (addr) != Pmode)
+               addr = convert_memory_address (Pmode, addr);
+#endif
+             real = gen_rtx_MEM (TYPE_MODE (type), addr);
+             set_mem_alias_set (real, get_varargs_alias_set ());
+
+             result_value = gen_rtx_CONCAT (SCmode, real, imag);
+             /* ??? this interface is stupid - why require a pointer?  */
+             result = gen_reg_rtx (Pmode);
+             slot = assign_stack_temp (SCmode, 8, 0);
+             emit_move_insn (slot, result_value);
+             emit_move_insn (result, XEXP (slot, 0));
+           }
+#endif /* FUNCTION_ARG_SCmode_WART */
+
          emit_jump_insn (gen_jump (lab_over));
          emit_barrier ();
          emit_label (lab_false);
@@ -6060,16 +6105,22 @@ sh_va_arg (valist, type)
            emit_move_insn (addr_rtx, r);
        }
 
-      emit_label (lab_over);
-
-      tmp = make_tree (pptr_type_node, addr_rtx);
-      valist = build1 (INDIRECT_REF, ptr_type_node, tmp);
+      if (! result)
+        emit_label (lab_over);
     }
 
   /* ??? In va-sh.h, there had been code to make values larger than
      size 8 indirect.  This does not match the FUNCTION_ARG macros.  */
 
-  result = std_expand_builtin_va_arg (valist, type);
+  result_ptr = std_expand_builtin_va_arg (valist, type);
+  if (result)
+    {
+      emit_move_insn (result, result_ptr);
+      emit_label (lab_over);
+    }
+  else
+    result = result_ptr;
+
   if (pass_by_ref)
     {
 #ifdef POINTERS_EXTEND_UNSIGNED
index 2c62d47..ee49f6b 100644 (file)
@@ -1867,20 +1867,12 @@ struct sh_args {
     (CUM).outgoing = 0;                                                \
   } while (0)
  
-#define OLD_ARG_MODE(MODE, TYPE) \
-  (((TYPE) \
-    && (TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE) \
-    && (MODE) != BLKmode && GET_MODE_CLASS (MODE) != MODE_INT) \
-   ? int_mode_for_mode (MODE) : (MODE))
-
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
    (TYPE is null for libcalls where that information may not be
    available.)  */
 
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
-do {                                                   \
- enum machine_mode MODE_ = OLD_ARG_MODE ((MODE), (TYPE));\
  if ((CUM).force_mem)                                  \
    (CUM).force_mem = 0;                                        \
  else if (TARGET_SH5)                                  \
@@ -1888,17 +1880,17 @@ do {                                                    \
      tree TYPE_ = ((CUM).byref && (TYPE)               \
                   ? TREE_TYPE (TYPE)                   \
                   : (TYPE));                           \
-     int dwords, numregs;                              \
+     enum machine_mode MODE_ = ((CUM).byref && (TYPE)  \
+                               ? TYPE_MODE (TYPE_)     \
+                               : (MODE));              \
+     int dwords = (((CUM).byref                                \
+                   ? (CUM).byref                       \
+                   : (MODE_) == BLKmode                \
+                   ? int_size_in_bytes (TYPE_)         \
+                   : GET_MODE_SIZE (MODE_)) + 7) / 8;  \
+     int numregs = MIN (dwords, NPARM_REGS (SImode)    \
+                       - (CUM).arg_count[(int) SH_ARG_INT]); \
                                                        \
-     MODE_ = ((CUM).byref && (TYPE)                    \
-             ? TYPE_MODE (TYPE_) : (MODE_));           \
-     dwords = (((CUM).byref                            \
-               ? (CUM).byref                           \
-               : (MODE_) == BLKmode                    \
-               ? int_size_in_bytes (TYPE_)             \
-               : GET_MODE_SIZE (MODE_)) + 7) / 8;      \
-     numregs = MIN (dwords, NPARM_REGS (SImode)                \
-                   - (CUM).arg_count[(int) SH_ARG_INT]); \
      if (numregs)                                      \
        {                                               \
         (CUM).arg_count[(int) SH_ARG_INT] += numregs;  \
@@ -1990,13 +1982,12 @@ do {                                                    \
           }                                            \
        }                                               \
    }                                                   \
- else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE_), (TYPE))) \
-   ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE_)]    \
-    = (ROUND_REG ((CUM), (MODE_))                      \
-       + ((MODE_) == BLKmode                           \
+ else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
+   ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)]     \
+    = (ROUND_REG ((CUM), (MODE))                       \
+       + ((MODE) == BLKmode                            \
          ? ROUND_ADVANCE (int_size_in_bytes (TYPE))    \
-         : ROUND_ADVANCE (GET_MODE_SIZE (MODE_)))));   \
-} while (0)
+         : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))))
 
 /* Return boolean indicating arg of mode MODE will be passed in a reg.
    This macro is only used in this file.  */
@@ -2016,6 +2007,24 @@ do {                                                     \
             <= NPARM_REGS (MODE))) \
        : ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)))
 
+/* By accident we got stuck with passing SCmode on SH4 little endian
+   in two registers that are nominally successive - which is different from
+   two single SFmode values, where we take endianness translation into
+   account.  That does not work at all if an odd number of registers is
+   already in use, so that got fixed, but library functions are still more
+   likely to use complex numbers without mixing them with SFmode arguments
+   (which in C would have to be structures), so for the sake of ABI
+   compatibility the way SCmode values are passed when an even number of
+   FP registers is in use remains different from a pair of SFmode values for
+   now.
+   I.e.:
+   foo (double); a: fr5,fr4
+   foo (float a, float b); a: fr5 b: fr4
+   foo (__complex float a); a.real fr4 a.imag: fr5 - for consistency,
+                            this should be the other way round...
+   foo (float a, __complex float b); a: fr5 b.real: fr4 b.imag: fr7  */
+#define FUNCTION_ARG_SCmode_WART 1
+
 /* Define where to put the arguments to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
@@ -2035,29 +2044,44 @@ do {                                                    \
    its data type forbids.  */
 
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-  FUNCTION_ARG_1 ((CUM), OLD_ARG_MODE ((MODE), (TYPE)), (MODE), (TYPE), (NAMED))
-
-#define FUNCTION_ARG_1(CUM, MODE, NEW_MODE, TYPE, NAMED) \
   ((! TARGET_SH5 \
     && PASS_IN_REG_P ((CUM), (MODE), (TYPE))                           \
     && ((NAMED) || !TARGET_HITACHI))                                   \
-   ? gen_rtx_REG ((NEW_MODE),                                          \
-                 ((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE)))    \
-                  ^ ((MODE) == SFmode && TARGET_SH4                    \
-                     && TARGET_LITTLE_ENDIAN != 0)))                   \
+   ? (((MODE) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN          \
+       && (! FUNCTION_ARG_SCmode_WART || (ROUND_REG ((CUM), (MODE)) & 1)))\
+      ? (gen_rtx_PARALLEL                                              \
+        (SCmode,                                                       \
+         (gen_rtvec                                                    \
+          (2,                                                          \
+           (gen_rtx_EXPR_LIST                                          \
+            (VOIDmode,                                                 \
+             gen_rtx_REG (SFmode,                                      \
+                          BASE_ARG_REG (MODE)                          \
+                          + ROUND_REG ((CUM), (MODE)) ^ 1),            \
+             const0_rtx)),                                             \
+           (gen_rtx_EXPR_LIST                                          \
+            (VOIDmode,                                                 \
+             gen_rtx_REG (SFmode,                                      \
+                          BASE_ARG_REG (MODE)                          \
+                          + (ROUND_REG ((CUM), (MODE)) + 1) ^ 1),      \
+             GEN_INT (4)))))))                                         \
+      : gen_rtx_REG ((MODE),                                           \
+                    ((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
+                     ^ ((MODE) == SFmode && TARGET_SH4                 \
+                        && TARGET_LITTLE_ENDIAN != 0))))               \
    : TARGET_SH5                                                                \
    ? ((MODE) == VOIDmode && TARGET_SHCOMPACT                           \
       ? GEN_INT ((CUM).call_cookie)                                    \
       /* The following test assumes unnamed arguments are promoted to  \
         DFmode.  */                                                    \
       : (MODE) == SFmode && (CUM).free_single_fp_reg                   \
-      ? SH5_PROTOTYPED_FLOAT_ARG ((CUM), (NEW_MODE), (CUM).free_single_fp_reg) \
+      ? SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE), (CUM).free_single_fp_reg) \
       : (GET_SH_ARG_CLASS (MODE) == SH_ARG_FLOAT                       \
          && ((NAMED) || ! (CUM).prototype_p)                           \
          && (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (SFmode)) \
       ? ((! (CUM).prototype_p && TARGET_SHMEDIA)                       \
-        ? SH5_PROTOTYPELESS_FLOAT_ARG ((CUM), (NEW_MODE))              \
-        : SH5_PROTOTYPED_FLOAT_ARG ((CUM), (NEW_MODE),                 \
+        ? SH5_PROTOTYPELESS_FLOAT_ARG ((CUM), (MODE))                  \
+        : SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE),                     \
                                     FIRST_FP_PARM_REG                  \
                                     + (CUM).arg_count[(int) SH_ARG_FLOAT])) \
       : ((CUM).arg_count[(int) SH_ARG_INT] < NPARM_REGS (SImode)       \
@@ -2065,7 +2089,7 @@ do {                                                      \
             || (! SHCOMPACT_FORCE_ON_STACK ((MODE), (TYPE))            \
                 && ! SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE),        \
                                                  (TYPE), (NAMED)))))   \
-      ? gen_rtx_REG ((NEW_MODE), (FIRST_PARM_REG                       \
+      ? gen_rtx_REG ((MODE), (FIRST_PARM_REG                           \
                              + (CUM).arg_count[(int) SH_ARG_INT]))     \
       : 0)                                                             \
    : 0)
@@ -2076,7 +2100,7 @@ do {                                                      \
    loads them into the full 64-bits registers.  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) \
   (MUST_PASS_IN_STACK ((MODE), (TYPE)) \
-   || SHCOMPACT_BYREF ((CUM), OLD_ARG_MODE ((MODE), (TYPE)), (TYPE), (NAMED)))
+   || SHCOMPACT_BYREF ((CUM), (MODE), (TYPE), (NAMED)))
 
 #define SHCOMPACT_BYREF(CUM, MODE, TYPE, NAMED) \
   ((CUM).byref                                                         \