\f
;; TLS support.
-;; "b" output constraint here and on tls_ld to support tls linker optimization.
-(define_insn "tls_gd_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGD))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%2@got@tlsgd")
-
-(define_insn "tls_gd_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGD))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "addi %0,%1,%2@got@tlsgd")
-
-(define_insn "tls_ld_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")]
- UNSPEC_TLSLD))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%&@got@tlsld")
-
-(define_insn "tls_ld_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")]
- UNSPEC_TLSLD))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "addi %0,%1,%&@got@tlsld")
-
-(define_insn "tls_dtprel_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPREL))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%2@dtprel")
-
-(define_insn "tls_dtprel_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPREL))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "addi %0,%1,%2@dtprel")
-
-(define_insn "tls_dtprel_ha_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPRELHA))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addis %0,%1,%2@dtprel@ha")
+;; Mode attributes for different ABIs.
+(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
+(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
+(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
+(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
+
+(define_insn "tls_gd_aix<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+ (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
+ (match_operand 4 "" "g")))
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD)
+ (clobber (reg:SI LR_REGNO))]
+ "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+ "addi %0,%1,%2@got@tlsgd\;bl %z3\;%."
+ [(set_attr "type" "two")
+ (set_attr "length" "12")])
-(define_insn "tls_dtprel_ha_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPRELHA))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "addis %0,%1,%2@dtprel@ha")
+(define_insn "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+ (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
+ (match_operand 4 "" "g")))
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD)
+ (clobber (reg:SI LR_REGNO))]
+ "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
+{
+ if (flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
+ else
+ return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
+ }
+ else
+ return "addi %0,%1,%2@got@tlsgd\;bl %z3";
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
-(define_insn "tls_dtprel_lo_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPRELLO))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%2@dtprel@l")
+(define_insn "tls_ld_aix<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+ (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
+ (match_operand 3 "" "g")))
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
+ UNSPEC_TLSLD)
+ (clobber (reg:SI LR_REGNO))]
+ "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
+ "addi %0,%1,%&@got@tlsld\;bl %z2\;%."
+ [(set_attr "length" "12")])
-(define_insn "tls_dtprel_lo_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSDTPRELLO))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "addi %0,%1,%2@dtprel@l")
+(define_insn "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+ (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
+ (match_operand 3 "" "g")))
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
+ UNSPEC_TLSLD)
+ (clobber (reg:SI LR_REGNO))]
+ "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
+{
+ if (flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
+ else
+ return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
+ }
+ else
+ return "addi %0,%1,%&@got@tlsld\;bl %z2";
+}
+ [(set_attr "length" "8")])
-(define_insn "tls_got_dtprel_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTDTPREL))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "lwz %0,%2@got@dtprel(%1)")
+(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPREL))]
+ "HAVE_AS_TLS"
+ "addi %0,%1,%2@dtprel")
-(define_insn "tls_got_dtprel_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTDTPREL))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "ld %0,%2@got@dtprel(%1)")
+(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELHA))]
+ "HAVE_AS_TLS"
+ "addis %0,%1,%2@dtprel@ha")
-(define_insn "tls_tprel_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPREL))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%2@tprel")
+(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELLO))]
+ "HAVE_AS_TLS"
+ "addi %0,%1,%2@dtprel@l")
-(define_insn "tls_tprel_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPREL))]
- "HAVE_AS_TLS && TARGET_64BIT"
+(define_insn "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL))]
+ "HAVE_AS_TLS"
+ "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)")
+
+(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPREL))]
+ "HAVE_AS_TLS"
"addi %0,%1,%2@tprel")
-(define_insn "tls_tprel_ha_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPRELHA))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addis %0,%1,%2@tprel@ha")
-
-(define_insn "tls_tprel_ha_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPRELHA))]
- "HAVE_AS_TLS && TARGET_64BIT"
+(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELHA))]
+ "HAVE_AS_TLS"
"addis %0,%1,%2@tprel@ha")
-(define_insn "tls_tprel_lo_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPRELLO))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "addi %0,%1,%2@tprel@l")
-
-(define_insn "tls_tprel_lo_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTPRELLO))]
- "HAVE_AS_TLS && TARGET_64BIT"
+(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELLO))]
+ "HAVE_AS_TLS"
"addi %0,%1,%2@tprel@l")
;; "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.
-(define_insn "tls_got_tprel_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTTPREL))]
- "HAVE_AS_TLS && !TARGET_64BIT"
- "lwz %0,%2@got@tprel(%1)")
-
-(define_insn "tls_got_tprel_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTTPREL))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "ld %0,%2@got@tprel(%1)")
-
-(define_insn "tls_tls_32"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
- (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTLS))]
- "HAVE_AS_TLS && !TARGET_64BIT"
+(define_insn "tls_got_tprel_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL))]
+ "HAVE_AS_TLS"
+ "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)")
+
+(define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
+ [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTLS))]
+ "HAVE_AS_TLS"
"add %0,%1,%2@tls")
-(define_insn "tls_tls_64"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSTLS))]
- "HAVE_AS_TLS && TARGET_64BIT"
- "add %0,%1,%2@tls")
\f
;; Next come insns related to the calling sequence.
;;