OSDN Git Service

* config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Oct 2003 14:36:23 +0000 (14:36 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Oct 2003 14:36:23 +0000 (14:36 +0000)
TARGET_POWREPC64.
(UNITS_PER_GPR_WORD): Define.
(HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
(HARD_REGNO_CALL_PART_CLOBBERED): Define.
(HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
(CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
* config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
DFmode and DImode in 32-bit ABI / 64-bit computation mode.
(rs6000_emit_prologue): Select reg_mode and reg_size using
TARGET_32BIT, not TARGET_POWERPC64.
(rs6000_function_value): Generate PARALLEL for DImode in 32-bit
ABI / 64-bit computation mode

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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index 0123b86..b1132f9 100644 (file)
@@ -1,3 +1,20 @@
+2003-10-23  Fariborz Jahanian  <fjahanian@apple.com>
+           David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
+       TARGET_POWREPC64.
+       (UNITS_PER_GPR_WORD): Define.
+       (HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
+       (HARD_REGNO_CALL_PART_CLOBBERED): Define.
+       (HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
+       (CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
+       * config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
+       DFmode and DImode in 32-bit ABI / 64-bit computation mode.
+       (rs6000_emit_prologue): Select reg_mode and reg_size using
+       TARGET_32BIT, not TARGET_POWERPC64.
+       (rs6000_function_value): Generate PARALLEL for DImode in 32-bit
+       ABI / 64-bit computation mode
+
 2003-10-22  Andrew Haley  <aph@redhat.com>
 
        * toplev.c (output_file_directive): Allow for null input_name.
index 1680775..2387ea7 100644 (file)
@@ -4071,6 +4071,53 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                      || (align_words < GP_ARG_NUM_REG))))
            return gen_rtx_REG (mode, cum->fregno);
 
+         if (TARGET_32BIT && TARGET_POWERPC64 && mode == DFmode)
+           {
+              /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
+                in vararg list into zero, one or two GPRs */
+             if (align_words >= GP_ARG_NUM_REG)
+               return gen_rtx_PARALLEL (DFmode,
+                 gen_rtvec (2,
+                            gen_rtx_EXPR_LIST (VOIDmode,
+                                               NULL_RTX, const0_rtx), 
+                            gen_rtx_EXPR_LIST (VOIDmode,
+                                               gen_rtx_REG (mode,
+                                                            cum->fregno),
+                                               const0_rtx)));
+             else if (align_words + RS6000_ARG_SIZE (mode, type)
+                      > GP_ARG_NUM_REG)
+               /* If this is partially on the stack, then we only
+                  include the portion actually in registers here. */
+               return gen_rtx_PARALLEL (DFmode,
+                 gen_rtvec (2,   
+                            gen_rtx_EXPR_LIST (VOIDmode,
+                                               gen_rtx_REG (SImode,
+                                                            GP_ARG_MIN_REG
+                                                            + align_words),
+                                               const0_rtx),
+                            gen_rtx_EXPR_LIST (VOIDmode,
+                                               gen_rtx_REG (mode,
+                                                            cum->fregno),
+                                               const0_rtx)));
+
+             /* split a DFmode arg into two GPRs */
+             return gen_rtx_PARALLEL (DFmode,
+               gen_rtvec (3,
+                          gen_rtx_EXPR_LIST (VOIDmode,       
+                                             gen_rtx_REG (SImode,
+                                                          GP_ARG_MIN_REG
+                                                          + align_words),
+                                             const0_rtx),
+                          gen_rtx_EXPR_LIST (VOIDmode,
+                                             gen_rtx_REG (SImode,
+                                                          GP_ARG_MIN_REG
+                                                          + align_words + 1),
+                                             GEN_INT (4)),
+                          gen_rtx_EXPR_LIST (VOIDmode,
+                                             gen_rtx_REG (mode, cum->fregno),
+                                             const0_rtx)));
+            }
+
           return gen_rtx_PARALLEL (mode,
            gen_rtvec (2,
                       gen_rtx_EXPR_LIST (VOIDmode,
@@ -4091,6 +4138,37 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                                gen_rtx_REG (mode, cum->fregno),
                                const0_rtx)));
        }
+      /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+        or two GPRs */
+      else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
+              && align_words < GP_ARG_NUM_REG - 1)
+       {
+         return gen_rtx_PARALLEL (DImode,
+           gen_rtvec (2,
+                      gen_rtx_EXPR_LIST (VOIDmode,
+                                         gen_rtx_REG (SImode,
+                                                      GP_ARG_MIN_REG
+                                                      + align_words),
+                                         const0_rtx),
+                      gen_rtx_EXPR_LIST (VOIDmode,
+                                         gen_rtx_REG (SImode,
+                                                      GP_ARG_MIN_REG
+                                                      + align_words + 1),
+                                         GEN_INT (4))));
+       }
+      else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
+              && align_words == GP_ARG_NUM_REG - 1)
+       {
+         return gen_rtx_PARALLEL (DImode,
+           gen_rtvec (2,
+                      gen_rtx_EXPR_LIST (VOIDmode,
+                                         NULL_RTX, const0_rtx),
+                      gen_rtx_EXPR_LIST (VOIDmode,
+                                         gen_rtx_REG (SImode,
+                                                      GP_ARG_MIN_REG
+                                                      + align_words),
+                                         const0_rtx)));
+       }
       else if (align_words < GP_ARG_NUM_REG)
        return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
       else
@@ -11278,8 +11356,8 @@ void
 rs6000_emit_prologue (void)
 {
   rs6000_stack_t *info = rs6000_stack_info ();
-  enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
-  int reg_size = TARGET_POWERPC64 ? 8 : 4;
+  enum machine_mode reg_mode = Pmode;
+  int reg_size = UNITS_PER_WORD;
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
   rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
   rtx frame_reg_rtx = sp_reg_rtx;
@@ -11744,8 +11822,8 @@ rs6000_emit_epilogue (int sibcall)
   int sp_offset = 0;
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
   rtx frame_reg_rtx = sp_reg_rtx;
-  enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
-  int reg_size = TARGET_POWERPC64 ? 8 : 4;
+  enum machine_mode reg_mode = Pmode;
+  int reg_size = UNITS_PER_WORD;
   int i;
 
   info = rs6000_stack_info ();
@@ -15357,6 +15435,20 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
   enum machine_mode mode;
   unsigned int regno;
 
+  if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
+    {
+      /* Long long return value need be split in -mpowerpc64, 32bit ABI.  */
+      return gen_rtx_PARALLEL (DImode,
+       gen_rtvec (2,
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode, GP_ARG_RETURN),
+                                     const0_rtx),
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode,
+                                                  GP_ARG_RETURN + 1),
+                                     GEN_INT (4))));
+    }
+
   if ((INTEGRAL_TYPE_P (valtype)
        && TYPE_PRECISION (valtype) < BITS_PER_WORD)
       || POINTER_TYPE_P (valtype))
