i386.h (ix86_tune_indices): New.
authorUros Bizjak <ubizjak@gmail.com>
Thu, 19 Jun 2008 16:39:35 +0000 (18:39 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Thu, 19 Jun 2008 16:39:35 +0000 (18:39 +0200)
* config/i386/i386.h (ix86_tune_indices)
[X86_TUNE_FUSE_CMP_AND_BRANCH]: New.
(TARGET_FUSE_CMP_AND_BRANCH): New define.
* config/i386/i386.md (*jcc_fused_1): New insn pattern
(*jcc_fused_2): Ditto.
* config/i386/i386.c (ix86_tune_features): Add m_CORE2 to
X86_TUNE_USE_VECTOR_COMPARES targets.
(print operand): Handle 'E' and 'e' code.

From-SVN: r136954

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

index bde2b027f60110a3aa9df395847482dbc9d4b672..50bb34bdddc4b4c0103e388a33d14f6ca16c1e51 100644 (file)
@@ -1,3 +1,14 @@
+2008-06-19  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.h (ix86_tune_indices)
+       [X86_TUNE_FUSE_CMP_AND_BRANCH]: New.
+       (TARGET_FUSE_CMP_AND_BRANCH): New define.
+       * config/i386/i386.md (*jcc_fused_1): New insn pattern
+       (*jcc_fused_2): Ditto.
+       * config/i386/i386.c (ix86_tune_features): Add m_CORE2 to
+       X86_TUNE_USE_VECTOR_COMPARES targets.
+       (print operand): Handle 'E' and 'e' code.
+
 2008-06-19  Anatoly Sokolov  <aesok@post.ru>
 
        * config/avr/avr.c (avr_mcu_t): Add attiny13a.
index d7a07136791e3431a9c0f06810800de8dab2872f..5ebb31c22d0e53e0425bb5670b2df2fbac8cabba 100644 (file)
@@ -1435,6 +1435,11 @@ unsigned int ix86_tune_features[X86_TUNE_LAST] = {
   /* X86_TUNE_USE_VECTOR_CONVERTS: Prefer vector packed SSE conversion
      from integer to FP. */
   m_AMDFAM10,
+
+  /* X86_TUNE_FUSE_CMP_AND_BRANCH: Fuse a compare or test instruction
+     with a subsequent conditional jump instruction into a single
+     compare-and-branch uop.  */
+  m_CORE2,
 };
 
 /* Feature tests against the various architecture variations.  */
@@ -9020,6 +9025,7 @@ get_some_local_dynamic_name (void)
    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
    C -- print opcode suffix for set/cmov insn.
    c -- like C, but print reversed condition
+   E,e -- likewise, but for compare-and-branch fused insn.
    F,f -- likewise, but for floating-point.
    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
         otherwise nothing
@@ -9292,6 +9298,14 @@ print_operand (FILE *file, rtx x, int code)
          put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
          return;
 
+       case 'E':
+         put_condition_code (GET_CODE (x), CCmode, 0, 0, file);
+         return;
+
+       case 'e':
+         put_condition_code (GET_CODE (x), CCmode, 1, 0, file);
+         return;
+
        case 'H':
          /* It doesn't actually matter what mode we use here, as we're
             only going to use this for printing.  */
index 4c65b10d4f99549f5e736ab6c172f05400e9ef3d..b011885424a8699288499f2344625340ed070cb4 100644 (file)
@@ -281,6 +281,7 @@ enum ix86_tune_indices {
   X86_TUNE_NOT_UNPAIRABLE,
   X86_TUNE_NOT_VECTORMODE,
   X86_TUNE_USE_VECTOR_CONVERTS,
+  X86_TUNE_FUSE_CMP_AND_BRANCH,
 
   X86_TUNE_LAST
 };
@@ -363,7 +364,10 @@ extern unsigned int ix86_tune_features[X86_TUNE_LAST];
 #define        TARGET_MOVE_M1_VIA_OR   ix86_tune_features[X86_TUNE_MOVE_M1_VIA_OR]
 #define TARGET_NOT_UNPAIRABLE  ix86_tune_features[X86_TUNE_NOT_UNPAIRABLE]
 #define TARGET_NOT_VECTORMODE  ix86_tune_features[X86_TUNE_NOT_VECTORMODE]
-#define TARGET_USE_VECTOR_CONVERTS ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS]
+#define TARGET_USE_VECTOR_CONVERTS \
+       ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS]
+#define TARGET_FUSE_CMP_AND_BRANCH \
+       ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH]
 
 /* Feature tests against the various architecture variations.  */
 enum ix86_arch_indices {
index ca01494871f22450e3ca5f5dc5e8417dfc6a352e..48c8a326c578eb78b55397e4f50455bb112aac4d 100644 (file)
             (const_int 2)
             (const_int 6)))])
 
+;; ??? Handle alignment requirements for compare and branch fused macro-op;
+;; the branch instruction does not start at a 16-byte boundary or cross
+;; a 16-byte boundary.
+
+(define_insn "*jcc_fused_1"
+  [(set (pc)
+       (if_then_else (match_operator 1 "ix86_comparison_uns_operator"
+                       [(match_operand:SI 2 "nonimmediate_operand" "r,m,r")
+                        (match_operand:SI 3 "general_operand" "ri,r,m")])
+        (label_ref (match_operand 0 "" ""))
+        (pc)))]
+  "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
+   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
+{
+  if (REG_P (operands[2])
+      && operands[3] == CONST0_RTX (GET_MODE (operands[3])))
+    output_asm_insn ("test{l}\t%2, %2", operands);
+  else
+    output_asm_insn ("cmp{l}\t{%3, %2|%2, %3}",operands);
+
+  return "%+j%E1\t%l0\t# fused";
+}
+  [(set_attr "type" "multi")
+   (set_attr "mode" "SI")])
+
+(define_insn "*jcc_fused_2"
+  [(set (pc)
+       (if_then_else (match_operator 1 "ix86_comparison_uns_operator"
+                       [(match_operand:SI 2 "nonimmediate_operand" "r,m,r")
+                        (match_operand:SI 3 "general_operand" "ri,r,m")])
+        (pc)
+        (label_ref (match_operand 0 "" ""))))]
+  "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
+   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
+{
+  if (REG_P (operands[2])
+      && operands[3] == CONST0_RTX (GET_MODE (operands[3])))
+    output_asm_insn ("test{l}\t%2, %2", operands);
+  else
+    output_asm_insn ("cmp{l}\t{%3, %2|%2, %3}",operands);
+
+  return "%+j%e1\t%l0\t# fused";
+}
+  [(set_attr "type" "multi")
+   (set_attr "mode" "SI")])
+
 ;; In general it is not safe to assume too much about CCmode registers,
 ;; so simplify-rtx stops when it sees a second one.  Under certain
 ;; conditions this is safe on x86, so help combine not create