1;; -----------------------------------------------------------------
2;; PEEPHOLE PATTERNS
3;; -----------------------------------------------------------------
4
5;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
6
7(define_peephole2
8  [(parallel [(set (match_operand:HI 0 "register_operand" "")
9		   (lshiftrt:HI (match_dup 0)
10				(match_operand:HI 1 "const_int_operand" "")))
11	      (clobber (match_operand:HI 2 "" ""))])
12   (set (match_dup 0)
13	(and:HI (match_dup 0)
14		(match_operand:HI 3 "const_int_operand" "")))]
15  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
16  [(set (match_dup 0)
17	(and:HI (match_dup 0)
18		(const_int 255)))
19   (parallel [(set (match_dup 0)
20		   (lshiftrt:HI (match_dup 0) (match_dup 1)))
21	      (clobber (match_dup 2))])]
22  "")
23
24;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
25
26(define_peephole2
27  [(parallel [(set (match_operand:HI 0 "register_operand" "")
28		   (ashift:HI (match_dup 0)
29			      (match_operand:HI 1 "const_int_operand" "")))
30	      (clobber (match_operand:HI 2 "" ""))])
31   (set (match_dup 0)
32	(and:HI (match_dup 0)
33		(match_operand:HI 3 "const_int_operand" "")))]
34  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
35  [(set (match_dup 0)
36	(and:HI (match_dup 0)
37		(const_int 255)))
38   (parallel [(set (match_dup 0)
39		   (ashift:HI (match_dup 0) (match_dup 1)))
40	      (clobber (match_dup 2))])]
41  "")
42
43;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
44
45(define_peephole2
46  [(parallel [(set (match_operand:SI 0 "register_operand" "")
47		   (lshiftrt:SI (match_dup 0)
48				(match_operand:SI 1 "const_int_operand" "")))
49	      (clobber (match_operand:SI 2 "" ""))])
50   (set (match_dup 0)
51	(and:SI (match_dup 0)
52		(match_operand:SI 3 "const_int_operand" "")))]
53  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
54  [(set (match_dup 0)
55	(and:SI (match_dup 0)
56		(const_int 255)))
57   (parallel [(set (match_dup 0)
58		   (lshiftrt:SI (match_dup 0) (match_dup 1)))
59	      (clobber (match_dup 2))])]
60  "")
61
62;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
63
64(define_peephole2
65  [(parallel [(set (match_operand:SI 0 "register_operand" "")
66		   (ashift:SI (match_dup 0)
67			      (match_operand:SI 1 "const_int_operand" "")))
68	      (clobber (match_operand:SI 2 "" ""))])
69   (set (match_dup 0)
70	(and:SI (match_dup 0)
71		(match_operand:SI 3 "const_int_operand" "")))]
72  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
73  [(set (match_dup 0)
74	(and:SI (match_dup 0)
75		(const_int 255)))
76   (parallel [(set (match_dup 0)
77		   (ashift:SI (match_dup 0) (match_dup 1)))
78	      (clobber (match_dup 2))])]
79  "")
80
81;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
82
83(define_peephole2
84  [(parallel [(set (match_operand:SI 0 "register_operand" "")
85		   (lshiftrt:SI (match_dup 0)
86				(match_operand:SI 1 "const_int_operand" "")))
87	      (clobber (match_operand:SI 2 "" ""))])
88   (set (match_dup 0)
89	(and:SI (match_dup 0)
90		(match_operand:SI 3 "const_int_operand" "")))]
91  "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
92  [(set (match_dup 0)
93	(and:SI (match_dup 0)
94		(const_int 65535)))
95   (parallel [(set (match_dup 0)
96		   (lshiftrt:SI (match_dup 0) (match_dup 1)))
97	      (clobber (match_dup 2))])]
98  "")
99
100;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
101
102(define_peephole2
103  [(parallel [(set (match_operand:SI 0 "register_operand" "")
104		   (ashift:SI (match_dup 0)
105			      (match_operand:SI 1 "const_int_operand" "")))
106	      (clobber (match_operand:SI 2 "" ""))])
107   (set (match_dup 0)
108	(and:SI (match_dup 0)
109		(match_operand:SI 3 "const_int_operand" "")))]
110  "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
111  [(set (match_dup 0)
112	(and:SI (match_dup 0)
113		(const_int 65535)))
114   (parallel [(set (match_dup 0)
115		   (ashift:SI (match_dup 0) (match_dup 1)))
116	      (clobber (match_dup 2))])]
117  "")
118
119;; Cram four pushes into stm.l.
120
121(define_peephole2
122  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
123	(match_operand:SI 0 "register_operand" ""))
124   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
125	(match_operand:SI 1 "register_operand" ""))
126   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
127	(match_operand:SI 2 "register_operand" ""))
128   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
129	(match_operand:SI 3 "register_operand" ""))]
130  "TARGET_H8300S && !TARGET_NORMAL_MODE
131   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
132       && REGNO (operands[1]) == REGNO (operands[0]) + 1
133       && REGNO (operands[2]) == REGNO (operands[0]) + 2
134       && REGNO (operands[3]) == REGNO (operands[0]) + 3
135       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
136  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
137		   (match_dup 0))
138	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
139		   (match_dup 1))
140	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
141		   (match_dup 2))
142	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
143		   (match_dup 3))
144	      (set (reg:SI SP_REG)
145		   (plus:SI (reg:SI SP_REG)
146			    (const_int -16)))])]
147  "")
148
149(define_peephole2
150  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
151	(match_operand:SI 0 "register_operand" ""))
152   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
153	(match_operand:SI 1 "register_operand" ""))
154   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
155	(match_operand:SI 2 "register_operand" ""))
156   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
157	(match_operand:SI 3 "register_operand" ""))]
158  "TARGET_H8300S && TARGET_NORMAL_MODE
159   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
160       && REGNO (operands[1]) == REGNO (operands[0]) + 1
161       && REGNO (operands[2]) == REGNO (operands[0]) + 2
162       && REGNO (operands[3]) == REGNO (operands[0]) + 3
163       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
164  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
165		   (match_dup 0))
166	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
167		   (match_dup 1))
168	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
169		   (match_dup 2))
170	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
171		   (match_dup 3))
172	      (set (reg:HI SP_REG)
173		   (plus:HI (reg:HI SP_REG)
174			    (const_int -16)))])]
175  "")
176
177;; Cram three pushes into stm.l.
178
179(define_peephole2
180  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
181	(match_operand:SI 0 "register_operand" ""))
182   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
183	(match_operand:SI 1 "register_operand" ""))
184   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
185	(match_operand:SI 2 "register_operand" ""))]
186  "TARGET_H8300S && !TARGET_NORMAL_MODE
187   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
188       && REGNO (operands[1]) == REGNO (operands[0]) + 1
189       && REGNO (operands[2]) == REGNO (operands[0]) + 2
190       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
191  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
192		   (match_dup 0))
193	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
194		   (match_dup 1))
195	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
196		   (match_dup 2))
197	      (set (reg:SI SP_REG)
198		   (plus:SI (reg:SI SP_REG)
199			    (const_int -12)))])]
200  "")
201
202(define_peephole2
203  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
204	(match_operand:SI 0 "register_operand" ""))
205   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
206	(match_operand:SI 1 "register_operand" ""))
207   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
208	(match_operand:SI 2 "register_operand" ""))]
209  "TARGET_H8300S && TARGET_NORMAL_MODE
210   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
211       && REGNO (operands[1]) == REGNO (operands[0]) + 1
212       && REGNO (operands[2]) == REGNO (operands[0]) + 2
213       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
214  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
215		   (match_dup 0))
216	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
217		   (match_dup 1))
218	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
219		   (match_dup 2))
220	      (set (reg:HI SP_REG)
221		   (plus:HI (reg:HI SP_REG)
222			    (const_int -12)))])]
223  "")
224
225;; Cram two pushes into stm.l.
226
227(define_peephole2
228  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
229	(match_operand:SI 0 "register_operand" ""))
230   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
231	(match_operand:SI 1 "register_operand" ""))]
232  "TARGET_H8300S && !TARGET_NORMAL_MODE
233   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
234       && REGNO (operands[1]) == REGNO (operands[0]) + 1
235       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
236  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
237		   (match_dup 0))
238	      (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
239		   (match_dup 1))
240	      (set (reg:SI SP_REG)
241		   (plus:SI (reg:SI SP_REG)
242			    (const_int -8)))])]
243  "")
244
245(define_peephole2
246  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
247	(match_operand:SI 0 "register_operand" ""))
248   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
249	(match_operand:SI 1 "register_operand" ""))]
250  "TARGET_H8300S && TARGET_NORMAL_MODE
251   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
252       && REGNO (operands[1]) == REGNO (operands[0]) + 1
253       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
254  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
255		   (match_dup 0))
256	      (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
257		   (match_dup 1))
258	      (set (reg:HI SP_REG)
259		   (plus:HI (reg:HI SP_REG)
260			    (const_int -8)))])]
261  "")
262
263;; Turn
264;;
265;;   mov.w #2,r0
266;;   add.w r7,r0  (6 bytes)
267;;
268;; into
269;;
270;;   mov.w r7,r0
271;;   adds  #2,r0  (4 bytes)
272
273(define_peephole2
274  [(set (match_operand:HI 0 "register_operand" "")
275	(match_operand:HI 1 "const_int_operand" ""))
276   (set (match_dup 0)
277	(plus:HI (match_dup 0)
278		 (match_operand:HI 2 "register_operand" "")))]
279  "REG_P (operands[0]) && REG_P (operands[2])
280   && REGNO (operands[0]) != REGNO (operands[2])
281   && (satisfies_constraint_J (operands[1])
282       || satisfies_constraint_L (operands[1])
283       || satisfies_constraint_N (operands[1]))"
284  [(set (match_dup 0)
285	(match_dup 2))
286   (set (match_dup 0)
287	(plus:HI (match_dup 0)
288		 (match_dup 1)))]
289  "")
290
291;; Turn
292;;
293;;   sub.l  er0,er0
294;;   add.b  #4,r0l
295;;   add.l  er7,er0  (6 bytes)
296;;
297;; into
298;;
299;;   mov.l  er7,er0
300;;   adds   #4,er0   (4 bytes)
301
302(define_peephole2
303  [(set (match_operand:SI 0 "register_operand" "")
304	(match_operand:SI 1 "const_int_operand" ""))
305   (set (match_dup 0)
306	(plus:SI (match_dup 0)
307		 (match_operand:SI 2 "register_operand" "")))]
308  "REG_P (operands[0]) && REG_P (operands[2])
309   && REGNO (operands[0]) != REGNO (operands[2])
310   && (satisfies_constraint_L (operands[1])
311       || satisfies_constraint_N (operands[1]))"
312  [(set (match_dup 0)
313	(match_dup 2))
314   (set (match_dup 0)
315	(plus:SI (match_dup 0)
316		 (match_dup 1)))]
317  "")
318
319;; Turn
320;;
321;;   mov.l er7,er0
322;;   add.l #10,er0  (takes 8 bytes)
323;;
324;; into
325;;
326;;   sub.l er0,er0
327;;   add.b #10,r0l
328;;   add.l er7,er0  (takes 6 bytes)
329
330(define_peephole2
331  [(set (match_operand:SI 0 "register_operand" "")
332	(match_operand:SI 1 "register_operand" ""))
333   (set (match_dup 0)
334	(plus:SI (match_dup 0)
335		 (match_operand:SI 2 "const_int_operand" "")))]
336  "operands[0] != stack_pointer_rtx
337   && REG_P (operands[0]) && REG_P (operands[1])
338   && REGNO (operands[0]) != REGNO (operands[1])
339   && !satisfies_constraint_L (operands[2])
340   && !satisfies_constraint_N (operands[2])
341   && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
342       || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
343       || INTVAL (operands[2]) == 0xffff
344       || INTVAL (operands[2]) == 0xfffe)"
345  [(set (match_dup 0)
346	(match_dup 2))
347   (set (match_dup 0)
348	(plus:SI (match_dup 0)
349		 (match_dup 1)))]
350  "")
351
352;; If a load of mem:SI is followed by an AND that turns off the upper
353;; half, then we can load mem:HI instead.
354
355(define_peephole2
356  [(set (match_operand:SI 0 "register_operand" "")
357	(match_operand:SI 1 "memory_operand" ""))
358   (set (match_dup 0)
359	(and:SI (match_dup 0)
360		(match_operand:SI 2 "const_int_operand" "")))]
361  "!MEM_VOLATILE_P (operands[1])
362   && offsettable_memref_p (operands[1])
363   && (INTVAL (operands[2]) & ~0xffff) == 0
364   && INTVAL (operands[2]) != 255"
365  [(set (match_dup 3)
366	(match_dup 4))
367   (set (match_dup 0)
368	(and:SI (match_dup 0)
369		(match_dup 2)))]
370  {
371    operands[3] = gen_lowpart (HImode, operands[0]);
372    operands[4] = gen_lowpart (HImode, operands[1]);
373  })
374
375;; These triggers right at the end of allocation of locals in the
376;; prologue (and possibly at other places).
377
378;; stack adjustment of -4, generate one push
379;;
380;; before : 6 bytes
381;; after  : 4 bytes
382
383(define_peephole2
384  [(set (reg:SI SP_REG)
385	(plus:SI (reg:SI SP_REG)
386		 (const_int -4)))
387   (set (mem:SFI (reg:SI SP_REG))
388	(match_operand:SFI 0 "register_operand" ""))]
389  "!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
390  [(set (mem:SFI (pre_dec:SI (reg:SI SP_REG)))
391	(match_dup 0))])
392
393;; stack adjustment of -8, generate one push
394;;
395;; before : 8 bytes
396;; after  : 6 bytes
397
398(define_peephole2
399  [(set (reg:SI SP_REG)
400	(plus:SI (reg:SI SP_REG)
401		 (const_int -8)))
402   (set (mem:SFI (reg:SI SP_REG))
403	(match_operand:SFI 0 "register_operand" ""))]
404  "!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
405  [(set (reg:SI SP_REG)
406	(plus:SI (reg:SI SP_REG)
407		 (const_int -4)))
408   (set (mem:SFI (pre_dec:SI (reg:SI SP_REG)))
409	(match_dup 0))])
410
411;; stack adjustment of -12, generate one push
412;;
413;; before : 10 bytes
414;; after  :  8 bytes
415
416(define_peephole2
417  [(set (reg:SI SP_REG)
418	(plus:SI (reg:SI SP_REG)
419		 (const_int -12)))
420   (set (mem:SFI (reg:SI SP_REG))
421	(match_operand:SFI 0 "register_operand" ""))]
422  "!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
423  [(set (reg:SI SP_REG)
424	(plus:SI (reg:SI SP_REG)
425		 (const_int -4)))
426   (set (reg:SI SP_REG)
427	(plus:SI (reg:SI SP_REG)
428		 (const_int -4)))
429   (set (mem:SFI (pre_dec:SI (reg:SI SP_REG)))
430	(match_dup 0))])
431
432;; Transform
433;;
434;;	mov	dst,reg
435;;	op	reg
436;;	mov	reg,dst
437;;
438;; into
439;;
440;;	op	dst
441;;
442;; if "reg" dies at the end of the sequence.
443
444(define_peephole2
445  [(set (match_operand 0 "register_operand" "")
446	(match_operand 1 "memory_operand" ""))
447   (set (match_dup 0)
448	(match_operator 2 "h8sx_unary_memory_operator"
449	 [(match_dup 0)]))
450   (set (match_operand 3 "memory_operand" "")
451	(match_dup 0))]
452  "TARGET_H8300SX
453   && peep2_reg_dead_p (3, operands[0])
454   && !reg_overlap_mentioned_p (operands[0], operands[3])
455   && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
456  [(set (match_dup 3)
457	(match_dup 4))]
458  {
459    operands[4] = shallow_copy_rtx (operands[2]);
460    XEXP (operands[4], 0) = operands[1];
461  })
462
463;; Combine two moves.
464
465(define_peephole2
466  [(set (match_operand 0 "register_operand" "")
467	(match_operand 1 "h8300_src_operand" ""))
468   (set (match_operand 2 "h8300_dst_operand" "")
469	(match_dup 0))]
470  "TARGET_H8300SX
471   && peep2_reg_dead_p (2, operands[0])
472   && !reg_overlap_mentioned_p (operands[0], operands[2])"
473  [(set (match_dup 2)
474	(match_dup 1))])
475
476
477