Commit 2d01e445 by Alexandre Oliva Committed by Alexandre Oliva

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
parent 9eca082e
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> 2000-11-24 Nick Clifton <nickc@redhat.com>
* config.gcc (v850-*-*): Define c_target_objs and * config.gcc (v850-*-*): Define c_target_objs and
......
...@@ -77,6 +77,7 @@ extern int regs_used PARAMS ((rtx, int)); ...@@ -77,6 +77,7 @@ extern int regs_used PARAMS ((rtx, int));
extern void fixup_addr_diff_vecs PARAMS ((rtx)); extern void fixup_addr_diff_vecs PARAMS ((rtx));
extern int get_dest_uid PARAMS ((rtx, int)); extern int get_dest_uid PARAMS ((rtx, int));
extern void final_prescan_insn PARAMS ((rtx, 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 system_reg_operand PARAMS ((rtx, enum machine_mode));
extern int general_movsrc_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)); extern int general_movdst_operand PARAMS ((rtx, enum machine_mode));
......
...@@ -4822,6 +4822,14 @@ fpul_operand (op, mode) ...@@ -4822,6 +4822,14 @@ fpul_operand (op, mode)
} }
int 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) commutative_float_operator (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
......
...@@ -2201,6 +2201,15 @@ do { char dstr[30]; \ ...@@ -2201,6 +2201,15 @@ do { char dstr[30]; \
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
fputs ("@PLT", (STREAM)); \ fputs ("@PLT", (STREAM)); \
break; \ 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: \ default: \
goto FAIL; \ goto FAIL; \
} \ } \
...@@ -2297,7 +2306,8 @@ extern struct rtx_def *fpscr_rtx; ...@@ -2297,7 +2306,8 @@ extern struct rtx_def *fpscr_rtx;
{"general_movdst_operand", {SUBREG, REG, MEM}}, \ {"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \ {"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \ {"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 /* 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, in a wider mode than that declared by the program. In such cases,
......
...@@ -108,6 +108,7 @@ ...@@ -108,6 +108,7 @@
(UNSPEC_GOT 7) (UNSPEC_GOT 7)
(UNSPEC_GOTOFF 8) (UNSPEC_GOTOFF 8)
(UNSPEC_PLT 9) (UNSPEC_PLT 9)
(UNSPEC_CALLER 10)
(UNSPEC_ICACHE 12) (UNSPEC_ICACHE 12)
;; These are used with unspec_volatile. ;; These are used with unspec_volatile.
...@@ -3389,6 +3390,7 @@ ...@@ -3389,6 +3390,7 @@
[(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(use (reg:PSI FPSCR_REG)) (use (reg:PSI FPSCR_REG))
(use (reg:SI PIC_REG))
(use (match_operand 2 "" "")) (use (match_operand 2 "" ""))
(clobber (reg:SI PR_REG))] (clobber (reg:SI PR_REG))]
"TARGET_SH2" "TARGET_SH2"
...@@ -3399,6 +3401,34 @@ ...@@ -3399,6 +3401,34 @@
(const_string "single") (const_string "double"))) (const_string "single") (const_string "double")))
(set_attr "needs_delay_slot" "yes")]) (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" (define_insn "call_valuei"
[(set (match_operand 0 "" "=rf") [(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"))
...@@ -3418,6 +3448,7 @@ ...@@ -3418,6 +3448,7 @@
(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 "" ""))) (match_operand 2 "" "")))
(use (reg:PSI FPSCR_REG)) (use (reg:PSI FPSCR_REG))
(use (reg:SI PIC_REG))
(use (match_operand 3 "" "")) (use (match_operand 3 "" ""))
(clobber (reg:SI PR_REG))] (clobber (reg:SI PR_REG))]
"TARGET_SH2" "TARGET_SH2"
...@@ -3428,6 +3459,36 @@ ...@@ -3428,6 +3459,36 @@
(const_string "single") (const_string "double"))) (const_string "single") (const_string "double")))
(set_attr "needs_delay_slot" "yes")]) (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" (define_expand "call"
[(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
(match_operand 1 "" "")) (match_operand 1 "" ""))
...@@ -3436,18 +3497,12 @@ ...@@ -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 (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{ {
rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx (); emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
current_function_uses_pic_offset_table = 1;
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));
DONE; DONE;
} }
else else
...@@ -3463,19 +3518,13 @@ ...@@ -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 (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{ {
rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx (); emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
operands[2]));
if (SYMBOL_REF_FLAG (XEXP (operands[1], 0))) current_function_uses_pic_offset_table = 1;
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));
DONE; DONE;
} }
else else
...@@ -3597,13 +3646,22 @@ ...@@ -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" (define_expand "sym_label2reg"
[(set (match_operand:SI 0 "" "") [(set (match_operand:SI 0 "" "")
(const (minus:SI (const (minus:SI
(const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC)) (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_PIC))
(const (plus:SI (const (plus:SI
(unspec [(label_ref (match_operand:SI 2 "" ""))] (match_operand:SI 2 "" "")
UNSPEC_PIC)
(const_int 2))))))] (const_int 2))))))]
"" "") "" "")
...@@ -3637,8 +3695,7 @@ ...@@ -3637,8 +3695,7 @@
(unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT) (unspec [(match_operand:SI 1 "" "")] UNSPEC_PLT)
(pc))) (pc)))
(const (plus:SI (const (plus:SI
(unspec [(label_ref (match_operand:SI 2 "" ""))] (match_operand:SI 2 "" "")
UNSPEC_PIC)
(const_int 2)))))) (const_int 2))))))
(use (match_dup 3))] (use (match_dup 3))]
;; Even though the PIC register is not really used by the call ;; Even though the PIC register is not really used by the call
......
...@@ -2438,6 +2438,14 @@ try_split (pat, trial, last) ...@@ -2438,6 +2438,14 @@ try_split (pat, trial, last)
LABEL_NUSES (JUMP_LABEL (trial))++; 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); tem = emit_insn_after (seq, before);
delete_insn (trial); delete_insn (trial);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment