@@ -1123,6 +1123,18 @@ arc64_output_addr_const_extra (FILE *file, rtx x)
11231123 fputs ("@gotpc" , file );
11241124 break ;
11251125
1126+ case ARC64_UNSPEC_TLS_GD :
1127+ fputs ("@tlsgd" , file );
1128+ break ;
1129+
1130+ case ARC64_UNSPEC_TLS_IE :
1131+ fputs ("@tlsie" , file );
1132+ break ;
1133+
1134+ case ARC64_UNSPEC_TLS_OFF :
1135+ fputs ("@tpoff" , file );
1136+ break ;
1137+
11261138 default :
11271139 gcc_unreachable ();
11281140 }
@@ -1140,6 +1152,94 @@ gen_sym_unspec (rtx x, int kind)
11401152 return gen_rtx_UNSPEC (Pmode , gen_rtvec (1 , x ), kind );
11411153}
11421154
1155+ /* The __tls_get_attr symbol. */
1156+ static GTY (( )) rtx arc_tls_symbol ;
1157+
1158+ /* Emit a call to __tls_get_addr. TI is the argument to this function.
1159+ RET is an RTX for the return value location. The entire insn sequence
1160+ is returned. */
1161+
1162+ static void
1163+ arc64_tls_call (rtx dest , rtx arg )
1164+ {
1165+ if (!arc_tls_symbol )
1166+ arc_tls_symbol = init_one_libfunc ("__tls_get_addr" );
1167+
1168+ emit_library_call_value (arc_tls_symbol , dest , LCT_CONST , Pmode ,
1169+ arg , Pmode );
1170+ }
1171+
1172+ /* Create a legitimate mov instruction for the given BASE (unspec). */
1173+
1174+ static rtx
1175+ arc64_legit_unspec (rtx base )
1176+ {
1177+ rtx t1 , ret ;
1178+ gcc_assert (can_create_pseudo_p ());
1179+
1180+ switch (arc64_cmodel_var )
1181+ {
1182+ case ARC64_CMODEL_SMALL :
1183+ case ARC64_CMODEL_MEDIUM :
1184+ return base ;
1185+
1186+ case ARC64_CMODEL_LARGE :
1187+ t1 = gen_reg_rtx (Pmode );
1188+ ret = gen_reg_rtx (Pmode );
1189+ emit_insn (gen_rtx_SET (t1 , gen_rtx_HIGH (Pmode , base )));
1190+ emit_insn (gen_rtx_SET (ret , gen_rtx_LO_SUM (Pmode , t1 , base )));
1191+ return ret ;
1192+
1193+ default :
1194+ break ;
1195+ }
1196+ gcc_unreachable ();
1197+ }
1198+
1199+ /* Return a legitimized TLS address to access ADDR, which is a
1200+ SYMBOL_REF. */
1201+
1202+ static rtx
1203+ arc64_legitimize_tls_address (rtx addr )
1204+ {
1205+ rtx t1 , t2 ;
1206+ rtx base ;
1207+ enum tls_model model = SYMBOL_REF_TLS_MODEL (addr );
1208+
1209+ gcc_assert (can_create_pseudo_p ());
1210+
1211+ switch (model )
1212+ {
1213+ case TLS_MODEL_LOCAL_DYNAMIC :
1214+ case TLS_MODEL_GLOBAL_DYNAMIC :
1215+ /* Gen:
1216+ addl r0,pcl,@ADDR@tlsgd
1217+ bl __tls_get_addr@plt */
1218+ t2 = gen_reg_rtx (Pmode );
1219+ base = gen_sym_unspec (addr , ARC64_UNSPEC_TLS_GD );
1220+ t1 = arc64_legit_unspec (base );
1221+ arc64_tls_call (t2 , t1 );
1222+ return t2 ;
1223+
1224+ case TLS_MODEL_INITIAL_EXEC :
1225+ /* Gen:
1226+ ldl rx,[pcl,@ADDR@tlsie]
1227+ addl rx,rx,r30 */
1228+ addr = arc64_legit_unspec (gen_sym_unspec (addr , ARC64_UNSPEC_TLS_IE ));
1229+ addr = copy_to_mode_reg (Pmode , gen_const_mem (Pmode , addr ));
1230+ return gen_rtx_PLUS (Pmode , addr , gen_rtx_REG (Pmode , R30_REGNUM ));
1231+
1232+ case TLS_MODEL_LOCAL_EXEC :
1233+ /* Gen:
1234+ addl rx,r30,@ADDR@tpoff */
1235+ addr = arc64_legit_unspec (gen_sym_unspec (addr , ARC64_UNSPEC_TLS_OFF ));
1236+ return gen_rtx_PLUS (Pmode , gen_rtx_REG (Pmode , R30_REGNUM ), addr );
1237+
1238+ default :
1239+ gcc_unreachable ();
1240+ }
1241+ }
1242+
11431243/* Helper function. Returns a valid ARC64 RTX that represents the
11441244 argument X which is an invalid address RTX. The argument SCRATCH
11451245 may be used as a temp when building affresses. */
@@ -1154,6 +1254,8 @@ arc64_legitimize_address_1 (rtx x, rtx scratch)
11541254 {
11551255 case SYMBOL_REF :
11561256 is_local = SYMBOL_REF_LOCAL_P (x );
1257+ if (SYMBOL_REF_TLS_MODEL (x ))
1258+ return arc64_legitimize_tls_address (x );
11571259 /* FALLTHRU */
11581260
11591261 case LABEL_REF :
@@ -1934,6 +2036,12 @@ arc64_limm_addr_p (rtx op)
19342036#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
19352037#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA arc64_output_addr_const_extra
19362038
2039+ /* Having TLS support, we turn R30 fixed as well. */
2040+ #ifdef HAVE_AS_TLS
2041+ #undef TARGET_HAVE_TLS
2042+ #define TARGET_HAVE_TLS HAVE_AS_TLS
2043+ #endif
2044+
19372045struct gcc_target targetm = TARGET_INITIALIZER ;
19382046
19392047#include "gt-arc64.h"
0 commit comments