]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* config/s390/s390-protos.h (s390_output_pool_entry): Declare.
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 23 Aug 2003 00:17:35 +0000 (00:17 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 23 Aug 2003 00:17:35 +0000 (00:17 +0000)
* config/s390/s390.c (gen_consttable): Remove.
(s390_dump_pool): Use UNSPECV_POOL_ENTRY for pool entry insns.
(s390_output_pool_entry): New function.
* config/s390/s390.md (UNSPECV_POOL_QI, UNSPECV_POOL_HI,
UNSPECV_POOL_SI, UNSPECV_POOL_DI, UNSPECV_POOL_TI,
UNSPECV_POOL_SF, UNSPECV_POOL_DF): Remove, replace by ...
(UNSPECV_POOL_ENTRY): ... this new constant.
("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
"consttable_ti", "consttable_sf", "consttable_df"): Remove ...
("*pool_entry"): ... and replace by this new insn.
("literal_pool_31"): Do not emit anchor label if pool empty.

* config/s390/s390.c (struct machine_function): Add save_return_addr_p.
(s390_optimize_prolog): Save RETURN_REGNUM if save_return_addr_p.
(s390_fixup_clobbered_return_reg): Remove.
(s390_reorg): Don't call s390_fixup_clobbered_return_reg.
(s390_return_addr_rtx): Always retrieve return address from save area
slot.  Use save_return_addr_p to force slot to be filled.
(s390_emit_prologue): Remove has_hard_reg_initial_val test.

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

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index 85e8b8778e0635bd04bfe451bf67fea0c38126ec..cc8bd095b276f1f11debc12b7c0b3c0dc0ff30ea 100644 (file)
@@ -1,3 +1,26 @@
+2003-08-23  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390-protos.h (s390_output_pool_entry): Declare.
+       * config/s390/s390.c (gen_consttable): Remove.
+       (s390_dump_pool): Use UNSPECV_POOL_ENTRY for pool entry insns.
+       (s390_output_pool_entry): New function.
+       * config/s390/s390.md (UNSPECV_POOL_QI, UNSPECV_POOL_HI, 
+       UNSPECV_POOL_SI, UNSPECV_POOL_DI, UNSPECV_POOL_TI, 
+       UNSPECV_POOL_SF, UNSPECV_POOL_DF): Remove, replace by ...
+       (UNSPECV_POOL_ENTRY): ... this new constant.
+       ("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
+       "consttable_ti", "consttable_sf", "consttable_df"): Remove ...
+       ("*pool_entry"): ... and replace by this new insn.
+       ("literal_pool_31"): Do not emit anchor label if pool empty.
+
+       * config/s390/s390.c (struct machine_function): Add save_return_addr_p.
+       (s390_optimize_prolog): Save RETURN_REGNUM if save_return_addr_p.
+       (s390_fixup_clobbered_return_reg): Remove.
+       (s390_reorg): Don't call s390_fixup_clobbered_return_reg.
+       (s390_return_addr_rtx): Always retrieve return address from save area
+       slot.  Use save_return_addr_p to force slot to be filled.
+       (s390_emit_prologue): Remove has_hard_reg_initial_val test.
+
 2003-08-22  Chris Demetriou  <cgd@broadcom.com>
 
        * config/mips/mips.h (MASK_FIX_SB1, TARGET_FIX_SB1): New defines.
index c64e97413188feaa1cf9db835952c15508358777..40026d3b85f66b056e3364c56be2ab9e416c7e13 100644 (file)
@@ -80,6 +80,8 @@ extern void s390_output_symbolic_const (FILE *, rtx);
 extern void print_operand_address (FILE *, rtx);
 extern void print_operand (FILE *, rtx, int);
 extern void s390_output_constant_pool (rtx, rtx);
+extern void s390_output_pool_entry (FILE *, rtx, enum machine_mode, 
+                                   unsigned int);
 extern void s390_trampoline_template (FILE *);
 extern void s390_initialize_trampoline (rtx, rtx, rtx);
 extern rtx s390_gen_rtx_const_DI (int, int);
index 55e5149cbd110cf2400b37f7aab555a1f98aed75..568a35b888e6c8f7373f5c37f9490acae27096a1 100644 (file)
@@ -189,6 +189,10 @@ struct machine_function GTY(())
   /* Set, if some of the fprs 8-15 need to be saved (64 bit abi).  */
   int save_fprs_p;
 
+  /* Set if return address needs to be saved because the current
+     function uses __builtin_return_addr (0).  */
+  bool save_return_addr_p;
+
   /* Number of first and last gpr to be saved, restored.  */
   int first_save_gpr;
   int first_restore_gpr;
@@ -220,7 +224,6 @@ static void replace_constant_pool_ref (rtx *, rtx, rtx);
 static rtx find_ltrel_base (rtx);
 static void replace_ltrel_base (rtx *, rtx);
 static void s390_optimize_prolog (int);
-static bool s390_fixup_clobbered_return_reg (rtx);
 static int find_unused_clobbered_reg (void);
 static void s390_frame_info (void);
 static rtx save_fpr (rtx, int, int);
@@ -4049,11 +4052,6 @@ enum machine_mode constant_modes[NR_C_MODES] =
   QImode
 };
 
