diff options
author | Alan Modra <amodra@gmail.com> | 2011-06-20 14:42:10 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2011-06-20 14:42:10 +0930 |
commit | 3bae1d98650efce91703cc4cb37231bf8c12ef94 (patch) | |
tree | a7c8d0569095d18c55aee8e1f58232219baf0804 /gcc/config/rs6000 | |
parent | 8fe2f96186ca193a2216da101a00cc02e93f1842 (diff) | |
download | gcc-3bae1d98650efce91703cc4cb37231bf8c12ef94.zip gcc-3bae1d98650efce91703cc4cb37231bf8c12ef94.tar.gz gcc-3bae1d98650efce91703cc4cb37231bf8c12ef94.tar.bz2 |
rs6000.c (create_TOC_reference): Wrap high part of toc-relative address in CONST.
* config/rs6000/rs6000.c (create_TOC_reference): Wrap high part
of toc-relative address in CONST.
(rs6000_delegitimize_address): Recognize changed address.
(rs6000_legitimize_reload_address): Likewise.
(rs6000_emit_move): Don't force these constants to memory.
* config/rs6000/rs6000.md (tls_gd, tls_gd_high): Wrap high part of
toc-relative address in CONST.
(tls_ld, tls_ld_high, tls_got_dtprel, tls_got_dtprel_high): Likewise.
(tls_got_tprel, tls_got_tprel_high, largetoc_high): Likewise.
From-SVN: r175200
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 26 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 67 |
2 files changed, 55 insertions, 38 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c15c04e..df6e7d9 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5803,12 +5803,13 @@ rs6000_delegitimize_address (rtx orig_x) || TARGET_MINIMAL_TOC || TARGET_CMODEL != CMODEL_SMALL)) || (TARGET_CMODEL != CMODEL_SMALL - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (x, 0)) == CONST + && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG + && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH && rtx_equal_p (XEXP (x, 1), - XEXP (XEXP (XEXP (x, 0), 1), 0))))) + XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0))))) { y = XVECEXP (y, 0, 0); if (offset != NULL_RTX) @@ -6147,11 +6148,12 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH && GET_CODE (XEXP (x, 1)) == CONST && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL - && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1))) + && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1))) { push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, @@ -7197,6 +7199,11 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) } else if (mode == Pmode && CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && !(TARGET_CMODEL != CMODEL_SMALL + && GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH) && ((GET_CODE (operands[1]) != CONST_INT && ! easy_fp_constant (operands[1], mode)) || (GET_CODE (operands[1]) == CONST_INT @@ -7204,7 +7211,6 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2))) || (GET_CODE (operands[0]) == REG && FP_REGNO_P (REGNO (operands[0])))) - && GET_CODE (operands[1]) != HIGH && ! legitimate_constant_pool_address_p (operands[1], mode, false) && ! toc_relative_expr_p (operands[1]) @@ -19063,7 +19069,9 @@ create_TOC_reference (rtx symbol, rtx largetoc_reg) tocreg = gen_rtx_REG (Pmode, TOC_REGISTER); if (TARGET_CMODEL != CMODEL_SMALL) { - rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel)); + rtx hi = gen_rtx_CONST (Pmode, + gen_rtx_PLUS (Pmode, tocreg, + gen_rtx_HIGH (Pmode, tocrel))); if (largetoc_reg != NULL) { emit_move_insn (largetoc_reg, hi); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 61a70ee..e70598d 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -11523,9 +11523,10 @@ "addi %0,%1,%2@got@tlsgd" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))] @@ -11540,10 +11541,11 @@ (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tlsgd@ha" [(set_attr "length" "4")]) @@ -11658,9 +11660,10 @@ "addi %0,%1,%&@got@tlsld" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 2) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 2) (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] @@ -11675,9 +11678,10 @@ (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%&@got@tlsld@ha" [(set_attr "length" "4")]) @@ -11753,9 +11757,10 @@ "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))] @@ -11770,10 +11775,11 @@ (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@dtprel@ha" [(set_attr "length" "4")]) @@ -11823,9 +11829,10 @@ "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))] @@ -11840,10 +11847,11 @@ (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tprel@ha" [(set_attr "length" "4")]) @@ -12157,8 +12165,9 @@ ;; Largetoc support (define_insn "largetoc_high" [(set (match_operand:DI 0 "gpc_reg_operand" "=b") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") - (high:DI (match_operand:DI 2 "" ""))))] + (const:DI + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (high:DI (match_operand:DI 2 "" "")))))] "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" "{cau|addis} %0,%1,%2@ha") |