index 8ab42b1..3665b0a 100644 (file)
@@ -625,7 +625,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define MAX_BITS_PER_WORD 64
 
 /* Width of a word, in units (bytes).  */
-#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
+#define UNITS_PER_WORD (TARGET_32BIT ? 4 : 8)
 #ifdef IN_LIBGCC2
 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
 #else
@@ -988,6 +988,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    POWER and PowerPC GPRs hold 32 bits worth;
    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
 
+#define UNITS_PER_GPR_WORD (! TARGET_POWERPC64 ? 4 : 8)
+
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
   (FP_REGNO_P (REGNO)                                                  \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
@@ -995,7 +997,12 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
    : ALTIVEC_REGNO_P (REGNO)                                           \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
-   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+   : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD))
+
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)    \
+  ((TARGET_32BIT && TARGET_POWERPC64                   \
+    && (MODE == DImode || MODE == DFmode)              \
+    && INT_REGNO_P (REGNO)) ? 1 : 0)
 
 #define ALTIVEC_VECTOR_MODE(MODE)      \
         ((MODE) == V16QImode           \
@@ -1035,7 +1042,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
    : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
    : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
-   : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
+   : GET_MODE_SIZE (MODE) <= UNITS_PER_GPR_WORD)
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -1458,7 +1465,7 @@ enum reg_class
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
  (((CLASS) == FLOAT_REGS)                                              \
   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
-  : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+  : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD))
 
 
 /* Return a class of registers that cannot change FROM mode to TO mode.  */