s390.md (literal_pool_64, [...]): New insns.
authorHartmut Penner <hpenner@de.ibm.com>
Tue, 26 Nov 2002 15:26:40 +0000 (15:26 +0000)
committerHartmut Penner <hpenner@gcc.gnu.org>
Tue, 26 Nov 2002 15:26:40 +0000 (15:26 +0000)
  * config/s390/s390.md (literal_pool_64, literal_pool_31 ): New
insns.
* config/s390/s390.c (struct machine_function): Introduction of
struct machine_function.
* config/s390/s390-protos.h (s390_output_constant_pool): Changed
prototype.

From-SVN: r59515

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

index 6a3858c1de9816a4990edcd62e017197a0120606..fd2047ecfc53a54813837f6a3c7673f5a42aab47 100644 (file)
@@ -1,3 +1,12 @@
+2002-11-26  Hartmut Penner  <hpenner@de.ibm.com>
+
+       * config/s390/s390.md (literal_pool_64, literal_pool_31 ): New
+       insns.
+       * config/s390/s390.c (struct machine_function): Introduction of
+       struct machine_function.
+       * config/s390/s390-protos.h (s390_output_constant_pool): Changed 
+       prototype.
+       
 2002-11-26  Jakub Jelinek  <jakub@redhat.com>
 
        * varasm.c (output_constant_pool): For pool constants in mergeable
index 556402555aaba4409f4cfd8d06348bc820261478..deecef6b9695cebd84de3e49833467689faafe12 100644 (file)
@@ -70,7 +70,7 @@ extern rtx s390_return_addr_rtx PARAMS ((int, rtx));
 extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
 extern void print_operand_address PARAMS ((FILE *, rtx));
 extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void s390_output_constant_pool PARAMS ((FILE *));
+extern void s390_output_constant_pool PARAMS ((rtx, rtx));
 extern void s390_trampoline_template PARAMS ((FILE *));
 extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
 extern rtx s390_gen_rtx_const_DI PARAMS ((int, int));
index c2828a57aa7c4ab2f387c25029fb3a50c3a75ca8..3332d0f5746aaa5f034da5639d0f1711af37e493 100644 (file)
@@ -115,17 +115,22 @@ struct s390_address
   int pointer;
 };
 
-/* Structure containing information for prologue and epilogue.  */ 
+/* Define the structure for the machine field in struct function.  */
 
-struct s390_frame
+struct machine_function GTY(())
 {
-  int frame_pointer_p;
+  /* Label of start of initial literal pool.  */
+  rtx literal_pool_label;
+
+  /* Set, if some of the fprs 8-15 need to be saved (64 bit abi).  */
   int save_fprs_p;
+
+  /* Number of first and last gpr to be saved, restored.  */
   int first_save_gpr;
   int first_restore_gpr;
   int last_save_gpr;
-  int arg_frame_offset;
 
+  /* Size of stack frame.  */
   HOST_WIDE_INT frame_size;
 };
 
@@ -146,13 +151,13 @@ static void replace_base_register_ref PARAMS ((rtx *, rtx));
 static void s390_optimize_prolog PARAMS ((int));
 static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
 static int find_unused_clobbered_reg PARAMS ((void));
-static void s390_frame_info PARAMS ((struct s390_frame *));
+static void s390_frame_info PARAMS ((void));
 static rtx save_fpr PARAMS ((rtx, int, int));
 static rtx restore_fpr PARAMS ((rtx, int, int));
 static rtx save_gprs PARAMS ((rtx, int, int, int));
 static rtx restore_gprs PARAMS ((rtx, int, int, int));
 static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
-
+static struct machine_function * s390_init_machine_status PARAMS ((void));
  
 /* Return true if SET either doesn't set the CC register, or else
    the source and destination have matching CC modes and that 
@@ -827,8 +832,10 @@ override_options ()
 {
   /* Acquire a unique set number for our register saves and restores.  */
   s390_sr_alias_set = new_alias_set ();
-}
 
+  /* Set up function hooks.  */
+  init_machine_status = s390_init_machine_status;
+}
 
 /* Map for smallest class containing reg regno.  */
 
@@ -2580,10 +2587,12 @@ s390_output_symbolic_const (file, x)
         case 100:
         case 104:
          s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
-          fprintf (file, "-.LT%d", current_function_funcdef_no);
-         break;
+          fprintf (file, "-"); 
+         s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
+         break;
         case 105:
