On Sun, Mar 4, 2012 at 11:38 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Sun, Mar 4, 2012 at 2:12 PM, Uros Bizjak <ubiz...@gmail.com> wrote: >> On Fri, Mar 2, 2012 at 9:36 PM, H.J. Lu <hongjiu...@intel.com> wrote: >> >>> X86-64 linker optimizes TLS_MODEL_INITIAL_EXEC to TLS_MODEL_LOCAL_EXEC >>> by checking >>> >>> movq foo@gottpoff(%rip), %reg >>> >>> and >>> >>> addq foo@gottpoff(%rip), %reg >>> >>> It uses the REX prefix to avoid the last byte of the previous >>> instruction. With 32bit Pmode, we may not have the REX prefix and >>> the last byte of the previous instruction may be an offset, which >>> may look like a REX prefix. IE->LE optimization will generate corrupted >>> binary. This patch makes sure we always output an REX pfrefix for >>> UNSPEC_GOTNTPOFF. OK for trunk? >> >> No, please implement this using UNSPEC in the same way as >> tls_initial_exec_64_sun implements Sun linker quirk. >> > > I am not sure how it can be done with UNSPEC cleanly. > Unlike the Sun linker issue, this is an instruction encoding > issue. At instruction pattern level, there is no difference > between x32 and x86-64. I need to make sure that there is > always one and only one REX prefix with UNSPEC_GOTNTPOFF. > If REG is r8-r15, we shouldn't add another REX prefix.
(define_insn "tls_initial_exec_x32" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] UNSPEC_TLS_IE_X32)) (clobber (reg:CC FLAGS_REG))] "TARGET_X32" { if (!REX_INT_REG_P (operands[0]) fputs (\trex\n", asm_out_file); output_asm_insn ("mov{l}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); if (!REX_INT_REG_P (operands[0]) fputs (\trex\n", asm_out_file); return "add{l}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; } [(set_attr "type" "multi")]) rex or rex64 prefix, whatever you wish. Then generate this pattern from legitimize_tls_address, <TLS_MODEL_INITIAL_EXEC>, see TARGET_SUN_TLS part. Uros.