On Mon, Mar 19, 2012 at 6:01 PM, Uros Bizjak <ubiz...@gmail.com> wrote: >>>> For x32, thread pointer is an unsigned 32bit value. >>>> >>>> movl %fs:0, %eax >>>> >>>> is the correct instruction to load thread pointer into EAX and RAX. >>> >>> So, where is ZERO_EXTEND RTX then? >>> >> >> Thread pointer (TP) is an opaque value to GCC. GCC needs to load >> TP into a SImode or DImode register. ZERO_EXTEND isn't needed >> when there is a single instruction to load TP into a DImode register. > > I don't agree with this explanation. The mode can't be SImode and > DImode. TP is either SImode or ZERO_EXTENDed to DImode, this is the > reason we went for all that TARGET_X32 stuff in TP load RTX. > > Please test my proposed patch. If it works OK, I will commit it to SVN.
The onyl acceptable way is to generate ZERO_EXTEND in place, so: --cut here-- static rtx get_thread_pointer (enum machine_mode tp_mode, bool to_reg) { rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP); if (GET_MODE (tp) != tp_mode) { gcc_assert (GET_MODE (tp) == SImode); gcc_assert (tp_mode == DImode); tp = gen_rtx_ZERO_EXTEND (tp_mode, tp); } if (to_reg) tp = copy_to_mode_reg (tp_mode, tp); return tp; } --cut here-- This will generate: movq c@gottpoff(%rip), %rax movzbl %fs:(%rax), %eax movb %al, y(%rip) movq w@gottpoff(%rip), %rax movzwl %fs:(%rax), %eax movw %ax, i(%rip) ret Uros.