*/
scalar_mode = mode = GET_MODE (src);
- rtx src0 = XEXP (src, 0);
- tls_symbol = XVECEXP (src0, 0, 0);
- rtx src1 = XVECEXP (src0, 0, 1);
- if (REG_P (src1))
- {
- set_insn = tls_set_insn_from_symbol (src1, tls_symbol);
- gcc_assert (set_insn);
- }
- else
- {
- set_insn = nullptr;
- gcc_assert (GET_CODE (src1) == UNSPEC
- && XINT (src1, 1) == UNSPEC_TLSDESC
- && SYMBOL_REF_P (XVECEXP (src1, 0, 0))
- && rtx_equal_p (XVECEXP (src1, 0, 0), tls_symbol));
- }
- /* Use TLS_SYMBOL and
+ /* Since the first operand of PLUS in the source TLS_COMBINE
+ pattern is unused, use the second operand of PLUS:
(const:DI (unspec:DI [
(symbol_ref:DI ("e") [flags 0x1a])
] UNSPEC_DTPOFF))
- as VAL to check if 2 patterns have the same source. */
-
- rtvec vec = gen_rtvec (2, tls_symbol, XEXP (src, 1));
- val = gen_rtx_UNSPEC (mode, vec, UNSPEC_TLSDESC);
- def_insn = set_insn;
+ as VAL to check if 2 TLS_COMBINE patterns have the same
+ source. */
+ val = XEXP (src, 1);
+ gcc_assert (GET_CODE (val) == CONST
+ && GET_CODE (XEXP (val, 0)) == UNSPEC
+ && XINT (XEXP (val, 0), 1) == UNSPEC_DTPOFF
+ && SYMBOL_REF_P (XVECEXP (XEXP (val, 0), 0, 0)));
+ def_insn = nullptr;
return true;
}
--- /dev/null
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O3 -fpic -fplt -mtls-dialect=gnu" } */
+
+typedef enum
+{
+ bfd_error_invalid_error_code
+} bfd_error_type;
+static thread_local bfd_error_type bfd_error;
+extern int sections;
+extern void *bfd_alloc_ret;
+extern int bfd_alloc___o;
+extern long bfd_alloc_size;
+
+extern void _objalloc_alloc (int *, long);
+
+bfd_error_type
+bfd_get_error ()
+{
+ return bfd_error;
+}
+
+bool
+s7_bfd_score_elf_late_size_sections ()
+{
+ for (; sections;)
+ {
+ if (bfd_alloc_size)
+ {
+ bfd_error_type error_tag;
+ bfd_error = error_tag;
+ }
+ _objalloc_alloc (&bfd_alloc___o, 0);
+ if (bfd_alloc_ret)
+ {
+ bfd_error_type error_tag;
+ bfd_error = error_tag;
+ }
+ }
+}
+
+/* { dg-final { scan-assembler-times "call\[ \t\]__tls_get_addr@PLT" 2 { target { ! ia32 } } } } */