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
This commit is contained in:
Alexandre Oliva 2000-11-25 04:32:45 +00:00 committed by Alexandre Oliva
parent 9eca082e50
commit 2d01e44576
6 changed files with 124 additions and 24 deletions

View 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

View 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));

View 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;

View 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,

View File

@ -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

View 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);