-rtx (*gen_consttable[NR_C_MODES])(rtx) =
-{
-  gen_consttable_ti, gen_consttable_df, gen_consttable_di, gen_consttable_sf, gen_consttable_si, gen_consttable_hi, gen_consttable_qi
-};
-
 struct constant
 {
   struct constant *next;
@@ -4249,7 +4247,11 @@ s390_dump_pool (struct constant_pool *pool)
 
        insn = emit_label_after (c->label, insn);
        INSN_ADDRESSES_NEW (insn, -1);
-       insn = emit_insn_after (gen_consttable[i] (value), insn);
+
+       value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i], 
+                                        gen_rtvec (1, value),
+                                        UNSPECV_POOL_ENTRY);
+       insn = emit_insn_after (value, insn);
        INSN_ADDRESSES_NEW (insn, -1);
       }
 
@@ -4717,6 +4719,46 @@ s390_output_constant_pool (rtx start_label, rtx end_label)
     }
 }
 
+/* Output to FILE the constant pool entry EXP in mode MODE
+   with alignment ALIGN.  */
+
+void
+s390_output_pool_entry (FILE *file, rtx exp, enum machine_mode mode, 
+                       unsigned int align)
+{
+  REAL_VALUE_TYPE r;
+
+  switch (GET_MODE_CLASS (mode))
+    {
+    case MODE_FLOAT:
+      if (GET_CODE (exp) != CONST_DOUBLE)
+       abort ();
+
+      REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
+      assemble_real (r, mode, align);
+      break;
+
+    case MODE_INT:
+      if (GET_CODE (exp) == CONST
+         || GET_CODE (exp) == SYMBOL_REF
+         || GET_CODE (exp) == LABEL_REF)
+       {
+         fputs (integer_asm_op (GET_MODE_SIZE (mode), TRUE), file);
+         s390_output_symbolic_const (file, exp);
+         fputc ('\n', file);
+       }
+      else
+       {
+         assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
+       }
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+
 /* Rework the prolog/epilog to avoid saving/restoring
    registers unnecessarily.  If TEMP_REGNO is nonnegative,
    it specifies the number of a caller-saved register used
@@ -4742,8 +4784,11 @@ s390_optimize_prolog (int temp_regno)
     regs_ever_live[BASE_REGISTER] = 1;
 
   /* In non-leaf functions, the prolog/epilog code relies
-     on RETURN_REGNUM being saved in any case.  */
-  if (!current_function_is_leaf)
+     on RETURN_REGNUM being saved in any case.  We also need
+     to save the return register if __builtin_return_address (0)
+     was used in the current function.  */
+  if (!current_function_is_leaf 
+      || cfun->machine->save_return_addr_p)
     regs_ever_live[RETURN_REGNUM] = 1;
 
   /* We need to save/restore the temporary register.  */
@@ -4868,68 +4913,11 @@ s390_optimize_prolog (int temp_regno)
     }
 }
 
-/* Check whether any insn in the function makes use of the original
-   value of RETURN_REG (e.g. for __builtin_return_address).
-   If so, insert an insn reloading that value.
-
-   Return true if any such insn was found.  */
-
-static bool
-s390_fixup_clobbered_return_reg (rtx return_reg)
-{
-  bool replacement_done = 0;
-  rtx insn;
-
-  /* If we never called __builtin_return_address, register 14
-     might have been used as temp during the prolog; we do
-     not want to touch those uses.  */
-  if (!has_hard_reg_initial_val (Pmode, REGNO (return_reg)))
-    return false;
-
-  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    {
-      rtx reg, off, new_insn;
-
-      if (GET_CODE (insn) != INSN)
-       continue;
-      if (!reg_referenced_p (return_reg, PATTERN (insn)))
-       continue;
-      if (GET_CODE (PATTERN (insn)) == PARALLEL
-         && store_multiple_operation (PATTERN (insn), VOIDmode))
-       continue;
-
-      if (frame_pointer_needed)
-       reg = hard_frame_pointer_rtx;
-      else
-       reg = stack_pointer_rtx;
-
-      off = GEN_INT (cfun->machine->frame_size + REGNO (return_reg) * UNITS_PER_WORD);
-      if (!DISP_IN_RANGE (INTVAL (off)))
-       {
-         off = force_const_mem (Pmode, off);
-         new_insn = gen_rtx_SET (Pmode, return_reg, off);
-         new_insn = emit_insn_before (new_insn, insn);
-         INSN_ADDRESSES_NEW (new_insn, -1);
-         off = return_reg;
-       }
-
-      new_insn = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, reg, off));
-      new_insn = gen_rtx_SET (Pmode, return_reg, new_insn);
-      new_insn = emit_insn_before (new_insn, insn);
-      INSN_ADDRESSES_NEW (new_insn, -1);
-
-      replacement_done = 1;
-    }
-
-  return replacement_done;
-}
-
 /* Perform machine-dependent processing.  */
 
 static void
 s390_reorg (void)
 {
-  bool fixed_up_clobbered_return_reg = 0;
   rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
   bool temp_used = 0;
 
@@ -4985,21 +4973,6 @@ s390_reorg (void)
           continue;
         }
 
