aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md73
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")