Tested on SPARC/Solaris and SPARC64/Linux, applied on the mainline.
2021-04-29 Eric Botcazou <ebotca...@adacore.com> * config/sparc/sparc.c (gen_load_pcrel_sym): Delete. (load_got_register): Do the PIC dance here. (sparc_legitimize_tls_address): Simplify. (sparc_emit_probe_stack_range): Likewise. (sparc32_initialize_trampoline): Likewise. (sparc64_initialize_trampoline): Likewise. * config/sparc/sparc.md (load_pcrel_sym<P:mode>): Add @ marker. (probe_stack_range<P:mode>): Likewise. (flush<P:mode>): Likewise. (tgd_hi22<P:mode>): Likewise. (tgd_lo10<P:mode>): Likewise. (tgd_add<P:mode>): Likewise. (tgd_call<P:mode>): Likewise. (tldm_hi22<P:mode>): Likewise. (tldm_lo10<P:mode>): Likewise. (tldm_add<P:mode>): Likewise. (tldm_call<P:mode>): Likewise. (tldo_hix22<P:mode>): Likewise. (tldo_lox10<P:mode>): Likewise. (tldo_add<P:mode>): Likewise. (tie_hi22<P:mode>): Likewise. (tie_lo10<P:mode>): Likewise. (tie_add<P:mode>): Likewise. (tle_hix22<P:mode>): Likewise. (tle_lox10<P:mode>): Likewise. (stack_protect_setsi): Rename to... (stack_protect_set32): ...this. (stack_protect_setdi): Rename to... (stack_protect_set64): ...this. (stack_protect_set): Adjust calls to above. (stack_protect_testsi): Rename to... (stack_protect_test32): ...this. (stack_protect_testdi): Rename to... (stack_protect_test64): ...this. (stack_protect_test): Adjust calls to above. -- Eric Botcazou
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 42ba415255c..3b4d41630f3 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4213,26 +4213,7 @@ sparc_got (void) return got_symbol_rtx; } -/* Wrapper around the load_pcrel_sym{si,di} patterns. */ - -static rtx -gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2) -{ - int orig_flag_pic = flag_pic; - rtx insn; - - /* The load_pcrel_sym{si,di} patterns require absolute addressing. */ - flag_pic = 0; - if (TARGET_ARCH64) - insn = gen_load_pcrel_symdi (op0, op1, op2, GEN_INT (REGNO (op0))); - else - insn = gen_load_pcrel_symsi (op0, op1, op2, GEN_INT (REGNO (op0))); - flag_pic = orig_flag_pic; - - return insn; -} - -/* Output the load_pcrel_sym{si,di} patterns. */ +/* Output the load_pcrel_sym pattern. */ const char * output_load_pcrel_sym (rtx *operands) @@ -4299,8 +4280,15 @@ load_got_register (void) got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); } - insn - = gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx); + /* The load_pcrel_sym{si,di} patterns require absolute addressing. */ + const int orig_flag_pic = flag_pic; + flag_pic = 0; + insn = gen_load_pcrel_sym (Pmode, + got_register_rtx, + sparc_got (), + got_helper_rtx, + GEN_INT (GLOBAL_OFFSET_TABLE_REGNUM)); + flag_pic = orig_flag_pic; } emit_insn (insn); @@ -4680,22 +4668,11 @@ sparc_legitimize_tls_address (rtx addr) ret = gen_reg_rtx (Pmode); o0 = gen_rtx_REG (Pmode, 8); got = sparc_tls_got (); - if (TARGET_ARCH32) - { - emit_insn (gen_tgd_hi22si (temp1, addr)); - emit_insn (gen_tgd_lo10si (temp2, temp1, addr)); - emit_insn (gen_tgd_addsi (o0, got, temp2, addr)); - insn = emit_call_insn (gen_tgd_callsi (o0, sparc_tls_get_addr (), - addr, const1_rtx)); - } - else - { - emit_insn (gen_tgd_hi22di (temp1, addr)); - emit_insn (gen_tgd_lo10di (temp2, temp1, addr)); - emit_insn (gen_tgd_adddi (o0, got, temp2, addr)); - insn = emit_call_insn (gen_tgd_calldi (o0, sparc_tls_get_addr (), - addr, const1_rtx)); - } + emit_insn (gen_tgd_hi22 (Pmode, temp1, addr)); + emit_insn (gen_tgd_lo10 (Pmode, temp2, temp1, addr)); + emit_insn (gen_tgd_add (Pmode, o0, got, temp2, addr)); + insn = emit_call_insn (gen_tgd_call (Pmode, o0, sparc_tls_get_addr (), + addr, const1_rtx)); use_reg (&CALL_INSN_FUNCTION_USAGE (insn), o0); RTL_CONST_CALL_P (insn) = 1; insn = get_insns (); @@ -4711,22 +4688,11 @@ sparc_legitimize_tls_address (rtx addr) ret = gen_reg_rtx (Pmode); o0 = gen_rtx_REG (Pmode, 8); got = sparc_tls_got (); - if (TARGET_ARCH32) - { - emit_insn (gen_tldm_hi22si (temp1)); - emit_insn (gen_tldm_lo10si (temp2, temp1)); - emit_insn (gen_tldm_addsi (o0, got, temp2)); - insn = emit_call_insn (gen_tldm_callsi (o0, sparc_tls_get_addr (), - const1_rtx)); - } - else - { - emit_insn (gen_tldm_hi22di (temp1)); - emit_insn (gen_tldm_lo10di (temp2, temp1)); - emit_insn (gen_tldm_adddi (o0, got, temp2)); - insn = emit_call_insn (gen_tldm_calldi (o0, sparc_tls_get_addr (), - const1_rtx)); - } + emit_insn (gen_tldm_hi22 (Pmode, temp1)); + emit_insn (gen_tldm_lo10 (Pmode, temp2, temp1)); + emit_insn (gen_tldm_add (Pmode, o0, got, temp2)); + insn = emit_call_insn (gen_tldm_call (Pmode, o0, sparc_tls_get_addr (), + const1_rtx)); use_reg (&CALL_INSN_FUNCTION_USAGE (insn), o0); RTL_CONST_CALL_P (insn) = 1; insn = get_insns (); @@ -4738,18 +4704,9 @@ sparc_legitimize_tls_address (rtx addr) UNSPEC_TLSLD_BASE)); temp1 = gen_reg_rtx (Pmode); temp2 = gen_reg_rtx (Pmode); - if (TARGET_ARCH32) - { - emit_insn (gen_tldo_hix22si (temp1, addr)); - emit_insn (gen_tldo_lox10si (temp2, temp1, addr)); - emit_insn (gen_tldo_addsi (ret, temp3, temp2, addr)); - } - else - { - emit_insn (gen_tldo_hix22di (temp1, addr)); - emit_insn (gen_tldo_lox10di (temp2, temp1, addr)); - emit_insn (gen_tldo_adddi (ret, temp3, temp2, addr)); - } + emit_insn (gen_tldo_hix22 (Pmode, temp1, addr)); + emit_insn (gen_tldo_lox10 (Pmode, temp2, temp1, addr)); + emit_insn (gen_tldo_add (Pmode, ret, temp3, temp2, addr)); break; case TLS_MODEL_INITIAL_EXEC: @@ -4757,27 +4714,17 @@ sparc_legitimize_tls_address (rtx addr) temp2 = gen_reg_rtx (Pmode); temp3 = gen_reg_rtx (Pmode); got = sparc_tls_got (); + emit_insn (gen_tie_hi22 (Pmode, temp1, addr)); + emit_insn (gen_tie_lo10 (Pmode, temp2, temp1, addr)); if (TARGET_ARCH32) - { - emit_insn (gen_tie_hi22si (temp1, addr)); - emit_insn (gen_tie_lo10si (temp2, temp1, addr)); - emit_insn (gen_tie_ld32 (temp3, got, temp2, addr)); - } + emit_insn (gen_tie_ld32 (temp3, got, temp2, addr)); else - { - emit_insn (gen_tie_hi22di (temp1, addr)); - emit_insn (gen_tie_lo10di (temp2, temp1, addr)); - emit_insn (gen_tie_ld64 (temp3, got, temp2, addr)); - } + emit_insn (gen_tie_ld64 (temp3, got, temp2, addr)); if (TARGET_SUN_TLS) { ret = gen_reg_rtx (Pmode); - if (TARGET_ARCH32) - emit_insn (gen_tie_addsi (ret, gen_rtx_REG (Pmode, 7), - temp3, addr)); - else - emit_insn (gen_tie_adddi (ret, gen_rtx_REG (Pmode, 7), - temp3, addr)); + emit_insn (gen_tie_add (Pmode, ret, gen_rtx_REG (Pmode, 7), + temp3, addr)); } else ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp3); @@ -4786,16 +4733,8 @@ sparc_legitimize_tls_address (rtx addr) case TLS_MODEL_LOCAL_EXEC: temp1 = gen_reg_rtx (Pmode); temp2 = gen_reg_rtx (Pmode); - if (TARGET_ARCH32) - { - emit_insn (gen_tle_hix22si (temp1, addr)); - emit_insn (gen_tle_lox10si (temp2, temp1, addr)); - } - else - { - emit_insn (gen_tle_hix22di (temp1, addr)); - emit_insn (gen_tle_lox10di (temp2, temp1, addr)); - } + emit_insn (gen_tle_hix22 (Pmode, temp1, addr)); + emit_insn (gen_tle_lox10 (Pmode, temp2, temp1, addr)); ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp2); break; @@ -5696,10 +5635,7 @@ sparc_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size) probes at FIRST + N * PROBE_INTERVAL for values of N from 1 until it is equal to ROUNDED_SIZE. */ - if (TARGET_ARCH64) - emit_insn (gen_probe_stack_rangedi (g1, g1, g4)); - else - emit_insn (gen_probe_stack_rangesi (g1, g1, g4)); + emit_insn (gen_probe_stack_range (Pmode, g1, g1, g4)); /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time @@ -9940,9 +9876,11 @@ sparc32_initialize_trampoline (rtx m_tramp, rtx fnaddr, rtx cxt) GEN_INT (trunc_int_for_mode (0x8410a000, SImode)), NULL_RTX, 1, OPTAB_DIRECT)); + emit_insn + (gen_flush (SImode, validize_mem (adjust_address (m_tramp, SImode, 0)))); + /* On UltraSPARC a flush flushes an entire cache line. The trampoline is aligned on a 16 byte boundary so one flush clears it all. */ - emit_insn (gen_flushsi (validize_mem (adjust_address (m_tramp, SImode, 0)))); if (sparc_cpu != PROCESSOR_ULTRASPARC && sparc_cpu != PROCESSOR_ULTRASPARC3 && sparc_cpu != PROCESSOR_NIAGARA @@ -9951,7 +9889,8 @@ sparc32_initialize_trampoline (rtx m_tramp, rtx fnaddr, rtx cxt) && sparc_cpu != PROCESSOR_NIAGARA4 && sparc_cpu != PROCESSOR_NIAGARA7 && sparc_cpu != PROCESSOR_M8) - emit_insn (gen_flushsi (validize_mem (adjust_address (m_tramp, SImode, 8)))); + emit_insn + (gen_flush (SImode, validize_mem (adjust_address (m_tramp, SImode, 8)))); /* Call __enable_execute_stack after writing onto the stack to make sure the stack address is accessible. */ @@ -9988,8 +9927,11 @@ sparc64_initialize_trampoline (rtx m_tramp, rtx fnaddr, rtx cxt) GEN_INT (trunc_int_for_mode (0xca586010, SImode))); emit_move_insn (adjust_address (m_tramp, DImode, 16), cxt); emit_move_insn (adjust_address (m_tramp, DImode, 24), fnaddr); - emit_insn (gen_flushdi (validize_mem (adjust_address (m_tramp, DImode, 0)))); + emit_insn + (gen_flush (DImode, validize_mem (adjust_address (m_tramp, DImode, 0)))); + /* On UltraSPARC a flush flushes an entire cache line. The trampoline is + aligned on a 16 byte boundary so one flush clears it all. */ if (sparc_cpu != PROCESSOR_ULTRASPARC && sparc_cpu != PROCESSOR_ULTRASPARC3 && sparc_cpu != PROCESSOR_NIAGARA @@ -9998,7 +9940,8 @@ sparc64_initialize_trampoline (rtx m_tramp, rtx fnaddr, rtx cxt) && sparc_cpu != PROCESSOR_NIAGARA4 && sparc_cpu != PROCESSOR_NIAGARA7 && sparc_cpu != PROCESSOR_M8) - emit_insn (gen_flushdi (validize_mem (adjust_address (m_tramp, DImode, 8)))); + emit_insn + (gen_flush (DImode, validize_mem (adjust_address (m_tramp, DImode, 8)))); /* Call __enable_execute_stack after writing onto the stack to make sure the stack address is accessible. */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index c5d369626cc..a8d99629fcd 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1592,7 +1592,7 @@ ;; because the RDPC instruction is extremely expensive and incurs a complete ;; instruction pipeline flush. -(define_insn "load_pcrel_sym<P:mode>" +(define_insn "@load_pcrel_sym<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "symbolic_operand" "") (match_operand:P 2 "call_address_operand" "") @@ -7290,7 +7290,7 @@ visl") = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS); }) -(define_insn "probe_stack_range<P:mode>" +(define_insn "@probe_stack_range<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") (match_operand:P 2 "register_operand" "r")] @@ -7468,7 +7468,7 @@ visl") ;; Special pattern for the FLUSH instruction. -(define_insn "flush<P:mode>" +(define_insn "@flush<P:mode>" [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)] "" { @@ -7935,14 +7935,14 @@ visl") ;; TLS support instructions. -(define_insn "tgd_hi22<P:mode>" +(define_insn "@tgd_hi22<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (high:P (unspec:P [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD)))] "TARGET_TLS" "sethi\\t%%tgd_hi22(%a1), %0") -(define_insn "tgd_lo10<P:mode>" +(define_insn "@tgd_lo10<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (lo_sum:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand 2 "tgd_symbolic_operand" "")] @@ -7950,7 +7950,7 @@ visl") "TARGET_TLS" "add\\t%1, %%tgd_lo10(%a2), %0") -(define_insn "tgd_add<P:mode>" +(define_insn "@tgd_add<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (plus:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand:P 2 "register_operand" "r") @@ -7959,7 +7959,7 @@ visl") "TARGET_TLS" "add\\t%1, %2, %0, %%tgd_add(%a3)") -(define_insn "tgd_call<P:mode>" +(define_insn "@tgd_call<P:mode>" [(set (match_operand 0 "register_operand" "=r") (call (mem:P (unspec:P [(match_operand:P 1 "symbolic_operand" "s") (match_operand 2 "tgd_symbolic_operand" "")] @@ -7972,20 +7972,20 @@ visl") (const_string "call") (const_string "call_no_delay_slot")))]) -(define_insn "tldm_hi22<P:mode>" +(define_insn "@tldm_hi22<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (high:P (unspec:P [(const_int 0)] UNSPEC_TLSLDM)))] "TARGET_TLS" "sethi\\t%%tldm_hi22(%&), %0") -(define_insn "tldm_lo10<P:mode>" +(define_insn "@tldm_lo10<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (lo_sum:P (match_operand:P 1 "register_operand" "r") (unspec:P [(const_int 0)] UNSPEC_TLSLDM)))] "TARGET_TLS" "add\\t%1, %%tldm_lo10(%&), %0") -(define_insn "tldm_add<P:mode>" +(define_insn "@tldm_add<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (plus:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand:P 2 "register_operand" "r")] @@ -7993,7 +7993,7 @@ visl") "TARGET_TLS" "add\\t%1, %2, %0, %%tldm_add(%&)") -(define_insn "tldm_call<P:mode>" +(define_insn "@tldm_call<P:mode>" [(set (match_operand 0 "register_operand" "=r") (call (mem:P (unspec:P [(match_operand:P 1 "symbolic_operand" "s")] UNSPEC_TLSLDM)) @@ -8005,14 +8005,14 @@ visl") (const_string "call") (const_string "call_no_delay_slot")))]) -(define_insn "tldo_hix22<P:mode>" +(define_insn "@tldo_hix22<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (high:P (unspec:P [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDO)))] "TARGET_TLS" "sethi\\t%%tldo_hix22(%a1), %0") -(define_insn "tldo_lox10<P:mode>" +(define_insn "@tldo_lox10<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (lo_sum:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand 2 "tld_symbolic_operand" "")] @@ -8020,7 +8020,7 @@ visl") "TARGET_TLS" "xor\\t%1, %%tldo_lox10(%a2), %0") -(define_insn "tldo_add<P:mode>" +(define_insn "@tldo_add<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (plus:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand:P 2 "register_operand" "r") @@ -8029,14 +8029,14 @@ visl") "TARGET_TLS" "add\\t%1, %2, %0, %%tldo_add(%a3)") -(define_insn "tie_hi22<P:mode>" +(define_insn "@tie_hi22<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (high:P (unspec:P [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE)))] "TARGET_TLS" "sethi\\t%%tie_hi22(%a1), %0") -(define_insn "tie_lo10<P:mode>" +(define_insn "@tie_lo10<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (lo_sum:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand 2 "tie_symbolic_operand" "")] @@ -8068,7 +8068,7 @@ visl") [(set_attr "type" "load") (set_attr "subtype" "regular")]) -(define_insn "tie_add<P:mode>" +(define_insn "@tie_add<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (plus:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand:P 2 "register_operand" "r") @@ -8077,14 +8077,14 @@ visl") "TARGET_SUN_TLS" "add\\t%1, %2, %0, %%tie_add(%a3)") -(define_insn "tle_hix22<P:mode>" +(define_insn "@tle_hix22<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (high:P (unspec:P [(match_operand 1 "tle_symbolic_operand" "")] UNSPEC_TLSLE)))] "TARGET_TLS" "sethi\\t%%tle_hix22(%a1), %0") -(define_insn "tle_lox10<P:mode>" +(define_insn "@tle_lox10<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (lo_sum:P (match_operand:P 1 "register_operand" "r") (unspec:P [(match_operand 2 "tle_symbolic_operand" "")] @@ -8342,13 +8342,13 @@ visl") operands[1] = gen_rtx_MEM (Pmode, addr); #endif if (TARGET_ARCH64) - emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); + emit_insn (gen_stack_protect_set64 (operands[0], operands[1])); else - emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); + emit_insn (gen_stack_protect_set32 (operands[0], operands[1])); DONE; }) -(define_insn "stack_protect_setsi" +(define_insn "stack_protect_set32" [(set (match_operand:SI 0 "memory_operand" "=m") (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) (set (match_scratch:SI 2 "=&r") (const_int 0))] @@ -8357,7 +8357,7 @@ visl") [(set_attr "type" "multi") (set_attr "length" "3")]) -(define_insn "stack_protect_setdi" +(define_insn "stack_protect_set64" [(set (match_operand:DI 0 "memory_operand" "=m") (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) (set (match_scratch:DI 2 "=&r") (const_int 0))] @@ -8381,13 +8381,13 @@ visl") if (TARGET_ARCH64) { result = gen_reg_rtx (Pmode); - emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1])); + emit_insn (gen_stack_protect_test64 (result, operands[0], operands[1])); test = gen_rtx_EQ (VOIDmode, result, const0_rtx); emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2])); } else { - emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); + emit_insn (gen_stack_protect_test32 (operands[0], operands[1])); result = gen_rtx_REG (CCmode, SPARC_ICC_REG); test = gen_rtx_EQ (VOIDmode, result, const0_rtx); emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2])); @@ -8395,7 +8395,7 @@ visl") DONE; }) -(define_insn "stack_protect_testsi" +(define_insn "stack_protect_test32" [(set (reg:CC CC_REG) (unspec:CC [(match_operand:SI 0 "memory_operand" "m") (match_operand:SI 1 "memory_operand" "m")] @@ -8407,7 +8407,7 @@ visl") [(set_attr "type" "multi") (set_attr "length" "4")]) -(define_insn "stack_protect_testdi" +(define_insn "stack_protect_test64" [(set (match_operand:DI 0 "register_operand" "=&r") (unspec:DI [(match_operand:DI 1 "memory_operand" "m") (match_operand:DI 2 "memory_operand" "m")]