From 354f84af675670fe3ee6e6a92a8155fdf54feacf Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 19 Jun 2008 18:39:35 +0200 Subject: [PATCH] i386.h (ix86_tune_indices): New. * 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 | 11 ++++++++++ gcc/config/i386/i386.c | 14 +++++++++++++ gcc/config/i386/i386.h | 6 +++++- gcc/config/i386/i386.md | 46 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bde2b027f60..50bb34bdddc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-06-19 Uros Bizjak + + * 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 * config/avr/avr.c (avr_mcu_t): Add attiny13a. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d7a07136791..5ebb31c22d0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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. */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 4c65b10d4f9..b011885424a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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 { diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ca01494871f..48c8a326c57 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14032,6 +14032,52 @@ (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 -- 2.30.2