-      /* Check whether we have clobbered a use of the return
-        register (e.g. for __builtin_return_address).  If so,
-        add insns reloading the register where necessary.  */
-      if (temp_used && !fixed_up_clobbered_return_reg
-         && s390_fixup_clobbered_return_reg (temp_reg))
-       {
-         fixed_up_clobbered_return_reg = 1;
-
-         /* The fixup insns might have caused a jump to overflow.  */
-         if (pool_list)
-           s390_chunkify_cancel (pool_list);
-
-         continue;
-       }
-
       /* If we made it up to here, both conditions are satisfied.
         Finish up pool chunkification if required.  */
       if (pool_list)
@@ -5021,13 +4994,13 @@ s390_return_addr_rtx (int count, rtx frame)
 {
   rtx addr;
 
-  /* For the current frame, we use the initial value of RETURN_REGNUM.
-     This works both in leaf and non-leaf functions.  */
+  /* For the current frame, we need to make sure the initial
+     value of RETURN_REGNUM is actually saved.  */
 
   if (count == 0)
-    return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
+    cfun->machine->save_return_addr_p = true;
 
-  /* For frames farther back, we read the stack slot where the
+  /* To retrieve the return address we read the stack slot where the
      corresponding RETURN_REGNUM value was saved.  */
 
   addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
@@ -5343,7 +5316,6 @@ s390_emit_prologue (void)
      See below for why TPF must use the register 1.  */
 
   if (!current_function_is_leaf
-      && !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
       && get_pool_size () < S390_POOL_CHUNK_MAX / 2
       && !TARGET_TPF)
     temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
index 4376b38ea6d091fb905faa83b347c9b76819d45e..d4664092f69aa5c0b7c50f952f8d9336b2663cfe 100644 (file)
    (UNSPECV_POOL               200)
    (UNSPECV_POOL_START         201)
    (UNSPECV_POOL_END           202)
-   (UNSPECV_POOL_QI            203)
-   (UNSPECV_POOL_HI            204)
-   (UNSPECV_POOL_SI            205)
-   (UNSPECV_POOL_DI            206)
-   (UNSPECV_POOL_TI            207)
-   (UNSPECV_POOL_SF            208)
-   (UNSPECV_POOL_DF            209)
+   (UNSPECV_POOL_ENTRY         203)
    (UNSPECV_MAIN_POOL          300)
 
    ; TLS support
 ; Special literal pool access instruction pattern(s).
 ;
 
-(define_insn "consttable_qi"
-  [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_QI)]
+(define_insn "*pool_entry"
+  [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
+                    UNSPECV_POOL_ENTRY)]
   ""
 {
-  assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
+  enum machine_mode mode = GET_MODE (PATTERN (insn));
+  unsigned int align = GET_MODE_BITSIZE (mode);
+  s390_output_pool_entry (asm_out_file, operands[0], mode, align);
   return "";
 }
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "1")])
-
-(define_insn "consttable_hi"
-  [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_HI)]
-  ""
-{
-  assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
-  return "";
-}
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "2")])
-
-(define_insn "consttable_si"
-  [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_SI)]
-  ""
-  ".long\t%0"
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "4")])
-
-(define_insn "consttable_di"
-  [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_DI)]
-  ""
-  ".quad\t%0"
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "8")])
-
-(define_insn "consttable_ti"
-  [(unspec_volatile [(match_operand:TI 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_TI)]
-  ""
-{
-  assemble_integer (operands[0], 16, 16*BITS_PER_UNIT, 1);
-  return "";
-}
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "16")])
-
-(define_insn "consttable_sf"
-  [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_SF)]
-  ""
-{
-  REAL_VALUE_TYPE r;
-
-  if (GET_CODE (operands[0]) != CONST_DOUBLE)
-    abort ();
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
-  assemble_real (r, SFmode, 4*BITS_PER_UNIT);
-  return "";
-}
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "4")])
-
-(define_insn "consttable_df"
-  [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")]
-                   UNSPECV_POOL_DF)]
-  ""
-{
-  REAL_VALUE_TYPE r;
-
-  if (GET_CODE (operands[0]) != CONST_DOUBLE)
-    abort ();
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
-  assemble_real (r, DFmode, 8*BITS_PER_UNIT);
-  return "";
-}
-  [(set_attr "op_type"  "NN")
-   (set_attr "length"   "8")])
+  [(set_attr "op_type" "NN")
+   (set (attr "length") 
+        (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
 
 (define_insn "pool_start_31"
   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
        output_asm_insn ("bras\t%0,%2", operands);
        s390_output_constant_pool (operands[1], operands[2]);
      }
-   else if (flag_pic)
-     {
-        /* We need the anchor label in any case.  */
-        (*targetm.asm_out.internal_label) (asm_out_file, "L",
-                                           CODE_LABEL_NUMBER (operands[1]));
-     }
 
    return "";
 }