-          fprintf (file, ".LT%d-", current_function_funcdef_no);
+         s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
+          fprintf (file, "-");
          s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
          break;
        case 110:
@@ -2604,7 +2613,8 @@ s390_output_symbolic_const (file, x)
          break;
        case 114:
          s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
-          fprintf (file, "@PLT-.LT%d", current_function_funcdef_no);
+          fprintf (file, "@PLT-");
+         s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
          break;
        default:
          output_operand_lossage ("invalid UNSPEC as operand (2)");
@@ -4047,42 +4057,27 @@ int s390_nr_constants;
 /* Output main constant pool to stdio stream FILE.  */ 
 
 void
-s390_output_constant_pool (file)
-     FILE *file;
+s390_output_constant_pool (start_label, end_label)
+     rtx start_label;
+     rtx end_label;
 {
-  /* Output constant pool.  */
-  if (s390_nr_constants)
-    {
-      if (TARGET_64BIT)
-       {
-         fprintf (file, "\tlarl\t%s,.LT%d\n", reg_names[BASE_REGISTER],
-                  current_function_funcdef_no);
-         readonly_data_section ();
-         ASM_OUTPUT_ALIGN (file, 3);
-       }
-      else
-       {
-         fprintf (file, "\tbras\t%s,.LTN%d\n", reg_names[BASE_REGISTER],
-                  current_function_funcdef_no);
-       }
-      fprintf (file, ".LT%d:\n", current_function_funcdef_no);
-
-      s390_pool_count = 0;
-      output_constant_pool (current_function_name, current_function_decl);
-      s390_pool_count = -1;
+  if (TARGET_64BIT)
+    readonly_data_section ();
+  ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
 
-      if (TARGET_64BIT)
-       function_section (current_function_decl);
-      else
-        fprintf (file, ".LTN%d:\n", current_function_funcdef_no);
+  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (start_label));
+  s390_pool_count = 0;
+  output_constant_pool (current_function_name, current_function_decl);
+  s390_pool_count = -1;
+  if (TARGET_64BIT)
+    function_section (current_function_decl);
+  else
+    {
+      ASM_OUTPUT_ALIGN (asm_out_file, 1);
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (end_label));
     }
-
-  /* If no pool required, at least output the anchor label.  */
-  else if (!TARGET_64BIT && flag_pic)
-    fprintf (file, ".LT%d:\n", current_function_funcdef_no);
 }
 
-
 /* 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 
@@ -4097,13 +4092,10 @@ s390_optimize_prolog (temp_regno)
   int i, j;
   rtx insn, new_insn, next_insn;
 
-  struct s390_frame frame;
-  s390_frame_info (&frame);
-
   /* Recompute regs_ever_live data for special registers.  */
   regs_ever_live[BASE_REGISTER] = 0;
   regs_ever_live[RETURN_REGNUM] = 0;
-  regs_ever_live[STACK_POINTER_REGNUM] = frame.frame_size > 0;
+  regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
 
   /* If there is (possibly) any pool entry, we need to
      load the base register.  
@@ -4241,9 +4233,6 @@ s390_fixup_clobbered_return_reg (return_reg)
   bool replacement_done = 0;
   rtx insn;
 
-  struct s390_frame frame;
-  s390_frame_info (&frame);
-
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
       rtx reg, off, new_insn;
@@ -4256,12 +4245,12 @@ s390_fixup_clobbered_return_reg (return_reg)
          && store_multiple_operation (PATTERN (insn), VOIDmode))
        continue;
 
-      if (frame.frame_pointer_p)
+      if (frame_pointer_needed)
        reg = hard_frame_pointer_rtx;
       else
        reg = stack_pointer_rtx;
 
-      off = GEN_INT (frame.frame_size + REGNO (return_reg) * UNITS_PER_WORD);
+      off = GEN_INT (cfun->machine->frame_size + REGNO (return_reg) * UNITS_PER_WORD);
       if (INTVAL (off) >= 4096)
        {
          off = force_const_mem (Pmode, off);
@@ -4413,8 +4402,7 @@ find_unused_clobbered_reg ()
 /* Fill FRAME with info about frame of current function.  */
 
 static void
