Patchwork [x32] PATCH: PR target/47926: [x32] nested function pointer doesn't work

login
register
mail settings
Submitter H.J. Lu
Date March 1, 2011, 5:34 p.m.
Message ID <20110301173432.GA14670@intel.com>
Download mbox | patch
Permalink /patch/84960/
State New
Headers show

Comments

H.J. Lu - March 1, 2011, 5:34 p.m.
On Mon, Feb 28, 2011 at 11:13:56AM -0800, H.J. Lu wrote:
> Hi,
> 
> We should always use ptr_mode on on address for trampoline.  Checked
> into x32 branch.
> 
> H.J.
> ---
> diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
> index a7547677..df35e6f 100644
> --- a/gcc/ChangeLog.x32
> +++ b/gcc/ChangeLog.x32
> @@ -1,3 +1,9 @@
> +2011-02-28  H.J. Lu  <hongjiu.lu@intel.com>
> +
> +	PR target/47926
> +	* config/i386/i386.c (ix86_trampoline_init): Always use ptr_mode
> +	on address.
> +
>  2011-02-25  H.J. Lu  <hongjiu.lu@intel.com>
>  
>  	PR target/47715
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 7b42577..39b638c 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -23408,7 +23408,10 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
>  	  mem = adjust_address (m_tramp, HImode, offset);
>  	  emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
>  
> -	  mem = adjust_address (m_tramp, DImode, offset + 2);
> +	  mem = adjust_address (m_tramp, ptr_mode, offset + 2);
> +	  if (GET_MODE (fnaddr) != ptr_mode)
> +	    fnaddr = simplify_gen_subreg (ptr_mode, fnaddr,
> +					  GET_MODE (fnaddr), 0);
>  	  emit_move_insn (mem, fnaddr);
>  	  offset += 10;
>  	}
> @@ -23417,7 +23420,7 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
>        mem = adjust_address (m_tramp, HImode, offset);
>        emit_move_insn (mem, gen_int_mode (0xba49, HImode));
>  
> -      mem = adjust_address (m_tramp, DImode, offset + 2);
> +      mem = adjust_address (m_tramp, ptr_mode, offset + 2);
>        emit_move_insn (mem, chain_value);
>        offset += 10;
>  

chain_value in x32 is 32bit.  When we use movabs to load 64bit value,
the upper 32bit is undefined.  I reverted the last patch and checked
this one instead.


H.J.
---
commit b549b9f9f9666c54ec7af0fda8733a8b6d8cf75e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Mar 1 05:33:42 2011 -0800

    Use movl to load trampoline address for x32.

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index a7547677..191ed24 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,9 @@ 
+2011-03-01  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/47926
+	* config/i386/i386.c (ix86_trampoline_init): Use movl instead
+	of movabs for x32.
+
 2011-02-25  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR target/47715
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7b42577..4f7433d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23386,13 +23386,14 @@  ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
     }
   else
     {
-      int offset = 0;
+      int offset = 0, size;
 
       /* Load the function address to r11.  Try to load address using
 	 the shorter movl instead of movabs.  We may want to support
 	 movq for kernel mode, but kernel does not use trampolines at
 	 the moment.  */
-      if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
+      if (TARGET_X32
+	  || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
 	{
 	  fnaddr = copy_to_mode_reg (DImode, fnaddr);
 
@@ -23415,11 +23416,21 @@  ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
 
       /* Load static chain using movabs to r10.  */
       mem = adjust_address (m_tramp, HImode, offset);
-      emit_move_insn (mem, gen_int_mode (0xba49, HImode));
+      /* Use the shorter movl instead of movabs for x32.  */
+      if (TARGET_X32)
+	{
+	  size = 6;
+	  emit_move_insn (mem, gen_int_mode (0xba41, HImode));
+	}
+      else
+	{
+	  size = 10;
+	  emit_move_insn (mem, gen_int_mode (0xba49, HImode));
+	}
 
-      mem = adjust_address (m_tramp, DImode, offset + 2);
+      mem = adjust_address (m_tramp, ptr_mode, offset + 2);
       emit_move_insn (mem, chain_value);
-      offset += 10;
+      offset += size;
 
       /* Jump to r11; the last (unused) byte is a nop, only there to
 	 pad the write out to a single 32-bit store.  */