Skip to content

Commit 623759f

Browse files
clazissartemiy-volkov
authored andcommitted
[TLS] Add basic TLS support.
1 parent 50dff12 commit 623759f

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

gcc/config/arc64/arc64.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
19372045
struct gcc_target targetm = TARGET_INITIALIZER;
19382046

19392047
#include "gt-arc64.h"

gcc/config/arc64/arc64.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@
107107
/* Mode of a function address in a call instruction (for indexing purposes). */
108108
#define FUNCTION_MODE Pmode
109109

110+
#ifdef HAVE_AS_TLS
111+
#define ARC64_TLS_REGNO 1
112+
#else
113+
#define ARC64_TLS_REGNO 0
114+
#endif
115+
110116
/* Register usage:
111117
R0-R3 Parameter/result registers
112118
R4-R7 Parameter registers
@@ -138,7 +144,7 @@
138144
0, 0, 0, 0, 0, 0, 0, 0, /* R0 - R7 */ \
139145
0, 0, 0, 0, 0, 0, 0, 0, /* R8 - R15 */ \
140146
0, 0, 0, 0, 0, 0, 0, 0, /* R16 - R23 */ \
141-
0, 0, 0, 0, 1, 1, 0, 1, /* R24 - R26, FP, SP, ILINK, R30, BLINK */ \
147+
0, 0, 0, 0, 1, 1, ARC64_TLS_REGNO, 1, /* R24 - R26, FP, SP, ILINK, R30, BLINK */ \
142148
\
143149
1, 1, 1, 1, 1, 1, 1, 1, /* R32 - R39 */ \
144150
1, 1, 1, 1, 1, 1, 1, 1, /* R40 - R47 */ \

gcc/config/arc64/arc64.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@
7373
ARC64_UNSPEC_GOTOFF
7474
ARC64_UNSPEC_GOT
7575
ARC64_UNSPEC_GOT32
76+
ARC64_UNSPEC_TLS_GD
77+
ARC64_UNSPEC_TLS_IE
78+
ARC64_UNSPEC_TLS_OFF
7679
ARC64_VUNSPEC_BLOCKAGE
7780
])
7881

gcc/config/arc64/arith.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,16 @@
3434
(set_attr "length" "4,4,4,4,4,8,8")
3535
(set_attr "type" "<arc64_code_map>")]
3636
)
37+
38+
39+
;; To be merged into adddi3
40+
(define_insn "*add_tls_off"
41+
[(set (match_operand:DI 0 "register_operand" "=r")
42+
(plus:DI (match_operand:DI 1 "register_operand" "r")
43+
(unspec:DI [(match_operand 2 "" "")]
44+
ARC64_UNSPEC_TLS_OFF)))]
45+
""
46+
"addl\\t%0,%1,%2@tpoff"
47+
[(set_attr "type" "addl")
48+
(set_attr "length" "8")]
49+
)

0 commit comments

Comments
 (0)