0002-pr66609.diff 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. --- a/gcc/config/sh/sh-protos.h
  2. +++ a/gcc/config/sh/sh-protos.h
  3. @@ -159,6 +159,7 @@ extern int sh_eval_treg_value (rtx op);
  4. extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
  5. extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
  6. extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
  7. +extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool);
  8. /* Result value of sh_find_set_of_reg. */
  9. struct set_of_reg
  10. --- a/gcc/config/sh/sh.c
  11. +++ a/gcc/config/sh/sh.c
  12. @@ -1604,6 +1604,10 @@ sh_asm_output_addr_const_extra (FILE *file, rtx x)
  13. output_addr_const (file, XVECEXP (x, 0, 0));
  14. fputs ("@GOTPLT", file);
  15. break;
  16. + case UNSPEC_PCREL:
  17. + output_addr_const (file, XVECEXP (x, 0, 0));
  18. + fputs ("@PCREL", file);
  19. + break;
  20. case UNSPEC_DTPOFF:
  21. output_addr_const (file, XVECEXP (x, 0, 0));
  22. fputs ("@DTPOFF", file);
  23. @@ -10441,6 +10445,7 @@ nonpic_symbol_mentioned_p (rtx x)
  24. || XINT (x, 1) == UNSPEC_DTPOFF
  25. || XINT (x, 1) == UNSPEC_TPOFF
  26. || XINT (x, 1) == UNSPEC_PLT
  27. + || XINT (x, 1) == UNSPEC_PCREL
  28. || XINT (x, 1) == UNSPEC_SYMOFF
  29. || XINT (x, 1) == UNSPEC_PCREL_SYMOFF))
  30. return false;
  31. @@ -10714,7 +10719,8 @@ sh_delegitimize_address (rtx orig_x)
  32. rtx symplt = XEXP (XVECEXP (y, 0, 0), 0);
  33. if (GET_CODE (symplt) == UNSPEC
  34. - && XINT (symplt, 1) == UNSPEC_PLT)
  35. + && (XINT (symplt, 1) == UNSPEC_PLT
  36. + || XINT (symplt, 1) == UNSPEC_PCREL))
  37. return XVECEXP (symplt, 0, 0);
  38. }
  39. }
  40. @@ -11702,9 +11708,24 @@ sh_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
  41. || crtl->args.info.stack_regs == 0)
  42. && ! sh_cfun_interrupt_handler_p ()
  43. && (! flag_pic
  44. - || (decl && ! TREE_PUBLIC (decl))
  45. + || (decl && ! (TREE_PUBLIC (decl) || DECL_WEAK (decl)))
  46. || (decl && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)));
  47. }
  48. +
  49. +/* Expand to appropriate sym*_label2reg for SYM and SIBCALL_P. */
  50. +void
  51. +sh_expand_sym_label2reg (rtx reg, rtx sym, rtx lab, bool sibcall_p)
  52. +{
  53. + const_tree decl = SYMBOL_REF_DECL (sym);
  54. + bool is_weak = (decl && DECL_P (decl) && DECL_WEAK (decl));
  55. +
  56. + if (!is_weak && SYMBOL_REF_LOCAL_P (sym))
  57. + emit_insn (gen_sym_label2reg (reg, sym, lab));
  58. + else if (sibcall_p)
  59. + emit_insn (gen_symPCREL_label2reg (reg, sym, lab));
  60. + else
  61. + emit_insn (gen_symPLT_label2reg (reg, sym, lab));
  62. +}
  63. /* Machine specific built-in functions. */
  64. --- a/gcc/config/sh/sh.md
  65. +++ a/gcc/config/sh/sh.md
  66. @@ -135,6 +135,7 @@
  67. UNSPEC_PLT
  68. UNSPEC_CALLER
  69. UNSPEC_GOTPLT
  70. + UNSPEC_PCREL
  71. UNSPEC_ICACHE
  72. UNSPEC_INIT_TRAMP
  73. UNSPEC_FCOSA
  74. @@ -9470,11 +9471,8 @@ label:
  75. [(const_int 0)]
  76. {
  77. rtx lab = PATTERN (gen_call_site ());
  78. -
  79. - if (SYMBOL_REF_LOCAL_P (operands[0]))
  80. - emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
  81. - else
  82. - emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
  83. +
  84. + sh_expand_sym_label2reg (operands[2], operands[0], lab, false);
  85. emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
  86. DONE;
  87. }
  88. @@ -9605,10 +9603,7 @@ label:
  89. {
  90. rtx lab = PATTERN (gen_call_site ());
  91. - if (SYMBOL_REF_LOCAL_P (operands[1]))
  92. - emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
  93. - else
  94. - emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
  95. + sh_expand_sym_label2reg (operands[3], operands[1], lab, false);
  96. emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
  97. operands[2], copy_rtx (lab)));
  98. DONE;
  99. @@ -10008,7 +10003,7 @@ label:
  100. rtx lab = PATTERN (gen_call_site ());
  101. rtx call_insn;
  102. - emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
  103. + sh_expand_sym_label2reg (operands[2], operands[0], lab, true);
  104. call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
  105. copy_rtx (lab)));
  106. SIBLING_CALL_P (call_insn) = 1;
  107. @@ -10200,7 +10195,7 @@ label:
  108. rtx lab = PATTERN (gen_call_site ());
  109. rtx call_insn;
  110. - emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
  111. + sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
  112. call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
  113. operands[3],
  114. operands[2],
  115. @@ -10748,6 +10743,16 @@ label:
  116. UNSPEC_SYMOFF)))]
  117. "TARGET_SH1" "")
  118. +(define_expand "symPCREL_label2reg"
  119. + [(set (match_operand:SI 0 "" "")
  120. + (const:SI
  121. + (unspec:SI
  122. + [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PCREL))
  123. + (const:SI (plus:SI (match_operand:SI 2 "" "")
  124. + (const_int 2)))] UNSPEC_PCREL_SYMOFF)))]
  125. + "TARGET_SH1"
  126. + "")
  127. +
  128. (define_expand "symGOT_load"
  129. [(set (match_dup 2) (match_operand 1 "" ""))
  130. (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))