-s390_frame_info (frame)
-     struct s390_frame *frame;
+s390_frame_info ()
 {
   char gprs_ever_live[16];
   int i, j;
@@ -4424,28 +4412,24 @@ s390_frame_info (frame)
     fatal_error ("Total size of local variables exceeds architecture limit.");
 
   /* fprs 8 - 15 are caller saved for 64 Bit ABI.  */
-  frame->save_fprs_p = 0;
+  cfun->machine->save_fprs_p = 0;
   if (TARGET_64BIT)
     for (i = 24; i < 32; i++) 
       if (regs_ever_live[i])
        {
-          frame->save_fprs_p = 1;
+          cfun->machine->save_fprs_p = 1;
          break;
        }
 
-  frame->frame_size = fsize + frame->save_fprs_p * 64;
+  cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
 
   /* Does function need to setup frame and save area.  */
   
   if (! current_function_is_leaf
-      || frame->frame_size > 0
+      || cfun->machine->frame_size > 0
       || current_function_calls_alloca 
       || current_function_stdarg)
-    frame->frame_size += STARTING_FRAME_OFFSET;
-
-  /* Frame pointer needed.   */
-    
-  frame->frame_pointer_p = frame_pointer_needed;
+    cfun->machine->frame_size += STARTING_FRAME_OFFSET;
 
   /* Find first and last gpr to be saved.  Note that at this point,
      we assume the return register and the base register always
@@ -4459,7 +4443,7 @@ s390_frame_info (frame)
 
   gprs_ever_live[BASE_REGISTER] = 1;
   gprs_ever_live[RETURN_REGNUM] = 1;
-  gprs_ever_live[STACK_POINTER_REGNUM] = frame->frame_size > 0;
+  gprs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
   
   for (i = 6; i < 16; i++)
     if (gprs_ever_live[i])
@@ -4471,13 +4455,13 @@ s390_frame_info (frame)
 
 
   /* Save / Restore from gpr i to j.  */
-  frame->first_save_gpr = i;
-  frame->first_restore_gpr = i;
-  frame->last_save_gpr  = j;
+  cfun->machine->first_save_gpr = i;
+  cfun->machine->first_restore_gpr = i;
+  cfun->machine->last_save_gpr  = j;
 
   /* Varargs functions need to save gprs 2 to 6.  */
   if (current_function_stdarg)
-    frame->first_save_gpr = 2;
+    cfun->machine->first_save_gpr = 2;
 }
 
 /* Return offset between argument pointer and frame pointer 
@@ -4486,13 +4470,29 @@ s390_frame_info (frame)
 int 
 s390_arg_frame_offset ()
 {
-  struct s390_frame frame;
+  HOST_WIDE_INT fsize = get_frame_size ();
+  int save_fprs_p, i;
 
-  /* Compute frame_info.  */
+  /* fprs 8 - 15 are caller saved for 64 Bit ABI.  */
+  save_fprs_p = 0;
+  if (TARGET_64BIT)
+    for (i = 24; i < 32; i++) 
+      if (regs_ever_live[i])
+       {
+          save_fprs_p = 1;
+         break;
+       }
 
-  s390_frame_info (&frame);
+  fsize = fsize + save_fprs_p * 64;
 
-  return frame.frame_size + STACK_POINTER_OFFSET;
+  /* Does function need to setup frame and save area.  */
+  
+  if (! current_function_is_leaf
+      || fsize > 0
+      || current_function_calls_alloca 
+      || current_function_stdarg)
+    fsize += STARTING_FRAME_OFFSET;
+  return fsize + STACK_POINTER_OFFSET;
 }
 
 /* Emit insn to save fpr REGNUM at offset OFFSET relative
@@ -4646,14 +4646,14 @@ restore_gprs (base, offset, first, last)
 void
 s390_emit_prologue ()
 {
-  struct s390_frame frame;
   rtx insn, addr;
   rtx temp_reg;
+  rtx pool_start_label, pool_end_label;
   int i;
 
   /* Compute frame_info.  */
 
-  s390_frame_info (&frame);
+  s390_frame_info ();
 
   /* Choose best register to use for temp use within prologue.  */
   
@@ -4667,12 +4667,21 @@ s390_emit_prologue ()
   /* Save call saved gprs.  */
 
   insn = save_gprs (stack_pointer_rtx, 0, 
-                   frame.first_save_gpr, frame.last_save_gpr);
+                   cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
   emit_insn (insn);
 
