sh-protos.h (symbol_ref_operand): Declare.
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 25 Nov 2000 04:32:45 +0000 (04:32 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 25 Nov 2000 04:32:45 +0000 (04:32 +0000)
* config/sh/sh-protos.h (symbol_ref_operand): Declare.
* config/sh/sh.md (UNSPEC_CALLER): New constant.
(calli_pcrel, call_valuei_pcrel): Use PIC_REG.
(call_pcrel, call_value_pcrel): New insn_and_splits.
(call, call_value): Use them.
(call_site): New expand.
(sym_label2reg, symPLT_label2reg): Adjust to hold call_sites.
* config/sh/sh.h (OUTPUT_ADDR_CONST_EXTRA) [UNSPEC_CALLER]:
Output call_site label.
(PREDICATE_CODES): Added symbol_ref_operand.
* config/sh/sh.c (symbol_ref_operand): Define.
* emit-rtl.c (try_split): Propagate CALL_INSN_FUNCTION_USAGE
to CALL_INSNs in the split sequence.

From-SVN: r37730

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/emit-rtl.c

index b91468a64b202992ad6e830a959cf784a975a7cf..2365199cc0b1b14669fd5fa16030ffe9fd11ab5a 100644 (file)
@@ -1,3 +1,19 @@
+2000-11-25  Alexandre Oliva  <aoliva@redhat.com>, NIIBE Yutaka  <gniibe@m17n.org>
+
+       * config/sh/sh-protos.h (symbol_ref_operand): Declare.
+       * config/sh/sh.md (UNSPEC_CALLER): New constant.
+       (calli_pcrel, call_valuei_pcrel): Use PIC_REG.
+       (call_pcrel, call_value_pcrel): New insn_and_splits.
+       (call, call_value): Use them.
+       (call_site): New expand.
+       (sym_label2reg, symPLT_label2reg): Adjust to hold call_sites.
+       * config/sh/sh.h (OUTPUT_ADDR_CONST_EXTRA) [UNSPEC_CALLER]:
+       Output call_site label.
+       (PREDICATE_CODES): Added symbol_ref_operand.
+       * config/sh/sh.c (symbol_ref_operand): Define.
+       * emit-rtl.c (try_split): Propagate CALL_INSN_FUNCTION_USAGE
+       to CALL_INSNs in the split sequence.
+
 2000-11-24  Nick Clifton  <nickc@redhat.com>
 
        * config.gcc (v850-*-*): Define c_target_objs and
index 21872ac7f80f6b97f1fb476344526352ec21a655..79b66773f842cc191f224fb4aca5e7d8d3e94c5b 100644 (file)
@@ -77,6 +77,7 @@ extern int regs_used PARAMS ((rtx, int));
 extern void fixup_addr_diff_vecs PARAMS ((rtx));
 extern int get_dest_uid PARAMS ((rtx, int));
 extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
+extern int symbol_ref_operand PARAMS ((rtx, enum machine_mode));
 extern int system_reg_operand PARAMS ((rtx, enum machine_mode));
 extern int general_movsrc_operand PARAMS ((rtx, enum machine_mode));
 extern int general_movdst_operand PARAMS ((rtx, enum machine_mode));
index 87601c6d6af15bdb4b8ce50ae71596131cadf245..259e1480e46723bb59f1ea0bb9f26b4b2cf4cf96 100644 (file)
@@ -4821,6 +4821,14 @@ fpul_operand (op, mode)
          && GET_MODE (op) == mode);
 }
 
+int
+symbol_ref_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return (GET_CODE (op) == SYMBOL_REF);
+}
+
 int
 commutative_float_operator (op, mode)
      rtx op;
index 618f98cd265b4be69322998a0ae26130bc50372c..9c516fc9a3ea431ff8c7e653a06f1855ea6da08b 100644 (file)
@@ -2201,6 +2201,15 @@ do { char dstr[30];                                      \
            output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
            fputs ("@PLT", (STREAM));                                   \
            break;                                                      \
+         case UNSPEC_CALLER:                                           \
+           {                                                           \
+             char name[32];                                            \
+             /* LPCS stands for Label for PIC Call Site.  */           \
+             ASM_GENERATE_INTERNAL_LABEL                               \
+               (name, "LPCS", XINT (XVECEXP ((X), 0, 0), 0));          \
+             assemble_name ((STREAM), name);                           \
+           }                                                           \
+           break;                                                      \
          default:                                                      \
            goto FAIL;                                                  \
          }                                                             \
@@ -2297,7 +2306,8 @@ extern struct rtx_def *fpscr_rtx;
   {"general_movdst_operand", {SUBREG, REG, MEM}},                      \
   {"logical_operand", {SUBREG, REG, CONST_INT}},                       \
   {"noncommutative_float_operator", {MINUS, DIV}},                     \
-  {"register_operand", {SUBREG, REG}},
+  {"register_operand", {SUBREG, REG}},                                 \
+  {"symbol_ref_operand", {SYMBOL_REF}},
 
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases, 
index c3a93946ef0ef61a7051577b15f689ae6ced0b5f..2c0ba5d36fee4ba75214b92c7598594234c33afc 100644 (file)
   (UNSPEC_GOT          7)
   (UNSPEC_GOTOFF       8)
   (UNSPEC_PLT          9)
+  (UNSPEC_CALLER       10)
   (UNSPEC_ICACHE       12)
 
   ;; These are used with unspec_volatile.
   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
         (match_operand 1 "" ""))
    (use (reg:PSI FPSCR_REG))
