From fbce972ab3af46170e4689d3e0ea14fe72975913 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Mon, 24 Aug 2015 23:23:00 +0000 Subject: [PATCH] re PR target/66609 ([sh] Relative address expressions bind at as-time, even if symbol is weak) PR target/66609 * [SH] Take into account weak symbols for pc relative calls/sibcalls. From-SVN: r227155 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/config/sh/sh-protos.h | 1 + gcc/config/sh/sh.c | 25 +++++++++++++++++++++++-- gcc/config/sh/sh.md | 27 ++++++++++++++++----------- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 84679e6499f..2415b30354b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2015-08-24 Kaz Kojima + + PR target/66609 + * config/sh/sh.c (sh_asm_output_addr_const_extra): Handle + UNSPEC_PCREL. + (nonpic_symbol_mentioned_p): Likewise. + (sh_delegitimize_address): Likewise. + (sh_function_ok_for_sibcall): Take into account weak symbols. + (sh_expand_sym_label2reg): New. + * config/sh/sh-protos.h (sh_expand_sym_label2reg): Declare. + * config/sh/sh.md (UNSPEC_PCREL): New enum. + (call_pcrel): Use sh_expand_sym_label2reg. + (call_value_pcrel, sibcall_pcrel, sibcall_value_pcrel): Likewise. + (symPCREL_label2reg) New expand. + 2015-08-24 Aditya Kumar * graphite-poly.c: Change type of region from void* to sese. diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 5a552e2be81..3e4211be4de 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -159,6 +159,7 @@ extern int sh_eval_treg_value (rtx op); extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op); extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a); extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx); +extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool); /* Result value of sh_find_set_of_reg. */ struct set_of_reg diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 450d634e246..1442b7fc790 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -1604,6 +1604,10 @@ sh_asm_output_addr_const_extra (FILE *file, rtx x) output_addr_const (file, XVECEXP (x, 0, 0)); fputs ("@GOTPLT", file); break; + case UNSPEC_PCREL: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@PCREL", file); + break; case UNSPEC_DTPOFF: output_addr_const (file, XVECEXP (x, 0, 0)); fputs ("@DTPOFF", file); @@ -10441,6 +10445,7 @@ nonpic_symbol_mentioned_p (rtx x) || XINT (x, 1) == UNSPEC_DTPOFF || XINT (x, 1) == UNSPEC_TPOFF || XINT (x, 1) == UNSPEC_PLT + || XINT (x, 1) == UNSPEC_PCREL || XINT (x, 1) == UNSPEC_SYMOFF || XINT (x, 1) == UNSPEC_PCREL_SYMOFF)) return false; @@ -10714,7 +10719,8 @@ sh_delegitimize_address (rtx orig_x) rtx symplt = XEXP (XVECEXP (y, 0, 0), 0); if (GET_CODE (symplt) == UNSPEC - && XINT (symplt, 1) == UNSPEC_PLT) + && (XINT (symplt, 1) == UNSPEC_PLT + || XINT (symplt, 1) == UNSPEC_PCREL)) return XVECEXP (symplt, 0, 0); } } @@ -11702,9 +11708,24 @@ sh_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) || crtl->args.info.stack_regs == 0) && ! sh_cfun_interrupt_handler_p () && (! flag_pic - || (decl && ! TREE_PUBLIC (decl)) + || (decl && ! (TREE_PUBLIC (decl) || DECL_WEAK (decl))) || (decl && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT))); } + +/* Expand to appropriate sym*_label2reg for SYM and SIBCALL_P. */ +void +sh_expand_sym_label2reg (rtx reg, rtx sym, rtx lab, bool sibcall_p) +{ + const_tree decl = SYMBOL_REF_DECL (sym); + bool is_weak = (decl && DECL_P (decl) && DECL_WEAK (decl)); + + if (!is_weak && SYMBOL_REF_LOCAL_P (sym)) + emit_insn (gen_sym_label2reg (reg, sym, lab)); + else if (sibcall_p) + emit_insn (gen_symPCREL_label2reg (reg, sym, lab)); + else + emit_insn (gen_symPLT_label2reg (reg, sym, lab)); +} /* Machine specific built-in functions. */ diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index facce836def..4e7cd169f84 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -135,6 +135,7 @@ UNSPEC_PLT UNSPEC_CALLER UNSPEC_GOTPLT + UNSPEC_PCREL UNSPEC_ICACHE UNSPEC_INIT_TRAMP UNSPEC_FCOSA @@ -9470,11 +9471,8 @@ label: [(const_int 0)] { rtx lab = PATTERN (gen_call_site ()); - - if (SYMBOL_REF_LOCAL_P (operands[0])) - emit_insn (gen_sym_label2reg (operands[2], operands[0], lab)); - else - emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab)); + + sh_expand_sym_label2reg (operands[2], operands[0], lab, false); emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab))); DONE; } @@ -9605,10 +9603,7 @@ label: { rtx lab = PATTERN (gen_call_site ()); - if (SYMBOL_REF_LOCAL_P (operands[1])) - emit_insn (gen_sym_label2reg (operands[3], operands[1], lab)); - else - emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab)); + sh_expand_sym_label2reg (operands[3], operands[1], lab, false); emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3], operands[2], copy_rtx (lab))); DONE; @@ -10008,7 +10003,7 @@ label: rtx lab = PATTERN (gen_call_site ()); rtx call_insn; - emit_insn (gen_sym_label2reg (operands[2], operands[0], lab)); + sh_expand_sym_label2reg (operands[2], operands[0], lab, true); call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1], copy_rtx (lab))); SIBLING_CALL_P (call_insn) = 1; @@ -10200,7 +10195,7 @@ label: rtx lab = PATTERN (gen_call_site ()); rtx call_insn; - emit_insn (gen_sym_label2reg (operands[3], operands[1], lab)); + sh_expand_sym_label2reg (operands[3], operands[1], lab, true); call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0], operands[3], operands[2], @@ -10748,6 +10743,16 @@ label: UNSPEC_SYMOFF)))] "TARGET_SH1" "") +(define_expand "symPCREL_label2reg" + [(set (match_operand:SI 0 "" "") + (const:SI + (unspec:SI + [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PCREL)) + (const:SI (plus:SI (match_operand:SI 2 "" "") + (const_int 2)))] UNSPEC_PCREL_SYMOFF)))] + "TARGET_SH1" + "") + (define_expand "symGOT_load" [(set (match_dup 2) (match_operand 1 "" "")) (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG))) -- 2.30.2