yann@552: Original patch from gentoo: gentoo/src/patchsets/gcc/4.3.0/gentoo/20_all_gcc-x86-emit-cld.patch yann@552: bandaid for the cld issue. to be dropped when gcc-4.3 goes stable. yann@552: yann@552: http://gcc.gnu.org/ml/gcc-patches/2008-03/msg00417.html yann@552: yann@552: 2008-03-06 Uros Bizjak yann@552: yann@552: * config/i386/i386.h (TARGET_CLD): New define. yann@552: (struct machine_function): Add needs_cld field. yann@552: (ix86_current_function_needs_cld): New define. yann@552: * config/i386/i386.md (UNSPEC_CLD): New unspec volatile constant. yann@552: ("cld"): New isns pattern. yann@552: ("strmov_singleop"): Set ix86_current_function_needs_cld flag. yann@552: ("rep_mov"): Ditto. yann@552: ("strset_singleop"): Ditto. yann@552: ("rep_stos"): Ditto. yann@552: ("cmpstrnqi_nz_1"): Ditto. yann@552: ("cmpstrnqi_1"): Ditto. yann@552: ("strlenqi_1"): Ditto. yann@552: * config/i386/i386.c (ix86_expand_prologue): Emit cld insn for yann@552: TARGET_CLD when ix86_current_function_needs_cld is set. yann@552: yann@552: diff -durN gcc-4.3.0.orig/gcc/config/i386/i386.c gcc-4.3.0/gcc/config/i386/i386.c yann@552: --- gcc-4.3.0.orig/gcc/config/i386/i386.c 2008-02-21 13:30:00.000000000 +0100 yann@552: +++ gcc-4.3.0/gcc/config/i386/i386.c 2008-06-10 14:44:37.000000000 +0200 yann@552: @@ -6448,6 +6448,10 @@ yann@552: emit_insn (gen_prologue_use (pic_offset_table_rtx)); yann@552: emit_insn (gen_blockage ()); yann@552: } yann@552: + yann@552: + /* Emit cld instruction if stringops are used in the function. */ yann@552: + if (TARGET_CLD && ix86_current_function_needs_cld) yann@552: + emit_insn (gen_cld ()); yann@552: } yann@552: yann@552: /* Emit code to restore saved registers using MOV insns. First register yann@552: diff -durN gcc-4.3.0.orig/gcc/config/i386/i386.h gcc-4.3.0/gcc/config/i386/i386.h yann@552: --- gcc-4.3.0.orig/gcc/config/i386/i386.h 2008-02-15 09:12:02.000000000 +0100 yann@552: +++ gcc-4.3.0/gcc/config/i386/i386.h 2008-06-10 14:44:37.000000000 +0200 yann@552: @@ -388,6 +388,7 @@ yann@552: yann@552: extern int x86_prefetch_sse; yann@552: yann@552: +#define TARGET_CLD 1 yann@552: #define TARGET_ABM x86_abm yann@552: #define TARGET_CMPXCHG16B x86_cmpxchg16b yann@552: #define TARGET_POPCNT x86_popcnt yann@552: @@ -2443,8 +2444,9 @@ yann@552: int save_varrargs_registers; yann@552: int accesses_prev_frame; yann@552: int optimize_mode_switching[MAX_386_ENTITIES]; yann@552: - /* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to yann@552: - determine the style used. */ yann@552: + int needs_cld; yann@552: + /* Set by ix86_compute_frame_layout and used by prologue/epilogue yann@552: + expander to determine the style used. */ yann@552: int use_fast_prologue_epilogue; yann@552: /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE has been computed yann@552: for. */ yann@552: @@ -2464,6 +2466,7 @@ yann@552: #define ix86_stack_locals (cfun->machine->stack_locals) yann@552: #define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers) yann@552: #define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching) yann@552: +#define ix86_current_function_needs_cld (cfun->machine->needs_cld) yann@552: #define ix86_tls_descriptor_calls_expanded_in_cfun \ yann@552: (cfun->machine->tls_descriptor_call_expanded_p) yann@552: /* Since tls_descriptor_call_expanded is not cleared, even if all TLS yann@552: diff -durN gcc-4.3.0.orig/gcc/config/i386/i386.md gcc-4.3.0/gcc/config/i386/i386.md yann@552: --- gcc-4.3.0.orig/gcc/config/i386/i386.md 2008-02-06 12:34:00.000000000 +0100 yann@552: +++ gcc-4.3.0/gcc/config/i386/i386.md 2008-06-10 14:44:37.000000000 +0200 yann@552: @@ -205,6 +205,7 @@ yann@552: (UNSPECV_XCHG 12) yann@552: (UNSPECV_LOCK 13) yann@552: (UNSPECV_PROLOGUE_USE 14) yann@552: + (UNSPECV_CLD 15) yann@552: ]) yann@552: yann@552: ;; Constants to represent pcomtrue/pcomfalse variants yann@552: @@ -18529,6 +18530,14 @@ yann@552: yann@552: ;; Block operation instructions yann@552: yann@552: +(define_insn "cld" yann@552: + [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] yann@552: + "" yann@552: + "cld" yann@552: + [(set_attr "length" "1") yann@552: + (set_attr "length_immediate" "0") yann@552: + (set_attr "modrm" "0")]) yann@552: + yann@552: (define_expand "movmemsi" yann@552: [(use (match_operand:BLK 0 "memory_operand" "")) yann@552: (use (match_operand:BLK 1 "memory_operand" "")) yann@552: @@ -18601,7 +18610,7 @@ yann@552: (set (match_operand 2 "register_operand" "") yann@552: (match_operand 5 "" ""))])] yann@552: "TARGET_SINGLE_STRINGOP || optimize_size" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*strmovdi_rex_1" yann@552: [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) yann@552: @@ -18718,7 +18727,7 @@ yann@552: (match_operand 3 "memory_operand" "")) yann@552: (use (match_dup 4))])] yann@552: "" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*rep_movdi_rex64" yann@552: [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) yann@552: @@ -18878,7 +18887,7 @@ yann@552: (set (match_operand 0 "register_operand" "") yann@552: (match_operand 3 "" ""))])] yann@552: "TARGET_SINGLE_STRINGOP || optimize_size" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*strsetdi_rex_1" yann@552: [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) yann@552: @@ -18972,7 +18981,7 @@ yann@552: (use (match_operand 3 "register_operand" "")) yann@552: (use (match_dup 1))])] yann@552: "" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*rep_stosdi_rex64" yann@552: [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) yann@552: @@ -19148,7 +19157,7 @@ yann@552: (clobber (match_operand 1 "register_operand" "")) yann@552: (clobber (match_dup 2))])] yann@552: "" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*cmpstrnqi_nz_1" yann@552: [(set (reg:CC FLAGS_REG) yann@552: @@ -19195,7 +19204,7 @@ yann@552: (clobber (match_operand 1 "register_operand" "")) yann@552: (clobber (match_dup 2))])] yann@552: "" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*cmpstrnqi_1" yann@552: [(set (reg:CC FLAGS_REG) yann@552: @@ -19264,7 +19273,7 @@ yann@552: (clobber (match_operand 1 "register_operand" "")) yann@552: (clobber (reg:CC FLAGS_REG))])] yann@552: "" yann@552: - "") yann@552: + "ix86_current_function_needs_cld = 1;") yann@552: yann@552: (define_insn "*strlenqi_1" yann@552: [(set (match_operand:SI 0 "register_operand" "=&c")