diff mbox

PATCH: PR target/47715: [x32] Use SImode for thread pointer

Message ID CAMe9rOrmGbkcdUTsSW61TznXXSZ03=12Pi6cu4qTAmt+-E42kQ@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu July 28, 2011, 8:15 p.m. UTC
On Thu, Jul 28, 2011 at 11:31 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Thu, Jul 28, 2011 at 8:30 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>
>>>>>> TP is 32bit in x32  For load_tp_x32, we load SImode value and
>>>>>> zero-extend to DImode. For add_tp_x32, we are adding SImode
>>>>>> value.  We can't pretend TP is 64bit.  load_tp_x32 and add_tp_x32
>>>>>> must take SImode TP.
>>>>>>
>>>>>
>>>>> I will see what I can do.
>>>>>
>>>>
>>>> Here is the updated patch to use 32bit TP for 32.
>>>
>>> Why??
>>>
>>> This part makes no sense:
>>>
>>> -  tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
>>> +  tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
>>> +  if (ptr_mode != Pmode)
>>> +    tp = convert_to_mode (Pmode, tp, 1);
>>>
>>> You will create zero_extend (unspec ...), that won't be matched by any pattern.
>>
>> No.  I created  zero_exten from (reg:SI) to (reg: DI).
>>
>>> Can you please explain, how is this pattern different than DImode
>>> pattern, proposed in my patch?
>>>
>>> +(define_insn "*load_tp_x32"
>>> +  [(set (match_operand:SI 0 "register_operand" "=r")
>>> +       (unspec:SI [(const_int 0)] UNSPEC_TP))]
>>> +  "TARGET_X32"
>>> +  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
>>> +  [(set_attr "type" "imov")
>>> +   (set_attr "modrm" "0")
>>> +   (set_attr "length" "7")
>>> +   (set_attr "memory" "load")
>>> +   (set_attr "imm_disp" "false")])
>>>
>>> vs:
>>>
>>> +(define_insn "*load_tp_x32"
>>> +  [(set (match_operand:DI 0 "register_operand" "=r")
>>> +       (unspec:DI [(const_int 0)] UNSPEC_TP))]
>>
>> That is wrong since source (TP)  is 32bit.  This pattern tells compiler
>> source is 64bit.
>
> Where?
>

Here is the revised patch.  The difference is I changed *add_tp_x32 to SImode.
For

---
extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec")));

int *
__errno_location (void)
{
  return &__libc_errno;
}
---

compiled with -mx32 -O2 -fPIC  DImode *add_tp_x32 generates:

	movq	__libc_errno@gottpoff(%rip), %rax
	addl	%fs:0, %eax
	mov	%eax, %eax
	ret

SImode *add_tp_x32 generates:

	movl	%fs:0, %eax
	addl	__libc_errno@gottpoff(%rip), %eax
	ret

OK for trunk?

Thanks.
diff mbox

Patch

2011-07-28  Uros Bizjak  <ubizjak@gmail.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	PR target/47715
	* config/i386/i386.md (*load_tp_x32):  New.
	(*add_tp_x32): Likewise.
	(*load_tp_<mode>): Disabled for TARGET_X32.
	(*add_tp_<mode>): Likewise.

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f33b8a0..7658522 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12444,10 +12452,21 @@ 
 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
 
 ;; Load and add the thread base pointer from %<tp_seg>:0.
+(define_insn "*load_tp_x32"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(const_int 0)] UNSPEC_TP))]
+  "TARGET_X32"
+  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
+  [(set_attr "type" "imov")
+   (set_attr "modrm" "0")
+   (set_attr "length" "7")
+   (set_attr "memory" "load")
+   (set_attr "imm_disp" "false")])
+
 (define_insn "*load_tp_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
 	(unspec:P [(const_int 0)] UNSPEC_TP))]
-  ""
+  "!TARGET_X32"
   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
   [(set_attr "type" "imov")
    (set_attr "modrm" "0")
@@ -12455,12 +12474,25 @@ 
    (set_attr "memory" "load")
    (set_attr "imm_disp" "false")])
 
+(define_insn "*add_tp_x32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
+		 (match_operand:SI 1 "register_operand" "0")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_X32"
+  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
+  [(set_attr "type" "alu")
+   (set_attr "modrm" "0")
+   (set_attr "length" "7")
+   (set_attr "memory" "load")
+   (set_attr "imm_disp" "false")])
+
 (define_insn "*add_tp_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
 	(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
 		(match_operand:P 1 "register_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
-  ""
+  "!TARGET_X32"
   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
   [(set_attr "type" "alu")
    (set_attr "modrm" "0")