+   (use (reg:SI PIC_REG))
    (use (match_operand 2 "" ""))
    (clobber (reg:SI PR_REG))]
   "TARGET_SH2"
                      (const_string "single") (const_string "double")))
    (set_attr "needs_delay_slot" "yes")])
 
+(define_insn_and_split "call_pcrel"
+  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
+        (match_operand 1 "" ""))
+   (use (reg:PSI FPSCR_REG))
+   (use (reg:SI PIC_REG))
+   (clobber (reg:SI PR_REG))
+   (clobber (match_scratch:SI 2 "=r"))]
+  "TARGET_SH2 && optimize"
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx lab = gen_call_site ();
+
+  if (SYMBOL_REF_FLAG (operands[0]))
+    emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
+  else
+    emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
+  emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
+  DONE;
+}"
+  [(set_attr "type" "call")
+   (set (attr "fp_mode")
+       (if_then_else (eq_attr "fpu_single" "yes")
+                     (const_string "single") (const_string "double")))
+   (set_attr "needs_delay_slot" "yes")])
+
 (define_insn "call_valuei"
   [(set (match_operand 0 "" "=rf")
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
        (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
              (match_operand 2 "" "")))
    (use (reg:PSI FPSCR_REG))
+   (use (reg:SI PIC_REG))
    (use (match_operand 3 "" ""))
    (clobber (reg:SI PR_REG))]
   "TARGET_SH2"
                      (const_string "single") (const_string "double")))
    (set_attr "needs_delay_slot" "yes")])
 
+(define_insn_and_split "call_value_pcrel"
+  [(set (match_operand 0 "" "=rf")
+       (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
+             (match_operand 2 "" "")))
+   (use (reg:PSI FPSCR_REG))
+   (use (reg:SI PIC_REG))
+   (clobber (reg:SI PR_REG))
+   (clobber (match_scratch:SI 3 "=r"))]
+  "TARGET_SH2 && optimize"
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  "
+{
+  rtx lab = gen_call_site ();
+
+  if (SYMBOL_REF_FLAG (operands[1]))
+    emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
+  else
+    emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
+  emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
+                                        operands[2], lab));
+  DONE;
+}"
+  [(set_attr "type" "call")
+   (set (attr "fp_mode")
+       (if_then_else (eq_attr "fpu_single" "yes")
+                     (const_string "single") (const_string "double")))
+   (set_attr "needs_delay_slot" "yes")])
+
 (define_expand "call"
   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
                            (match_operand 1 "" ""))
   ""
   "
 {
-  if (flag_pic && TARGET_SH2 && ! flag_unroll_loops
+  if (flag_pic && TARGET_SH2 && optimize
       && GET_CODE (operands[0]) == MEM
       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
     {
-      rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx ();
-
-      if (SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
-       emit_insn (gen_sym_label2reg (reg, XEXP (operands[0], 0), lab));
-      else
-       emit_insn (gen_symPLT_label2reg (reg, XEXP (operands[0], 0), lab));
-      operands[0] = reg;
-      emit_call_insn (gen_calli_pcrel (operands[0], operands[1], lab));
+      emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
+      current_function_uses_pic_offset_table = 1;
       DONE;
     }
   else
   ""
   "
 {
-  if (flag_pic && TARGET_SH2 && ! flag_unroll_loops
+  if (flag_pic && TARGET_SH2 && optimize
       && GET_CODE (operands[1]) == MEM
       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
     {
-      rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx ();
-
-      if (SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
-       emit_insn (gen_sym_label2reg (reg, XEXP (operands[1], 0), lab));
-      else
-       emit_insn (gen_symPLT_label2reg (reg, XEXP (operands[1], 0), lab));
-      operands[1] = reg;
-      emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[1],
-                                            operands[2], lab));
+      emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
+                                           operands[2]));
+      current_function_uses_pic_offset_table = 1;
       DONE;
     }
   else
 }
 ")
 
+(define_expand "call_site"
+  [(unspec [(match_dup 0)] UNSPEC_CALLER)]
+  ""
+  "
+{
+  static HOST_WIDE_INT i = 0;
+  operands[0] = GEN_INT (i);
+  i++;
+}")
+
 (define_expand "sym_label2reg"
   [(set (match_operand:SI 0 "" "")
        (const (minus:SI
                (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC))
                (const (plus:SI
-                       (unspec [(label_ref (match_operand:SI 2 "" ""))]
-                               UNSPEC_PIC)
+                       (match_operand:SI 2 "" "")
                        (const_int 2))))))]
   "" "")
 
                        (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT)
                        (pc)))
                (const (plus:SI
-                       (unspec [(label_ref (match_operand:SI 2 "" ""))]
-                               UNSPEC_PIC)
+                       (match_operand:SI 2 "" "")
                        (const_int 2))))))
    (use (match_dup 3))]
   ;; Even though the PIC register is not really used by the call
index 4329346260a3083b17d807196d876155a15efff7..f658ec2cb9ace5b1fa8e5dae047f9407e8767693 100644 (file)
@@ -2438,6 +2438,14 @@ try_split (pat, trial, last)
                    LABEL_NUSES (JUMP_LABEL (trial))++;
                }
 
+         /* If we are splitting a CALL_INSN, look for the CALL_INSN
+            in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it.  */
+         if (GET_CODE (trial) == CALL_INSN)
+           for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)
+             if (GET_CODE (XVECEXP (seq, 0, i)) == CALL_INSN)
+               CALL_INSN_FUNCTION_USAGE (XVECEXP (seq, 0, i))
+                 = CALL_INSN_FUNCTION_USAGE (trial);
+
          tem = emit_insn_after (seq, before);
 
          delete_insn (trial);