OSDN Git Service

* config/i386/i386.md (*divmod<mode>4): Remove stray "&&" from
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
index d142c7f..3f29325 100644 (file)
   DONE;
 })
 
-(define_insn "*bt<mode>"
+(define_insn "*btdi_rex64"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
-         (zero_extract:SWI48
-           (match_operand:SWI48 0 "register_operand" "r")
+         (zero_extract:DI
+           (match_operand:DI 0 "register_operand" "r")
            (const_int 1)
-           (match_operand:SWI48 1 "nonmemory_operand" "rN"))
+           (match_operand:DI 1 "nonmemory_operand" "rN"))
+         (const_int 0)))]
+  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
+  "bt{q}\t{%1, %0|%0, %1}"
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
+
+(define_insn "*btsi"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:SI
+           (match_operand:SI 0 "register_operand" "r")
+           (const_int 1)
+           (match_operand:SI 1 "nonmemory_operand" "rN"))
          (const_int 0)))]
   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
-  "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
+  "bt{l}\t{%1, %0|%0, %1}"
   [(set_attr "type" "alu1")
    (set_attr "prefix_0f" "1")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "SI")])
 \f
 ;; Store-flag instructions.
 
     FAIL;
 })
 
-;; zero_extend in SImode is correct also for DImode, since this is what combine
-;; pass generates from shift insn with QImode operand.  Actually, the mode
-;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
+;; zero_extend in SImode is correct, since this is what combine pass
+;; generates from shift insn with QImode operand.  Actually, the mode of
+;; operand 2 (bit offset operand) doesn't matter since bt insn takes
 ;; appropriate modulo of the bit offset value.
 
-(define_insn_and_split "*jcc_bt<mode>"
+(define_insn_and_split "*jcc_btdi_rex64"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"
-                       [(zero_extract:SWI48
-                          (match_operand:SWI48 1 "register_operand" "r")
+                       [(zero_extract:DI
+                          (match_operand:DI 1 "register_operand" "r")
                           (const_int 1)
                           (zero_extend:SI
                             (match_operand:QI 2 "register_operand" "r")))
                      (label_ref (match_operand 3 "" ""))
                      (pc)))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
+  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
   "#"
   "&& 1"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
-         (zero_extract:SWI48
+         (zero_extract:DI
            (match_dup 1)
            (const_int 1)
            (match_dup 2))
                      (label_ref (match_dup 3))
                      (pc)))]
 {
-  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
+  operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
 
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
-;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
-;; also for DImode, this is what combine produces.
-define_insn_and_split "*jcc_bt<mode>_mask"
+;; avoid useless masking of bit offset operand
+(define_insn_and_split "*jcc_btdi_mask_rex64"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"
-                       [(zero_extract:SWI48
-                          (match_operand:SWI48 1 "register_operand" "r")
+                       [(zero_extract:DI
+                          (match_operand:DI 1 "register_operand" "r")
                           (const_int 1)
                           (and:SI
                             (match_operand:SI 2 "register_operand" "r")
@@ -11285,14 +11298,13 @@ define_insn_and_split "*jcc_bt<mode>_mask"
                      (label_ref (match_operand 4 "" ""))
                      (pc)))
    (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
-   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1"
+  "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
+   && (INTVAL (operands[3]) & 0x3f) == 0x3f"
   "#"
   "&& 1"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
-         (zero_extract:SWI48
+         (zero_extract:DI
            (match_dup 1)
            (const_int 1)
            (match_dup 2))
@@ -11302,11 +11314,73 @@ define_insn_and_split "*jcc_bt<mode>_mask"
                      (label_ref (match_dup 4))
                      (pc)))]
 {
-  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
+  operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
+
+  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
+})
+
+(define_insn_and_split "*jcc_btsi"
+  [(set (pc)
+       (if_then_else (match_operator 0 "bt_comparison_operator"
+                       [(zero_extract:SI
+                          (match_operand:SI 1 "register_operand" "r")
+                          (const_int 1)
+                          (zero_extend:SI
+                            (match_operand:QI 2 "register_operand" "r")))
+                        (const_int 0)])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:SI
+           (match_dup 1)
+           (const_int 1)
+           (match_dup 2))
+         (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+                     (label_ref (match_dup 3))
+                     (pc)))]
+{
+  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
 
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
+;; avoid useless masking of bit offset operand
+(define_insn_and_split "*jcc_btsi_mask"
+  [(set (pc)
+       (if_then_else (match_operator 0 "bt_comparison_operator"
+                       [(zero_extract:SI
+                          (match_operand:SI 1 "register_operand" "r")
+                          (const_int 1)
+                          (and:SI
+                            (match_operand:SI 2 "register_operand" "r")
+                            (match_operand:SI 3 "const_int_operand" "n")))])
+                     (label_ref (match_operand 4 "" ""))
+                     (pc)))
+   (clobber (reg:CC FLAGS_REG))]
+  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
+   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:SI
+           (match_dup 1)
+           (const_int 1)
+           (match_dup 2))
+         (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+                     (label_ref (match_dup 4))
+                     (pc)))]
+  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
+
 (define_insn_and_split "*jcc_btsi_1"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"