diff mbox

PATCH [7/n] X32: Handle address output and calls patterns

Message ID CAMe9rOqxq8i+49_dQPyz2gUjr7x8e+Mh3eAQFd5J8Sfdz0G-2A@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu July 20, 2011, 1:18 p.m. UTC
On Wed, Jul 20, 2011 at 1:19 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Jul 20, 2011 at 9:53 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>
>>>>>> since Pmode is used in non-PIC tablejump, we have to put 64bit value for
>>>>>> labels with 0 upper 32bits in tablejump for x32.
>>>>>
>>>>> The mode is completely controled by CASE_VECTOR_MODE.
>>>>>
>>>>
>>>> Here is the updated patch.  OK for trunk?
>>>>
>>>
>>> A small change.  It always use 64bit register for indirect branch.
>>
>> -         ix86_print_operand (file, x, 0);
>> +         /* Always use 64bit register for indirect branch.  */
>> +         ix86_print_operand (file, x,
>> +                             REG_P (x) && TARGET_64BIT ? 'q' : 0);
>>          return;
>>
>> /* Always use 64bit register for indirect branch.  */
>> if (REG_P (x) && TARGET_64BIT)
>>  print_reg (x, 'q', file);
>> else
>>  ix86_print_operand (file, x, 0);
>>
>>  (define_insn "*indirect_jump"
>> -  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
>> +  [(set (pc) (match_operand:P 0 "x32_indirect_branch_operand" "rm"))]
>>
>> Just name it "indirect_branch_operand".
>>
>>  (define_insn_and_split "*call_vzeroupper"
>> -  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
>> +  [(call (mem:QI (match_operand:P 0 "x32_call_insn_operand" "<c>zm"))
>>
>> Don't introduce new predicate, change call_insn_operand instead to
>> conditionally disable memory_operand on x32. You will need to change
>> "<c>zm" register constraint to "<c>z" on x32, otherwise you will get
>> ICEs.
>
> Use new constraint here, something like (untested):
>
> Index: constraints.md
> ===================================================================
> --- constraints.md      (revision 176494)
> +++ constraints.md      (working copy)
> @@ -127,6 +127,11 @@
>   "@internal Constant call address operand."
>   (match_operand 0 "constant_call_address_operand"))
>
> +(define_constraint "w"
> +  "@internal Call memory operand."
> +  (and (match_test "!TARGET_X32")
> +       (match_operand 0 "memory_operand"))
> +
>  ;; Integer constant constraints.
>  (define_constraint "I"
>   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
>
> Uros.
>

Here is the updated patch.  OK for trunk?

Thanks.

Comments

Uros Bizjak July 20, 2011, 1:41 p.m. UTC | #1
On Wed, Jul 20, 2011 at 3:18 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Jul 20, 2011 at 1:19 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Wed, Jul 20, 2011 at 9:53 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>
>>>>>>> since Pmode is used in non-PIC tablejump, we have to put 64bit value for
>>>>>>> labels with 0 upper 32bits in tablejump for x32.
>>>>>>
>>>>>> The mode is completely controled by CASE_VECTOR_MODE.
>>>>>>
>>>>>
>>>>> Here is the updated patch.  OK for trunk?
>>>>>
>>>>
>>>> A small change.  It always use 64bit register for indirect branch.
>>>
>>> -         ix86_print_operand (file, x, 0);
>>> +         /* Always use 64bit register for indirect branch.  */
>>> +         ix86_print_operand (file, x,
>>> +                             REG_P (x) && TARGET_64BIT ? 'q' : 0);
>>>          return;
>>>
>>> /* Always use 64bit register for indirect branch.  */
>>> if (REG_P (x) && TARGET_64BIT)
>>>  print_reg (x, 'q', file);
>>> else
>>>  ix86_print_operand (file, x, 0);
>>>
>>>  (define_insn "*indirect_jump"
>>> -  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
>>> +  [(set (pc) (match_operand:P 0 "x32_indirect_branch_operand" "rm"))]
>>>
>>> Just name it "indirect_branch_operand".
>>>
>>>  (define_insn_and_split "*call_vzeroupper"
>>> -  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
>>> +  [(call (mem:QI (match_operand:P 0 "x32_call_insn_operand" "<c>zm"))
>>>
>>> Don't introduce new predicate, change call_insn_operand instead to
>>> conditionally disable memory_operand on x32. You will need to change
>>> "<c>zm" register constraint to "<c>z" on x32, otherwise you will get
>>> ICEs.
>>
>> Use new constraint here, something like (untested):
>>
>> Index: constraints.md
>> ===================================================================
>> --- constraints.md      (revision 176494)
>> +++ constraints.md      (working copy)
>> @@ -127,6 +127,11 @@
>>   "@internal Constant call address operand."
>>   (match_operand 0 "constant_call_address_operand"))
>>
>> +(define_constraint "w"
>> +  "@internal Call memory operand."
>> +  (and (match_test "!TARGET_X32")
>> +       (match_operand 0 "memory_operand"))
>> +
>>  ;; Integer constant constraints.
>>  (define_constraint "I"
>>   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
>>
>> Uros.
>>
>
> Here is the updated patch.  OK for trunk?
>
> Thanks.
>
> --
> H.J.
> -----
> 2011-07-20  H.J. Lu  <hongjiu.lu@intel.com>
>            Uros Bizjak  <ubizjak@gmail.com>
>
>        * config/i386/constraints.md (w): New.
>
>        * config/i386/i386.c (ix86_print_operand): Always use 64bit
>        register for indirect branch.
>        (ix86_output_addr_vec_elt): Check TARGET_LP64 instead of
>        TARGET_64BIT for ASM_QUAD.
>
>        * config/i386/i386.h (CASE_VECTOR_MODE): Check TARGET_LP64
>        instead of TARGET_64BIT.
>
>        * config/i386/i386.md (*indirect_jump): Replace
>        nonimmediate_operand with indirect_branch_operand.
>        (*tablejump_1): Likewise.
>        (*call_vzeroupper): Replace constraint "m" with "w".
>        (*call): Likewise.
>        (*call_rex64_ms_sysv_vzeroupper): Likewise.
>        (*call_rex64_ms_sysv): Likewise.
>        (*call_value_vzeroupper): Likewise.
>        (*call_value): Likewise.
>        (*call_value_rex64_ms_sysv_vzeroupper): Likewise.
>        (*call_value_rex64_ms_sysv): Likewise.
>        (*tablejump_1_x32): New.
>        (set_got_offset_rex64): Check TARGET_LP64 instead of
>        TARGET_64BIT.
>
>        * config/i386/predicates.md (indirect_branch_operand): New.
>        (call_insn_operand): Support x32.
>

+
+(define_insn "*tablejump_1_x32"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+  "TARGET_X32"
+  "jmp\t%A0"
+  [(set_attr "type" "ibr")
+   (set_attr "length_immediate" "0")])

This pattern should include zero_extend from operand 0. Please fix the
tablejump expander to generate correct pattern.

Also, indirect jump needs to generate zero_extend from SImode register for x32.

Other than that, the patch looks OK to me. Please also wait for rth's approval.

Thanks,
Uros.
diff mbox

Patch

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 099c2e1..0b53c76 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -19,7 +19,7 @@ 
 
 ;;; Unused letters:
 ;;;     B     H           T  W
-;;;           h jk          vw
+;;;           h jk          v
 
 ;; Integer register constraints.
 ;; It is not necessary to define 'r' here.
@@ -127,6 +127,11 @@ 
   "@internal Constant call address operand."
   (match_operand 0 "constant_call_address_operand"))
 
+(define_constraint "w"
+  "@internal Call memory operand."
+  (and (match_test "!TARGET_X32")
+       (match_operand 0 "memory_operand")))
+
 ;; Integer constant constraints.
 (define_constraint "I"
   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 814250f..931b066 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13430,7 +13482,11 @@  ix86_print_operand (FILE *file, rtx x, int code)
 	      gcc_unreachable ();
 	    }
 
-	  ix86_print_operand (file, x, 0);
+	  /* Always use 64bit register for indirect branch.  */
+	  if (REG_P (x) && TARGET_64BIT)
+	    print_reg (x, 'q', file);
+	  else
+	    ix86_print_operand (file, x, 0);
 	  return;
 
 
@@ -14852,7 +14908,7 @@  ix86_output_addr_vec_elt (FILE *file, int value)
   const char *directive = ASM_LONG;
 
 #ifdef ASM_QUAD
-  if (TARGET_64BIT)
+  if (TARGET_LP64)
     directive = ASM_QUAD;
 #else
   gcc_assert (!TARGET_64BIT);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 47c1388..20c9a8f 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1674,7 +1674,7 @@  typedef struct ix86_args {
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE \
- (!TARGET_64BIT || (flag_pic && ix86_cmodel != CM_LARGE_PIC) ? SImode : DImode)
+ (!TARGET_LP64 || (flag_pic && ix86_cmodel != CM_LARGE_PIC) ? SImode : DImode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 1
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index cf0fdf4..708cfa5 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10966,7 +10985,7 @@ 
   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))])
 
 (define_insn "*indirect_jump"
-  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
+  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
   ""
   "jmp\t%A0"
   [(set_attr "type" "ibr")
@@ -11011,12 +11030,20 @@ 
 })
 
 (define_insn "*tablejump_1"
-  [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
+  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "jmp\t%A0"
   [(set_attr "type" "ibr")
    (set_attr "length_immediate" "0")])
+
+(define_insn "*tablejump_1_x32"
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+  "TARGET_X32"
+  "jmp\t%A0"
+  [(set_attr "type" "ibr")
+   (set_attr "length_immediate" "0")])
 
 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
 
@@ -11099,7 +11126,7 @@ 
 })
 
 (define_insn_and_split "*call_vzeroupper"
-  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
 	 (match_operand 1 "" ""))
    (unspec [(match_operand 2 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11111,7 +11138,7 @@ 
   [(set_attr "type" "call")])
 
 (define_insn "*call"
-  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
 	 (match_operand 1 "" ""))]
   "!SIBLING_CALL_P (insn)"
   "* return ix86_output_call_insn (insn, operands[0]);"
@@ -11119,7 +11146,7 @@ 
 
 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
   [(parallel
-    [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+    [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
 	   (match_operand 1 "" ""))
      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
      (clobber (reg:TI XMM6_REG))
@@ -11144,7 +11171,7 @@ 
   [(set_attr "type" "call")])
 
 (define_insn "*call_rex64_ms_sysv"
-  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
+  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
 	 (match_operand 1 "" ""))
    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
    (clobber (reg:TI XMM6_REG))
@@ -11275,7 +11302,7 @@ 
 
 (define_insn_and_split "*call_value_vzeroupper"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
 	      (match_operand 2 "" "")))
    (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11288,7 +11315,7 @@ 
 
 (define_insn "*call_value"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
 	      (match_operand 2 "" "")))]
   "!SIBLING_CALL_P (insn)"
   "* return ix86_output_call_insn (insn, operands[1]);"
@@ -11318,7 +11345,7 @@ 
 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
   [(parallel
     [(set (match_operand 0 "" "")
-	  (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+	  (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
 		(match_operand 2 "" "")))
      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
      (clobber (reg:TI XMM6_REG))
@@ -11344,7 +11371,7 @@ 
 
 (define_insn "*call_value_rex64_ms_sysv"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
+	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
 	      (match_operand 2 "" "")))
    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
    (clobber (reg:TI XMM6_REG))
@@ -11666,7 +11693,7 @@ 
 	(unspec:DI
 	  [(label_ref (match_operand 1 "" ""))]
 	  UNSPEC_SET_GOT_OFFSET))]
-  "TARGET_64BIT"
+  "TARGET_LP64"
   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
   [(set_attr "type" "imov")
    (set_attr "length_immediate" "0")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 2c75147..8b87753 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -563,11 +569,18 @@ 
   (ior (match_operand 0 "register_no_elim_operand")
        (match_operand 0 "immediate_operand")))
 
+;; Test for a valid operand for indirect branch.
+(define_predicate "indirect_branch_operand"
+  (if_then_else (match_test "TARGET_X32")
+    (match_operand 0 "register_operand")
+    (match_operand 0 "nonimmediate_operand")))
+
 ;; Test for a valid operand for a call instruction.
 (define_predicate "call_insn_operand"
   (ior (match_operand 0 "constant_call_address_operand")
        (match_operand 0 "call_register_no_elim_operand")
-       (match_operand 0 "memory_operand")))
+       (and (match_test "!TARGET_X32")
+	    (match_operand 0 "memory_operand"))))
 
 ;; Similarly, but for tail calls, in which we cannot allow memory references.
 (define_predicate "sibcall_insn_operand"