Hi all,

I currently have the following RTL patch to TLS handling code on hand, but
am having major trouble understanding it:

+#if TARGET_WIN32_TLS
+  rtx scratch = gen_rtx_SCRATCH (Pmode);
+
+  rtx basereg = gen_reg_rtx (Pmode);
+  rtx thread = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
UNSPEC_TP);
+
+  rtx insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_SET
(basereg, thread), gen_rtx_CLOBBER (VOIDmode, scratch)));
+  emit_insn (insn);
+
+  // Only 64-bit is supported
+  rtx offset = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TPOFF);
+  offset = gen_rtx_CONST (SImode, offset);
+
+  rtx reg = gen_reg_rtx (Pmode);
+  insn = gen_rtx_SET (gen_rtx_SUBREG (SImode, reg, 0), offset);
+  emit_insn (insn);
+
+  return gen_rtx_PLUS (Pmode, basereg, reg);
+#endif
+

When gcc with this patch applied is used to compile the following sample
test program:

_Thread_local int local = 2;

int get(void) {
    return local;
}

The following error results:

# gcc -s -std=c11 -pedantic -Wpedantic tls.c
tls.c: In function 'get':
tls.c:5:1: error: unrecognizable insn:
    5 | }
      | ^
(insn 5 2 6 2 (parallel [
            (set (reg:DI 100)
                (unspec:DI [
                        (const_int 0 [0])
                    ] UNSPEC_TP))
            (clobber (scratch:DI))
        ]) "tls.c":4:12 -1
     (nil))
during RTL pass: vregs

Suffice to say I can't understand what the RTL manipulation code above is
actually doing, no matter how much I consult the RTL documentation. All I
know is that UNSPEC_TP and UNSPEC_TPOFF obviously won't work, because those
RTL templates aren't meant for my target platform - Windows. Could I
trouble anyone and ask what exactly the RTL shown above will lower to? (As
in, what the resulting assembly will look like) I'd also appreciate if
someone could point out why the patch above results in this difficult to
interpret error, so I can learn more about what should be done to fix it

best regards,
Julian

Reply via email to