Handle address output and call patterns for x32.
authorH.J. Lu <hongjiu.lu@intel.com>
Wed, 20 Jul 2011 22:38:47 +0000 (22:38 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 20 Jul 2011 22:38:47 +0000 (15:38 -0700)
2011-07-20  H.J. Lu  <hongjiu.lu@intel.com>
    Uros Bizjak  <ubizjak@gmail.com>
    Richard Henderson  <rth@redhat.com>

* config/i386/constraints.md (w): New.

* config/i386/i386.c (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.
(*indirect_jump): Likewise.  Replace constraint "m" with "w".
(tablejump): Replace nonimmediate_operand with
indirect_branch_operand.  Convert operand 0 to Pmode for x32 if
not PIC.
(*tablejump_1): Replace nonimmediate_operand with
indirect_branch_operand.  Replace constraint "m" with "w".
(*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.
(set_got_offset_rex64): Check TARGET_LP64 instead of
TARGET_64BIT.

* config/i386/predicates.md (indirect_branch_operand): New.
(call_insn_operand): Support x32.

Co-Authored-By: Richard Henderson <rth@redhat.com>
Co-Authored-By: Uros Bizjak <ubizjak@gmail.com>
From-SVN: r176539

gcc/ChangeLog
gcc/config/i386/constraints.md
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 55db01c..6d2b417 100644 (file)
@@ -1,3 +1,37 @@
+2011-07-20  H.J. Lu  <hongjiu.lu@intel.com>
+           Uros Bizjak  <ubizjak@gmail.com>
+           Richard Henderson  <rth@redhat.com>
+
+       * config/i386/constraints.md (w): New.
+
+       * config/i386/i386.c (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.
+       (*indirect_jump): Likewise.  Replace constraint "m" with "w".
+       (tablejump): Replace nonimmediate_operand with
+       indirect_branch_operand.  Convert operand 0 to Pmode for x32 if
+       not PIC.
+       (*tablejump_1): Replace nonimmediate_operand with
+       indirect_branch_operand.  Replace constraint "m" with "w".
+       (*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.
+       (set_got_offset_rex64): Check TARGET_LP64 instead of
+       TARGET_64BIT.
+
+       * config/i386/predicates.md (indirect_branch_operand): New.
+       (call_insn_operand): Support x32.
+
 2011-07-20  Michael Eager  <eager@eagercon.com>
 
        * params.def (PARAM_MAX_VARTRACK_EXPR_DEPTH): Default to 12.
index 099c2e1..8d3e45a 100644 (file)
@@ -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.
   "@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."
index fbebd4c..403f312 100644 (file)
@@ -14865,7 +14865,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);
index 47c1388..20c9a8f 100644 (file)
@@ -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
index cf0fdf4..b704fa7 100644 (file)
    (set_attr "modrm" "0")])
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand 0 "nonimmediate_operand" ""))])
+  [(set (pc) (match_operand 0 "indirect_branch_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")
    (set_attr "length_immediate" "0")])
 
 (define_expand "tablejump"
-  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
+  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
              (use (label_ref (match_operand 1 "" "")))])]
   ""
 {
       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
                                         OPTAB_DIRECT);
     }
+  else if (TARGET_X32)
+    operands[0] = convert_memory_address (Pmode, operands[0]);
 })
 
 (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"
 })
 
 (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)]
   [(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]);"
 
 (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))
   [(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))
 
 (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)]
 
 (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]);"
 (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))
 
 (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))
        (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")
index fd93505..2ef9129 100644 (file)
   (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"