-  /* Dump constant pool and set constant pool register (13).  */
-  insn = emit_insn (gen_lit ());
+  /* Dump constant pool and set constant pool register.  */
+
+  pool_start_label = gen_label_rtx();
+  pool_end_label = gen_label_rtx();
+  cfun->machine->literal_pool_label = pool_start_label;
+  
+  if (TARGET_64BIT)
+    insn = emit_insn (gen_literal_pool_64 (gen_rtx_REG (Pmode, BASE_REGISTER),
+                                          pool_start_label, pool_end_label));
+  else
+    insn = emit_insn (gen_literal_pool_31 (gen_rtx_REG (Pmode, BASE_REGISTER),
+                                            pool_start_label, pool_end_label));  
   
   /* Save fprs for variable args.  */
 
@@ -4711,21 +4720,21 @@ s390_emit_prologue ()
 
   /* Decrement stack pointer.  */
 
-  if (frame.frame_size > 0)
+  if (cfun->machine->frame_size > 0)
     {
-      rtx frame_off = GEN_INT (-frame.frame_size);
+      rtx frame_off = GEN_INT (-cfun->machine->frame_size);
 
       /* Save incoming stack pointer into temp reg.  */
       
-      if (TARGET_BACKCHAIN || frame.save_fprs_p)
+      if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
        {
          insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
        }
       
       /* Substract frame size from stack pointer.  */
 
-      frame_off = GEN_INT (-frame.frame_size);
-      if (!CONST_OK_FOR_LETTER_P (-frame.frame_size, 'K'))
+      frame_off = GEN_INT (-cfun->machine->frame_size);
+      if (!CONST_OK_FOR_LETTER_P (-cfun->machine->frame_size, 'K'))
        frame_off = force_const_mem (Pmode, frame_off);
 
       insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
@@ -4734,7 +4743,7 @@ s390_emit_prologue ()
        gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
                           gen_rtx_SET (VOIDmode, stack_pointer_rtx,
                                   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-                                  GEN_INT (-frame.frame_size))),
+                                  GEN_INT (-cfun->machine->frame_size))),
                           REG_NOTES (insn));
 
       /* Set backchain.  */
@@ -4749,7 +4758,7 @@ s390_emit_prologue ()
 
   /* Save fprs 8 - 15 (64 bit ABI).  */
   
