aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2000-11-25 04:32:45 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2000-11-25 04:32:45 +0000
commit2d01e4457601734bdd414a89d74d87f79cc49d7a (patch)
tree8e72d36c1c46338b2d043c44058356ff002181e6
parent9eca082e508996b79dd3788d6223cded6055841b (diff)
downloadgcc-2d01e4457601734bdd414a89d74d87f79cc49d7a.zip
gcc-2d01e4457601734bdd414a89d74d87f79cc49d7a.tar.gz
gcc-2d01e4457601734bdd414a89d74d87f79cc49d7a.tar.bz2
sh-protos.h (symbol_ref_operand): Declare.
* 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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c8
-rw-r--r--gcc/config/sh/sh.h12
-rw-r--r--gcc/config/sh/sh.md103
-rw-r--r--gcc/emit-rtl.c8
6 files changed, 124 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b91468a..2365199 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 21872ac..79b6677 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -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));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 87601c6..259e148 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -4822,6 +4822,14 @@ fpul_operand (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;
enum machine_mode mode;
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 618f98c..9c516fc 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -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,
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index c3a9394..2c0ba5d 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -108,6 +108,7 @@
(UNSPEC_GOT 7)
(UNSPEC_GOTOFF 8)
(UNSPEC_PLT 9)
+ (UNSPEC_CALLER 10)
(UNSPEC_ICACHE 12)
;; These are used with unspec_volatile.
@@ -3389,6 +3390,7 @@
[(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"
@@ -3399,6 +3401,34 @@
(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"))
@@ -3418,6 +3448,7 @@
(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"
@@ -3428,6 +3459,36 @@
(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 "" ""))
@@ -3436,18 +3497,12 @@
""
"
{
- 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
@@ -3463,19 +3518,13 @@
""
"
{
- 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
@@ -3597,13 +3646,22 @@
}
")
+(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))))))]
"" "")
@@ -3637,8 +3695,7 @@
(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
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4329346..f658ec2 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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);