On Fri, Mar 30, 2012 at 8:19 AM, Richard Henderson <r...@redhat.com> wrote:
> On 03/30/2012 11:11 AM, Richard Henderson wrote:
>> On 03/30/2012 11:03 AM, Teresa Johnson wrote:
>>> +(define_insn "*movhi_imm_internal"
>>> +  [(set (match_operand:HI 0 "memory_operand" "=m")
>>> +        (match_operand:HI 1 "immediate_operand" "n"))]
>>> +  "!TARGET_LCP_STALL"
>>> +{
>>> +  return "mov{w}\t{%1, %0|%0, %1}";
>>> +}
>>> +  [(set (attr "type") (const_string "imov"))
>>> +   (set (attr "mode") (const_string "HI"))])
>>> +
>>>  (define_insn "*movhi_internal"
>>>    [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
>>> -    (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
>>> +    (match_operand:HI 1 "general_operand" "r,rn,rm,r"))]
>>>    "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
>>
>> For reload to work correctly, all alternatives must remain part of the same 
>> pattern.
>> This issue should be handled with the ISA and ENABLED attributes.
>
> I'll also ask if this should better be handled with a peephole2.
>
> While movw $1234,(%eax) might be expensive, is it so expensive that we
> *must* force the use of a free register?  Might it be better only to
> split the insn in two if and only if a free register exists?
>
> That can easily be done with a peephole2 pattern...
>

Here is a very old LCP patch with peephole2.  It may need some
updates.


-- 
H.J.
--- gcc/config/i386/i386-tune.c.movw	2007-08-06 07:58:38.000000000 -0700
+++ gcc/config/i386/i386-tune.c	2007-08-06 07:58:38.000000000 -0700
@@ -117,6 +117,9 @@ x86_tune_options (void)
 	    abort ();
 	}
     }
+
+  if (x86_split_movw_length_string)
+    x86_split_movw_length = atoi (x86_split_movw_length_string);
 }
 
 #undef TARGET_SCHED_ISSUE_RATE
@@ -137,3 +140,4 @@ const char *ix86_adjust_cost_string;
 int ia32_multipass_dfa_lookahead_value;
 const char *ia32_multipass_dfa_lookahead_string;
 
+int x86_split_movw_length;
--- gcc/config/i386/i386-tune.h.movw	2007-08-06 07:58:38.000000000 -0700
+++ gcc/config/i386/i386-tune.h	2007-08-06 07:58:38.000000000 -0700
@@ -4,6 +4,9 @@
 
    -mno-default
 
+   -msplit-movw-length=NUMBER
+      NUMBER is the maximum 16bit immediate move instruction length
+
    -missue-rate=NUMBER
 
    -madjust-cost=NUMBER
@@ -72,6 +75,7 @@
 
 extern void x86_tune_options (void);
 
+extern int x86_split_movw_length;
 
 extern int ix86_issue_rate_value;
 extern const char *ix86_issue_rate_string;
--- gcc/config/i386/i386-tune.opt.movw	2007-08-06 07:58:38.000000000 -0700
+++ gcc/config/i386/i386-tune.opt	2007-08-06 07:58:38.000000000 -0700
@@ -363,3 +363,6 @@ Target RejectNegative Joined Report Var(
 mno-default
 Target RejectNegative Report Var(x86_no_default_string) Undocumented
 
+msplit-movw-length=
+Target RejectNegative Joined Report Var(x86_split_movw_length_string) Undocumented
+
--- gcc/config/i386/i386.md.movw	2007-08-06 07:55:01.000000000 -0700
+++ gcc/config/i386/i386.md	2007-08-06 08:50:48.000000000 -0700
@@ -19655,14 +19655,18 @@
    (set (match_dup 0) (match_dup 1))]
   "")
 
+;; Also don't move a 16bit immediate directly to memory when target
+;; has slow LCP instructions.
 (define_peephole2
   [(match_scratch:HI 1 "r")
    (set (match_operand:HI 0 "memory_operand" "")
         (const_int 0))]
   "optimize_insn_for_speed_p ()
-   && ! TARGET_USE_MOV0
-   && TARGET_SPLIT_LONG_MOVES
-   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
+   && ((x86_split_movw_length_string != NULL
+	&& get_attr_length (insn) >= x86_split_movw_length)
+       || (! TARGET_USE_MOV0
+	   && TARGET_SPLIT_LONG_MOVES
+	   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
    && peep2_regno_dead_p (0, FLAGS_REG)"
   [(parallel [(set (match_dup 2) (const_int 0))
 	      (clobber (reg:CC FLAGS_REG))])
@@ -19694,13 +19698,17 @@
    (set (match_dup 0) (match_dup 2))]
   "")
 
+;; Also don't move a 16bit immediate directly to memory when target
+;; has slow LCP instructions.
 (define_peephole2
   [(match_scratch:HI 2 "r")
    (set (match_operand:HI 0 "memory_operand" "")
         (match_operand:HI 1 "immediate_operand" ""))]
   "optimize_insn_for_speed_p ()
-   && TARGET_SPLIT_LONG_MOVES
-   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
+   && ((x86_split_movw_length_string != NULL
+	&& get_attr_length (insn) >= x86_split_movw_length)
+       || (TARGET_SPLIT_LONG_MOVES
+	   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
   [(set (match_dup 2) (match_dup 1))
    (set (match_dup 0) (match_dup 2))]
   "")

Reply via email to