mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-30 11:05:09 +08:00
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:
parent
9eca082e50
commit
2d01e44576
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user