diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 8a88f14a6f4..d095c9542dc 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -86,6 +86,7 @@ UNSPEC_TLSTPRELLO UNSPEC_TLSGOTTPREL UNSPEC_TLSTLS + UNSPEC_TLSTLS_PCREL UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero UNSPEC_STFIWX UNSPEC_POPCNTB @@ -257,6 +258,31 @@ (define_attr "cannot_copy" "no,yes" (const_string "no")) +;; Whether this instruction is part of the two instruction sequence that +;; supports PCREL_OPT optimizations, where the linker can change code of the +;; form: +;; +;; pld b,var@got@pcrel +;; 100: +;; # possibly other instructions +;; .reloc 100b-8,R_PPC64_PCREL_OPT,0 +;; lwz r,0(b) +;; +;; into the following if 'var' is in the main program: +;; +;; plwz r,0(b) +;; # possibly other instructions +;; nop +;; +;; The states are: +;; no -- insn is not involved with PCREL_OPT optimizations +;; load_got -- insn loads up the GOT pointer for a load instruction +;; load -- insn is an offsettable load that uses the GOT pointer +;; store_got -- insn loads up the GOT pointer for a store instruction +;; store -- insn is an offsettable store that uses the GOT pointer + +(define_attr "pcrel_opt" "no,load_got,load,store_got,store" (const_string "no")) + ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed ;; before the instruction. A prefixed instruction has a prefix instruction ;; word that extends the immediate value of the instructions from 12-16 bits to @@ -9497,6 +9523,15 @@ ;; TLS support. +(define_insn "*tls_gd_pcrel<bits>" + [(set (match_operand:P 0 "gpc_reg_operand" "=b") + (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") + (const_int 0)] + UNSPEC_TLSGD))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS" + "la %0,%1@got@tlsgd@pcrel" + [(set_attr "prefixed" "yes")]) + (define_insn_and_split "*tls_gd<bits>" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") @@ -9537,6 +9572,14 @@ "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addi %0,%1,%2@got@tlsgd@l") +(define_insn "*tls_ld_pcrel<bits>" + [(set (match_operand:P 0 "gpc_reg_operand" "=b") + (unspec:P [(const_int 0)] + UNSPEC_TLSLD))] + "HAVE_AS_TLS && TARGET_TLS_MARKERS" + "la %0,%&@got@tlsld@pcrel" + [(set_attr "prefixed" "yes")]) + (define_insn_and_split "*tls_ld<bits>" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] @@ -9580,7 +9623,11 @@ (match_operand:P 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSDTPREL))] "HAVE_AS_TLS" - "addi %0,%1,%2@dtprel") + "addi %0,%1,%2@dtprel" + [(set (attr "prefixed") + (if_then_else (match_test "rs6000_tls_size == 16") + (const_string "no") + (const_string "yes")))]) (define_insn "tls_dtprel_ha_<bits>" [(set (match_operand:P 0 "gpc_reg_operand" "=r") @@ -9644,7 +9691,11 @@ (match_operand:P 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSTPREL))] "HAVE_AS_TLS" - "addi %0,%1,%2@tprel") + "addi %0,%1,%2@tprel" + [(set (attr "prefixed") + (if_then_else (match_test "rs6000_tls_size == 16") + (const_string "no") + (const_string "yes")))]) (define_insn "tls_tprel_ha_<bits>" [(set (match_operand:P 0 "gpc_reg_operand" "=r") @@ -9662,6 +9713,15 @@ "HAVE_AS_TLS" "addi %0,%1,%2@tprel@l") +(define_insn "*tls_got_tprel_pcrel_<bits>" + [(set (match_operand:P 0 "gpc_reg_operand" "=b") + (unspec:P [(const_int 0) + (match_operand:P 1 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL))] + "HAVE_AS_TLS" + "<ptrload> %0,%1@got@tprel@pcrel" + [(set_attr "prefixed" "yes")]) + ;; "b" output constraint here and on tls_tls input to support linker tls ;; optimization. The linker may edit the instructions emitted by a ;; tls_got_tprel/tls_tls pair to addis,addi. @@ -9705,6 +9765,14 @@ "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "<ptrload> %0,%2@got@tprel@l(%1)") +(define_insn "tls_tls_pcrel_<bits>" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTLS_PCREL))] + "TARGET_ELF && HAVE_AS_TLS" + "add %0,%1,%2@tls@pcrel") + (define_insn "tls_tls_<bits>" [(set (match_operand:P 0 "gpc_reg_operand" "=r") (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") @@ -14742,6 +14810,7 @@ [(set_attr "type" "logical")]) +(include "pcrel.md") (include "sync.md") (include "vector.md") (include "vsx.md") |