-  if (frame.save_fprs_p)
+  if (cfun->machine->save_fprs_p)
     {
       insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
 
@@ -4757,7 +4766,7 @@ s390_emit_prologue ()
        if (regs_ever_live[i])
          {
            rtx addr = plus_constant (stack_pointer_rtx, 
-                                     frame.frame_size - 64 + (i-24)*8);
+                                     cfun->machine->frame_size - 64 + (i-24)*8);
 
            insn = save_fpr (temp_reg, (i-24)*8, i);
            RTX_FRAME_RELATED_P (insn) = 1;
@@ -4772,7 +4781,7 @@ s390_emit_prologue ()
            
   /* Set frame pointer, if needed.  */
   
-  if (frame.frame_pointer_p)
+  if (frame_pointer_needed)
     {
       insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
       RTX_FRAME_RELATED_P (insn) = 1;
@@ -4818,26 +4827,21 @@ s390_emit_prologue ()
 void
 s390_emit_epilogue ()
 {
-  struct s390_frame frame;
   rtx frame_pointer, return_reg;
   int area_bottom, area_top, offset = 0;
   rtvec p;
 
-  /* Compute frame_info.  */
-  s390_frame_info (&frame);
-
   /* Check whether to use frame or stack pointer for restore.  */
 
-  frame_pointer = frame.frame_pointer_p ? 
+  frame_pointer = frame_pointer_needed ? 
     hard_frame_pointer_rtx : stack_pointer_rtx;
 
   /* Compute which parts of the save area we need to access.  */
 
-  if (frame.first_restore_gpr != -1)
+  if (cfun->machine->first_restore_gpr != -1)
     {
-      area_bottom = frame.first_restore_gpr * UNITS_PER_WORD;
-      area_top = (frame.last_save_gpr + 1) * UNITS_PER_WORD;
+      area_bottom = cfun->machine->first_restore_gpr * UNITS_PER_WORD;
+      area_top = (cfun->machine->last_save_gpr + 1) * UNITS_PER_WORD;
     }
   else
     {
@@ -4847,7 +4851,7 @@ s390_emit_epilogue ()
 
   if (TARGET_64BIT)
     {
-      if (frame.save_fprs_p)
+      if (cfun->machine->save_fprs_p)
        {
          if (area_bottom > -64)
            area_bottom = -64;
@@ -4880,18 +4884,18 @@ s390_emit_epilogue ()
     {
       /* Nothing to restore.  */
     }
-  else if (frame.frame_size + area_bottom >= 0
-           && frame.frame_size + area_top <= 4096)
+  else if (cfun->machine->frame_size + area_bottom >= 0
+           && cfun->machine->frame_size + area_top <= 4096)
     {
       /* Area is in range.  */
-      offset = frame.frame_size;
+      offset = cfun->machine->frame_size;
     }
   else
     {
       rtx insn, frame_off;
 
       offset = area_bottom < 0 ? -area_bottom : 0; 
-      frame_off = GEN_INT (frame.frame_size - offset);
+      frame_off = GEN_INT (cfun->machine->frame_size - offset);
 
       if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
        frame_off = force_const_mem (Pmode, frame_off);
@@ -4905,7 +4909,7 @@ s390_emit_epilogue ()
     {
       int i;
 
-      if (frame.save_fprs_p)
+      if (cfun->machine->save_fprs_p)
        for (i = 24; i < 32; i++)
          if (regs_ever_live[i] && !global_regs[i])
            restore_fpr (frame_pointer, 
@@ -4925,7 +4929,7 @@ s390_emit_epilogue ()
 
   /* Restore call saved gprs.  */
 
-  if (frame.first_restore_gpr != -1)
+  if (cfun->machine->first_restore_gpr != -1)
     {
       rtx insn, addr;
       int i;
@@ -4933,8 +4937,8 @@ s390_emit_epilogue ()
       /* Check for global register and save them 
         to stack location from where they get restored.  */
 
-      for (i = frame.first_restore_gpr; 
-          i <= frame.last_save_gpr;
+      for (i = cfun->machine->first_restore_gpr; 
+          i <= cfun->machine->last_save_gpr;
           i++)
        {
          /* These registers are special and need to be 
@@ -4979,7 +4983,8 @@ s390_emit_epilogue ()
       emit_insn (gen_blockage());      
 
       insn = restore_gprs (frame_pointer, offset, 
-                          frame.first_restore_gpr, frame.last_save_gpr);
+                          cfun->machine->first_restore_gpr, 
+                          cfun->machine->last_save_gpr);
       emit_insn (insn);
     }
 
@@ -5811,3 +5816,12 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
     }
 }
 
+/* How to allocate a 'struct machine_function'.  */
+
+static struct machine_function *
+s390_init_machine_status ()
+{
+  return ggc_alloc_cleared (sizeof (struct machine_function));
+}
+
+#include "gt-s390.h"
index 4d68049ded980bde86e2313ff2c54da3a3f725a4..197aa67ebcb8d441dd3ab8c35d28c6780ed5830a 100644 (file)
    (set_attr "type"    "jsr")          
    (set_attr "atype"   "mem")])
 
-
-(define_insn "lit"
-  [(set (reg 13) (pc))
-   (unspec_volatile [(const_int 0)] 200)]
+(define_insn "literal_pool_31"
+  [(unspec_volatile [(const_int 0)] 300)
+   (set (match_operand:SI 0 "register_operand" "=a") 
+        (label_ref (match_operand 1 "" "")))   
+   (use (label_ref (match_operand 2 "" "")))]
   ""
   "*
 {
-   s390_output_constant_pool (asm_out_file);
-   return \"\";
+   if (s390_nr_constants) {
+     output_asm_insn (\"bras\\t%0,%2\", operands);
+     s390_output_constant_pool (operands[1], operands[2]);
+   }
+   return \"\";        
 }"
   [(set_attr "op_type" "NN")
-   (set_attr "length"  "6")
-   (set_attr "type"    "integer")])
+   (set_attr "type"    "la")])
 
+(define_insn "literal_pool_64"
+  [(unspec_volatile [(const_int 0)] 300)
+   (set (match_operand:DI 0 "register_operand" "=a") 
+        (label_ref (match_operand 1 "" "")))   
+   (use (label_ref (match_operand 2 "" "")))]
+  ""
+  "*
+{
+   if (s390_nr_constants) {
+     output_asm_insn (\"larl\\t%0,%1\", operands);
+     s390_output_constant_pool (operands[1], operands[2]);
+   }
+   return \"\";        
+}"
+  [(set_attr "op_type" "NN")
+   (set_attr "type"    "la")])