h8300-protos.h: Replace do_movsi with h8300_expand_movsi.
[gcc.git] / gcc / config / h8300 / h8300.md
1 ;; GCC machine description for Hitachi H8/300
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003 Free Software Foundation, Inc.
4
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com),
6 ;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;; We compute exact length on each instruction for most of the time.
26 ;; In some case, most notably bit operations that may involve memory
27 ;; operands, the lengths in this file are "worst case".
28
29 ;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
30 ;; registers. Right now GCC doesn't expose the "e" half to the
31 ;; compiler, so using add/subs for addhi and subhi is safe. Long
32 ;; term, we want to expose the "e" half to the compiler (gives us 8
33 ;; more 16bit registers). At that point addhi and subhi can't use
34 ;; adds/subs.
35
36 ;; There's currently no way to have an insv/extzv expander for the H8/300H
37 ;; because word_mode is different for the H8/300 and H8/300H.
38
39 ;; Shifts/rotates by small constants should be handled by special
40 ;; patterns so we get the length and cc status correct.
41
42 ;; Bitfield operations no longer accept memory operands. We need
43 ;; to add variants which operate on memory back to the MD.
44
45 ;; ??? Implement remaining bit ops available on the h8300
46
47 ;; ----------------------------------------------------------------------
48 ;; CONSTANTS
49 ;; ----------------------------------------------------------------------
50
51 (define_constants
52 [(UNSPEC_INCDEC 0)
53 (UNSPEC_MONITOR 1)])
54
55 (define_constants
56 [(R0_REG 0)
57 (SC_REG 3)
58 (FP_REG 6)
59 (SP_REG 7)
60 (MAC_REG 8)
61 (AP_REG 9)
62 (RAP_REG 10)])
63
64 ;; ----------------------------------------------------------------------
65 ;; ATTRIBUTES
66 ;; ----------------------------------------------------------------------
67
68 (define_attr "cpu" "h8300,h8300h"
69 (const (symbol_ref "cpu_type")))
70
71 (define_attr "type" "branch,arith"
72 (const_string "arith"))
73
74 ;; The size of instructions in bytes.
75
76 (define_attr "length" ""
77 (cond [(eq_attr "type" "branch")
78 (if_then_else (and (ge (minus (match_dup 0) (pc))
79 (const_int -126))
80 (le (minus (match_dup 0) (pc))
81 (const_int 126)))
82 (const_int 2)
83 (if_then_else (and (eq_attr "cpu" "h8300h")
84 (and (ge (minus (pc) (match_dup 0))
85 (const_int -32000))
86 (le (minus (pc) (match_dup 0))
87 (const_int 32000))))
88 (const_int 4)
89 (const_int 6)))]
90 (const_int 200)))
91
92 ;; Condition code settings.
93 ;;
94 ;; none - insn does not affect cc
95 ;; none_0hit - insn does not affect cc but it does modify operand 0
96 ;; This attribute is used to keep track of when operand 0 changes.
97 ;; See the description of NOTICE_UPDATE_CC for more info.
98 ;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
99 ;; set_zn - insn sets z,n to usable values; v,c are unknown.
100 ;; compare - compare instruction
101 ;; clobber - value of cc is unknown
102
103 (define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
104 (const_string "clobber"))
105
106 ;; Provide the maximum length of an assembly instruction in an asm
107 ;; statement. The maximum length of 14 bytes is achieved on H8SX.
108
109 (define_asm_attributes
110 [(set (attr "length")
111 (cond [(ne (symbol_ref "TARGET_H8300") (const_int 0)) (const_int 4)
112 (ne (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 10)
113 (ne (symbol_ref "TARGET_H8300S") (const_int 0)) (const_int 10)]
114 (const_int 14)))])
115 \f
116 ;; ----------------------------------------------------------------------
117 ;; MOVE INSTRUCTIONS
118 ;; ----------------------------------------------------------------------
119
120 ;; movqi
121
122 (define_insn "pushqi1_h8300"
123 [(parallel [(set (reg:HI SP_REG)
124 (plus:HI (reg:HI SP_REG) (const_int -2)))
125 (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1)))
126 (match_operand:QI 0 "register_operand" "r"))])]
127 "TARGET_H8300
128 && operands[0] != stack_pointer_rtx"
129 "mov.w\\t%T0,@-r7"
130 [(set_attr "length" "2")
131 (set_attr "cc" "clobber")])
132
133 (define_insn "pushqi1_h8300hs"
134 [(parallel [(set (reg:SI SP_REG)
135 (plus:SI (reg:SI SP_REG) (const_int -4)))
136 (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
137 (match_operand:QI 0 "register_operand" "r"))])]
138 "(TARGET_H8300H || TARGET_H8300S)
139 && operands[0] != stack_pointer_rtx"
140 "mov.l\\t%S0,@-er7"
141 [(set_attr "length" "4")
142 (set_attr "cc" "clobber")])
143
144 (define_insn "pushqi1_h8300hs_normal"
145 [(parallel [(set (reg:HI SP_REG)
146 (plus:HI (reg:HI SP_REG) (const_int -4)))
147 (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
148 (match_operand:QI 0 "register_operand" "r"))])]
149 "(TARGET_H8300H || TARGET_H8300S)
150 && operands[0] != stack_pointer_rtx"
151 "mov.l\\t%S0,@-er7"
152 [(set_attr "length" "4")
153 (set_attr "cc" "clobber")])
154
155 (define_expand "pushqi1"
156 [(use (match_operand:QI 0 "register_operand" ""))]
157 ""
158 "
159 {
160 if (TARGET_H8300)
161 emit_insn (gen_pushqi1_h8300 (operands[0]));
162 else if (!TARGET_NORMAL_MODE)
163 emit_insn (gen_pushqi1_h8300hs (operands[0]));
164 else
165 emit_insn (gen_pushqi1_h8300hs_normal (operands[0]));
166 DONE;
167 }")
168
169 (define_insn "*movqi_h8300"
170 [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
171 (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
172 "TARGET_H8300
173 && (register_operand (operands[0], QImode)
174 || register_operand (operands[1], QImode))"
175 "@
176 sub.b %X0,%X0
177 mov.b %R1,%X0
178 mov.b %X1,%R0
179 mov.b %R1,%X0
180 mov.b %R1,%X0
181 mov.b %X1,%R0"
182 [(set_attr "length" "2,2,2,2,4,4")
183 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
184
185 (define_insn "*movqi_h8300hs"
186 [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
187 (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
188 "(TARGET_H8300H || TARGET_H8300S)
189 && (register_operand (operands[0], QImode)
190 || register_operand (operands[1], QImode))"
191 "@
192 sub.b %X0,%X0
193 mov.b %R1,%X0
194 mov.b %X1,%R0
195 mov.b %R1,%X0
196 mov.b %R1,%X0
197 mov.b %X1,%R0"
198 [(set (attr "length")
199 (symbol_ref "compute_mov_length (operands)"))
200 (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
201
202 (define_expand "movqi"
203 [(set (match_operand:QI 0 "general_operand_dst" "")
204 (match_operand:QI 1 "general_operand_src" ""))]
205 ""
206 "
207 {
208 /* One of the ops has to be in a register. */
209 if (!register_operand (operand0, QImode)
210 && !register_operand (operand1, QImode))
211 {
212 operands[1] = copy_to_mode_reg (QImode, operand1);
213 }
214 }")
215
216 (define_insn "movstrictqi"
217 [(set (strict_low_part
218 (match_operand:QI 0 "register_operand" "+r,r,r,r,r"))
219 (match_operand:QI 1 "general_operand_src" " I,r,n,>,m"))]
220 ""
221 "@
222 sub.b %X0,%X0
223 mov.b %X1,%X0
224 mov.b %R1,%X0
225 mov.b %X1,%X0
226 mov.b %R1,%X0"
227 [(set (attr "length")
228 (symbol_ref "compute_mov_length (operands)"))
229 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
230
231 ;; movhi
232
233 (define_expand "pushhi1_h8300"
234 [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
235 (match_operand:HI 0 "register_operand" ""))]
236 "TARGET_H8300
237 && operands[0] != stack_pointer_rtx"
238 "")
239
240 (define_insn "pushhi1_h8300hs"
241 [(parallel [(set (reg:SI SP_REG)
242 (plus:SI (reg:SI SP_REG) (const_int -4)))
243 (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
244 (match_operand:HI 0 "register_operand" "r"))])]
245 "(TARGET_H8300H || TARGET_H8300S)
246 && operands[0] != stack_pointer_rtx"
247 "mov.l\\t%S0,@-er7"
248 [(set_attr "length" "4")
249 (set_attr "cc" "clobber")])
250
251 (define_insn "pushhi1_h8300hs_normal"
252 [(parallel [(set (reg:HI SP_REG)
253 (plus:HI (reg:HI SP_REG) (const_int -4)))
254 (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
255 (match_operand:HI 0 "register_operand" "r"))])]
256 "(TARGET_H8300H || TARGET_H8300S)
257 && operands[0] != stack_pointer_rtx"
258 "mov.l\\t%S0,@-er7"
259 [(set_attr "length" "4")
260 (set_attr "cc" "clobber")])
261
262 (define_expand "pushhi1"
263 [(use (match_operand:HI 0 "register_operand" ""))]
264 ""
265 "
266 {
267 if (TARGET_H8300)
268 emit_insn (gen_pushhi1_h8300 (operands[0]));
269 else if (!TARGET_NORMAL_MODE)
270 emit_insn (gen_pushhi1_h8300hs (operands[0]));
271 else
272 emit_insn (gen_pushhi1_h8300hs_normal (operands[0]));
273 DONE;
274 }")
275
276 (define_insn "*movhi_h8300"
277 [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
278 (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
279 "TARGET_H8300
280 && (register_operand (operands[0], HImode)
281 || register_operand (operands[1], HImode))
282 && !(GET_CODE (operands[0]) == MEM
283 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
284 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
285 && GET_CODE (operands[1]) == REG
286 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
287 "@
288 sub.w %T0,%T0
289 mov.w %T1,%T0
290 mov.w %T1,%T0
291 mov.w %T1,%T0
292 mov.w %T1,%T0
293 mov.w %T1,%T0"
294 [(set (attr "length")
295 (symbol_ref "compute_mov_length (operands)"))
296 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
297
298 (define_insn "*movhi_h8300hs"
299 [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
300 (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
301 "(TARGET_H8300H || TARGET_H8300S)
302 && (register_operand (operands[0], HImode)
303 || register_operand (operands[1], HImode))"
304 "@
305 sub.w %T0,%T0
306 mov.w %T1,%T0
307 mov.w %T1,%T0
308 mov.w %T1,%T0
309 mov.w %T1,%T0
310 mov.w %T1,%T0"
311 [(set (attr "length")
312 (symbol_ref "compute_mov_length (operands)"))
313 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
314
315 (define_expand "movhi"
316 [(set (match_operand:HI 0 "general_operand_dst" "")
317 (match_operand:HI 1 "general_operand_src" ""))]
318 ""
319 "
320 {
321 /* One of the ops has to be in a register. */
322 if (!register_operand (operand1, HImode)
323 && !register_operand (operand0, HImode))
324 {
325 operands[1] = copy_to_mode_reg (HImode, operand1);
326 }
327 }")
328
329 (define_insn "movstricthi"
330 [(set (strict_low_part
331 (match_operand:HI 0 "register_operand" "+r,r,r,r,r"))
332 (match_operand:HI 1 "general_operand_src" " I,r,i,>,m"))]
333 ""
334 "@
335 sub.w %T0,%T0
336 mov.w %T1,%T0
337 mov.w %T1,%T0
338 mov.w %T1,%T0
339 mov.w %T1,%T0"
340 [(set (attr "length")
341 (symbol_ref "compute_mov_length (operands)"))
342 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
343
344 ;; movsi
345
346 (define_expand "movsi"
347 [(set (match_operand:SI 0 "general_operand_dst" "")
348 (match_operand:SI 1 "general_operand_src" ""))]
349 ""
350 "
351 {
352 if (TARGET_H8300)
353 {
354 if (h8300_expand_movsi (operands))
355 DONE;
356 }
357 else
358 {
359 /* One of the ops has to be in a register. */
360 if (!register_operand (operand1, SImode)
361 && !register_operand (operand0, SImode))
362 {
363 operands[1] = copy_to_mode_reg (SImode, operand1);
364 }
365 }
366 }")
367
368 (define_expand "movsf"
369 [(set (match_operand:SF 0 "general_operand_dst" "")
370 (match_operand:SF 1 "general_operand_src" ""))]
371 ""
372 "
373 {
374 if (TARGET_H8300)
375 {
376 if (h8300_expand_movsi (operands))
377 DONE;
378 }
379 else
380 {
381 /* One of the ops has to be in a register. */
382 if (!register_operand (operand1, SFmode)
383 && !register_operand (operand0, SFmode))
384 {
385 operands[1] = copy_to_mode_reg (SFmode, operand1);
386 }
387 }
388 }")
389
390 (define_insn "*movsi_h8300"
391 [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
392 (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
393 "TARGET_H8300
394 && (register_operand (operands[0], SImode)
395 || register_operand (operands[1], SImode))"
396 "*
397 {
398 unsigned int rn = -1;
399 switch (which_alternative)
400 {
401 case 0:
402 return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
403 case 1:
404 if (REGNO (operands[0]) < REGNO (operands[1]))
405 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
406 else
407 return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
408 case 2:
409 /* Make sure we don't trample the register we index with. */
410 if (GET_CODE (operands[1]) == MEM)
411 {
412 rtx inside = XEXP (operands[1], 0);
413 if (REG_P (inside))
414 {
415 rn = REGNO (inside);
416 }
417 else if (GET_CODE (inside) == PLUS)
418 {
419 rtx lhs = XEXP (inside, 0);
420 rtx rhs = XEXP (inside, 1);
421 if (REG_P (lhs)) rn = REGNO (lhs);
422 if (REG_P (rhs)) rn = REGNO (rhs);
423 }
424 }
425 if (rn == REGNO (operands[0]))
426 {
427 /* Move the second word first. */
428 return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
429 }
430 else
431 {
432 if (GET_CODE (operands[1]) == CONST_INT)
433 {
434 /* If either half is zero, use sub.w to clear that
435 half. */
436 if ((INTVAL (operands[1]) & 0xffff) == 0)
437 return \"mov.w %e1,%e0\;sub.w %f0,%f0\";
438 if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
439 return \"sub.w %e0,%e0\;mov.w %f1,%f0\";
440 /* If the upper half and the lower half are the same,
441 copy one half to the other. */
442 if ((INTVAL (operands[1]) & 0xffff)
443 == ((INTVAL (operands[1]) >> 16) & 0xffff))
444 return \"mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0\";
445 }
446 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
447 }
448 case 3:
449 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
450 case 4:
451 return \"mov.w %f1,%T0\;mov.w %e1,%T0\";
452 case 5:
453 return \"mov.w %T1,%e0\;mov.w %T1,%f0\";
454 default:
455 abort ();
456 }
457 }"
458 [(set (attr "length")
459 (symbol_ref "compute_mov_length (operands)"))
460 (set_attr "cc" "clobber")])
461
462 (define_insn "*movsf_h8300"
463 [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
464 (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
465 "TARGET_H8300
466 && (register_operand (operands[0], SFmode)
467 || register_operand (operands[1], SFmode))"
468 "*
469 {
470 /* Copy of the movsi stuff. */
471 unsigned int rn = -1;
472 switch (which_alternative)
473 {
474 case 0:
475 return \"sub.w %e0,%e0\;sub.w %f0,%f0\";
476 case 1:
477 if (REGNO (operands[0]) < REGNO (operands[1]))
478 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
479 else
480 return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
481 case 2:
482 /* Make sure we don't trample the register we index with. */
483 if (GET_CODE (operands[1]) == MEM)
484 {
485 rtx inside = XEXP (operands[1], 0);
486 if (REG_P (inside))
487 {
488 rn = REGNO (inside);
489 }
490 else if (GET_CODE (inside) == PLUS)
491 {
492 rtx lhs = XEXP (inside, 0);
493 rtx rhs = XEXP (inside, 1);
494 if (REG_P (lhs)) rn = REGNO (lhs);
495 if (REG_P (rhs)) rn = REGNO (rhs);
496 }
497 }
498 if (rn == REGNO (operands[0]))
499 /* Move the second word first. */
500 return \"mov.w %f1,%f0\;mov.w %e1,%e0\";
501 else
502 /* Move the first word first. */
503 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
504
505 case 3:
506 return \"mov.w %e1,%e0\;mov.w %f1,%f0\";
507 case 4:
508 return \"mov.w %f1,%T0\;mov.w %e1,%T0\";
509 case 5:
510 return \"mov.w %T1,%e0\;mov.w %T1,%f0\";
511 default:
512 abort ();
513 }
514 }"
515 [(set (attr "length")
516 (symbol_ref "compute_mov_length (operands)"))
517 (set_attr "cc" "clobber")])
518
519 (define_insn "*movsi_h8300hs"
520 [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
521 (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
522 "(TARGET_H8300S || TARGET_H8300H)
523 && (register_operand (operands[0], SImode)
524 || register_operand (operands[1], SImode))
525 && !(GET_CODE (operands[0]) == MEM
526 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
527 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
528 && GET_CODE (operands[1]) == REG
529 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))"
530 "*
531 {
532 switch (which_alternative)
533 {
534 case 0:
535 return \"sub.l %S0,%S0\";
536 case 7:
537 return \"clrmac\";
538 case 8:
539 return \"clrmac\;ldmac %1,macl\";
540 case 9:
541 return \"stmac macl,%0\";
542 default:
543 if (GET_CODE (operands[1]) == CONST_INT)
544 {
545 int val = INTVAL (operands[1]);
546
547 /* Look for constants which can be made by adding an 8-bit
548 number to zero in one of the two low bytes. */
549 if (val == (val & 0xff))
550 {
551 operands[1] = GEN_INT ((char) val & 0xff);
552 return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\";
553 }
554
555 if (val == (val & 0xff00))
556 {
557 operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
558 return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
559 }
560
561 /* Look for constants that can be obtained by subs, inc, and
562 dec to 0. */
563 switch (val & 0xffffffff)
564 {
565 case 0xffffffff:
566 return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
567 case 0xfffffffe:
568 return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
569 case 0xfffffffc:
570 return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
571
572 case 0x0000ffff:
573 return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
574 case 0x0000fffe:
575 return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
576
577 case 0xffff0000:
578 return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
579 case 0xfffe0000:
580 return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
581
582 case 0x00010000:
583 return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
584 case 0x00020000:
585 return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
586 }
587 }
588 }
589 return \"mov.l %S1,%S0\";
590 }"
591 [(set (attr "length")
592 (symbol_ref "compute_mov_length (operands)"))
593 (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
594
595 (define_insn "*movsf_h8300hs"
596 [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
597 (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
598 "(TARGET_H8300H || TARGET_H8300S)
599 && (register_operand (operands[0], SFmode)
600 || register_operand (operands[1], SFmode))"
601 "@
602 sub.l %S0,%S0
603 mov.l %S1,%S0
604 mov.l %S1,%S0
605 mov.l %S1,%S0
606 mov.l %S1,%S0
607 mov.l %S1,%S0"
608 [(set (attr "length")
609 (symbol_ref "compute_mov_length (operands)"))
610 (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
611 \f
612 ;; ----------------------------------------------------------------------
613 ;; TEST INSTRUCTIONS
614 ;; ----------------------------------------------------------------------
615
616 (define_insn ""
617 [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
618 (const_int 1)
619 (match_operand 1 "const_int_operand" "n,n")))]
620 "TARGET_H8300"
621 "btst %Z1,%Y0"
622 [(set_attr "length" "2,4")
623 (set_attr "cc" "set_zn,set_zn")])
624
625 (define_insn ""
626 [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
627 (const_int 1)
628 (match_operand 1 "const_int_operand" "n")))]
629 "TARGET_H8300"
630 "btst %Z1,%Y0"
631 [(set_attr "length" "2")
632 (set_attr "cc" "set_zn")])
633
634 (define_insn_and_split "*tst_extzv_1_n"
635 [(set (cc0)
636 (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
637 (const_int 1)
638 (match_operand 1 "const_int_operand" "n,n,n")))
639 (clobber (match_scratch:QI 2 "=X,X,&r"))]
640 "(TARGET_H8300H || TARGET_H8300S)"
641 "@
642 btst\\t%Z1,%Y0
643 btst\\t%Z1,%Y0
644 #"
645 "&& reload_completed
646 && !EXTRA_CONSTRAINT (operands[0], 'U')"
647 [(set (match_dup 2)
648 (match_dup 0))
649 (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
650 (const_int 1)
651 (match_dup 1)))
652 (clobber (scratch:QI))])]
653 ""
654 [(set_attr "length" "2,8,10")
655 (set_attr "cc" "set_zn,set_zn,set_zn")])
656
657 (define_insn ""
658 [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
659 (const_int 1)
660 (match_operand 1 "const_int_operand" "n")))]
661 "(TARGET_H8300H || TARGET_H8300S)
662 && INTVAL (operands[1]) <= 15"
663 "btst %Z1,%Y0"
664 [(set_attr "length" "2")
665 (set_attr "cc" "set_zn")])
666
667 (define_insn_and_split "*tstsi_upper_bit"
668 [(set (cc0)
669 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
670 (const_int 1)
671 (match_operand 1 "const_int_operand" "n")))
672 (clobber (match_scratch:SI 2 "=&r"))]
673 "(TARGET_H8300H || TARGET_H8300S)
674 && INTVAL (operands[1]) >= 16"
675 "#"
676 "&& reload_completed"
677 [(set (match_dup 2)
678 (ior:SI (and:SI (match_dup 2)
679 (const_int -65536))
680 (lshiftrt:SI (match_dup 0)
681 (const_int 16))))
682 (set (cc0)
683 (zero_extract:SI (match_dup 2)
684 (const_int 1)
685 (match_dup 3)))]
686 "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
687
688 (define_insn "*tstsi_variable_bit"
689 [(set (cc0)
690 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
691 (const_int 1)
692 (and:SI (match_operand:SI 1 "register_operand" "r")
693 (const_int 7))))]
694 "TARGET_H8300H || TARGET_H8300S"
695 "btst %w1,%w0"
696 [(set_attr "length" "2")
697 (set_attr "cc" "set_zn")])
698
699 (define_insn_and_split "*tstsi_variable_bit_qi"
700 [(set (cc0)
701 (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
702 (const_int 1)
703 (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
704 (const_int 7))))
705 (clobber (match_scratch:QI 2 "=X,X,&r"))]
706 "(TARGET_H8300H || TARGET_H8300S)"
707 "@
708 btst\\t%w1,%X0
709 btst\\t%w1,%X0
710 #"
711 "&& reload_completed
712 && !EXTRA_CONSTRAINT (operands[0], 'U')"
713 [(set (match_dup 2)
714 (match_dup 0))
715 (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
716 (const_int 1)
717 (and:SI (match_dup 1)
718 (const_int 7))))
719 (clobber (scratch:QI))])]
720 ""
721 [(set_attr "length" "2,8,10")
722 (set_attr "cc" "set_zn,set_zn,set_zn")])
723
724 (define_insn "tstqi"
725 [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
726 ""
727 "mov.b %X0,%X0"
728 [(set_attr "length" "2")
729 (set_attr "cc" "set_znv")])
730
731 (define_insn "tsthi"
732 [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
733 ""
734 "mov.w %T0,%T0"
735 [(set_attr "length" "2")
736 (set_attr "cc" "set_znv")])
737
738 (define_insn "*tsthi_upper"
739 [(set (cc0)
740 (and:HI (match_operand:HI 0 "register_operand" "r")
741 (const_int -256)))]
742 ""
743 "mov.b %t0,%t0"
744 [(set_attr "length" "2")
745 (set_attr "cc" "set_znv")])
746
747 (define_insn "tstsi"
748 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
749 "TARGET_H8300H || TARGET_H8300S"
750 "mov.l %S0,%S0"
751 [(set_attr "length" "2")
752 (set_attr "cc" "set_znv")])
753
754 (define_insn "*tstsi_upper"
755 [(set (cc0)
756 (and:SI (match_operand:SI 0 "register_operand" "r")
757 (const_int -65536)))]
758 ""
759 "mov.w %e0,%e0"
760 [(set_attr "length" "2")
761 (set_attr "cc" "set_znv")])
762
763 (define_insn "cmpqi"
764 [(set (cc0)
765 (compare (match_operand:QI 0 "register_operand" "r")
766 (match_operand:QI 1 "nonmemory_operand" "rn")))]
767 ""
768 "cmp.b %X1,%X0"
769 [(set_attr "length" "2")
770 (set_attr "cc" "compare")])
771
772 (define_expand "cmphi"
773 [(set (cc0)
774 (compare (match_operand:HI 0 "register_operand" "")
775 (match_operand:HI 1 "nonmemory_operand" "")))]
776 ""
777 "
778 {
779 /* Force operand1 into a register if we're compiling
780 for the H8/300. */
781 if (GET_CODE (operands[1]) != REG && TARGET_H8300)
782 operands[1] = force_reg (HImode, operands[1]);
783 }")
784
785 (define_insn "*cmphi_h8300"
786 [(set (cc0)
787 (compare (match_operand:HI 0 "register_operand" "r")
788 (match_operand:HI 1 "register_operand" "r")))]
789 "TARGET_H8300"
790 "cmp.w %T1,%T0"
791 [(set_attr "length" "2")
792 (set_attr "cc" "compare")])
793
794 (define_insn "*cmphi_h8300hs"
795 [(set (cc0)
796 (compare (match_operand:HI 0 "register_operand" "r,r")
797 (match_operand:HI 1 "nonmemory_operand" "r,n")))]
798 "TARGET_H8300H || TARGET_H8300S"
799 "cmp.w %T1,%T0"
800 [(set_attr "length" "2,4")
801 (set_attr "cc" "compare,compare")])
802
803 (define_insn "cmpsi"
804 [(set (cc0)
805 (compare (match_operand:SI 0 "register_operand" "r,r")
806 (match_operand:SI 1 "nonmemory_operand" "r,i")))]
807 "TARGET_H8300H || TARGET_H8300S"
808 "cmp.l %S1,%S0"
809 [(set_attr "length" "2,6")
810 (set_attr "cc" "compare,compare")])
811 \f
812 ;; ----------------------------------------------------------------------
813 ;; ADD INSTRUCTIONS
814 ;; ----------------------------------------------------------------------
815
816 (define_insn "addqi3"
817 [(set (match_operand:QI 0 "register_operand" "=r")
818 (plus:QI (match_operand:QI 1 "register_operand" "%0")
819 (match_operand:QI 2 "nonmemory_operand" "rn")))]
820 ""
821 "add.b %X2,%X0"
822 [(set_attr "length" "2")
823 (set_attr "cc" "set_zn")])
824
825 (define_expand "addhi3"
826 [(set (match_operand:HI 0 "register_operand" "")
827 (plus:HI (match_operand:HI 1 "register_operand" "")
828 (match_operand:HI 2 "nonmemory_operand" "")))]
829 ""
830 "")
831
832 (define_insn "*addhi3_h8300"
833 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
834 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
835 (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
836 "TARGET_H8300"
837 "@
838 adds %2,%T0
839 subs %G2,%T0
840 add.b %t2,%t0
841 add.b %s2,%s0\;addx %t2,%t0
842 add.w %T2,%T0"
843 [(set_attr "length" "2,2,2,4,2")
844 (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
845
846 ;; This splitter is very important to make the stack adjustment
847 ;; interrupt-safe. The combination of add.b and addx is unsafe!
848 ;;
849 ;; We apply this split after the peephole2 pass so that we won't end
850 ;; up creating too many adds/subs when a scratch register is
851 ;; available, which is actually a common case because stack unrolling
852 ;; tends to happen immediately after a function call.
853
854 (define_split
855 [(set (match_operand:HI 0 "stack_pointer_operand" "")
856 (plus:HI (match_dup 0)
857 (match_operand 1 "const_int_gt_2_operand" "")))]
858 "TARGET_H8300 && flow2_completed"
859 [(const_int 0)]
860 "split_adds_subs (HImode, operands); DONE;")
861
862 (define_peephole2
863 [(match_scratch:HI 2 "r")
864 (set (match_operand:HI 0 "stack_pointer_operand" "")
865 (plus:HI (match_dup 0)
866 (match_operand:HI 1 "const_int_ge_8_operand" "")))]
867 "TARGET_H8300"
868 [(set (match_dup 2)
869 (match_dup 1))
870 (set (match_dup 0)
871 (plus:HI (match_dup 0)
872 (match_dup 2)))]
873 "")
874
875 (define_insn "*addhi3_h8300hs"
876 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
877 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
878 (match_operand:HI 2 "nonmemory_operand" "L,N,J,n,r")))]
879 "TARGET_H8300H || TARGET_H8300S"
880 "@
881 adds %2,%S0
882 subs %G2,%S0
883 add.b %t2,%t0
884 add.w %T2,%T0
885 add.w %T2,%T0"
886 [(set_attr "length" "2,2,2,4,2")
887 (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
888
889 (define_insn "*addhi3_incdec"
890 [(set (match_operand:HI 0 "register_operand" "=r,r")
891 (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
892 (match_operand:HI 2 "incdec_operand" "M,O")]
893 UNSPEC_INCDEC))]
894 "TARGET_H8300H || TARGET_H8300S"
895 "@
896 inc.w %2,%T0
897 dec.w %G2,%T0"
898 [(set_attr "length" "2,2")
899 (set_attr "cc" "set_zn,set_zn")])
900
901 (define_split
902 [(set (match_operand:HI 0 "register_operand" "")
903 (plus:HI (match_dup 0)
904 (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
905 ""
906 [(const_int 0)]
907 "split_adds_subs (HImode, operands); DONE;")
908
909 (define_expand "addsi3"
910 [(set (match_operand:SI 0 "register_operand" "")
911 (plus:SI (match_operand:SI 1 "register_operand" "")
912 (match_operand:SI 2 "nonmemory_operand" "")))]
913 ""
914 "")
915
916 (define_insn "*addsi_h8300"
917 [(set (match_operand:SI 0 "register_operand" "=r,r")
918 (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
919 (match_operand:SI 2 "nonmemory_operand" "n,r")))]
920 "TARGET_H8300"
921 "* return output_plussi (operands);"
922 [(set (attr "length")
923 (symbol_ref "compute_plussi_length (operands)"))
924 (set (attr "cc")
925 (symbol_ref "compute_plussi_cc (operands)"))])
926
927 (define_insn "*addsi_h8300hs"
928 [(set (match_operand:SI 0 "register_operand" "=r,r")
929 (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
930 (match_operand:SI 2 "nonmemory_operand" "i,r")))]
931 "TARGET_H8300H || TARGET_H8300S"
932 "* return output_plussi (operands);"
933 [(set (attr "length")
934 (symbol_ref "compute_plussi_length (operands)"))
935 (set (attr "cc")
936 (symbol_ref "compute_plussi_cc (operands)"))])
937
938 (define_insn "*addsi3_incdec"
939 [(set (match_operand:SI 0 "register_operand" "=r,r")
940 (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
941 (match_operand:SI 2 "incdec_operand" "M,O")]
942 UNSPEC_INCDEC))]
943 "TARGET_H8300H || TARGET_H8300S"
944 "@
945 inc.l %2,%S0
946 dec.l %G2,%S0"
947 [(set_attr "length" "2,2")
948 (set_attr "cc" "set_zn,set_zn")])
949
950 (define_split
951 [(set (match_operand:SI 0 "register_operand" "")
952 (plus:SI (match_dup 0)
953 (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
954 "TARGET_H8300H || TARGET_H8300S"
955 [(const_int 0)]
956 "split_adds_subs (SImode, operands); DONE;")
957
958 ;; ----------------------------------------------------------------------
959 ;; SUBTRACT INSTRUCTIONS
960 ;; ----------------------------------------------------------------------
961
962 (define_insn "subqi3"
963 [(set (match_operand:QI 0 "register_operand" "=r")
964 (minus:QI (match_operand:QI 1 "register_operand" "0")
965 (match_operand:QI 2 "register_operand" "r")))]
966 ""
967 "sub.b %X2,%X0"
968 [(set_attr "length" "2")
969 (set_attr "cc" "set_zn")])
970
971 (define_expand "subhi3"
972 [(set (match_operand:HI 0 "register_operand" "")
973 (minus:HI (match_operand:HI 1 "general_operand" "")
974 (match_operand:HI 2 "nonmemory_operand" "")))]
975 ""
976 "")
977
978 (define_insn "*subhi3_h8300"
979 [(set (match_operand:HI 0 "register_operand" "=r,r")
980 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
981 (match_operand:HI 2 "nonmemory_operand" "r,n")))]
982 "TARGET_H8300"
983 "@
984 sub.w %T2,%T0
985 add.b %E2,%s0\;addx %F2,%t0"
986 [(set_attr "length" "2,4")
987 (set_attr "cc" "set_zn,clobber")])
988
989 (define_insn "*subhi3_h8300hs"
990 [(set (match_operand:HI 0 "register_operand" "=r,r")
991 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
992 (match_operand:HI 2 "nonmemory_operand" "r,n")))]
993 "TARGET_H8300H || TARGET_H8300S"
994 "@
995 sub.w %T2,%T0
996 sub.w %T2,%T0"
997 [(set_attr "length" "2,4")
998 (set_attr "cc" "set_zn,set_zn")])
999
1000 (define_expand "subsi3"
1001 [(set (match_operand:SI 0 "register_operand" "")
1002 (minus:SI (match_operand:SI 1 "register_operand" "")
1003 (match_operand:SI 2 "nonmemory_operand" "")))]
1004 ""
1005 "")
1006
1007 (define_insn "*subsi3_h8300"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (minus:SI (match_operand:SI 1 "register_operand" "0")
1010 (match_operand:SI 2 "register_operand" "r")))]
1011 "TARGET_H8300"
1012 "sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0"
1013 [(set_attr "length" "6")
1014 (set_attr "cc" "clobber")])
1015
1016 (define_insn "*subsi3_h8300hs"
1017 [(set (match_operand:SI 0 "register_operand" "=r,r")
1018 (minus:SI (match_operand:SI 1 "general_operand" "0,0")
1019 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1020 "TARGET_H8300H || TARGET_H8300S"
1021 "@
1022 sub.l %S2,%S0
1023 sub.l %S2,%S0"
1024 [(set_attr "length" "2,6")
1025 (set_attr "cc" "set_zn,set_zn")])
1026 \f
1027 ;; ----------------------------------------------------------------------
1028 ;; MULTIPLY INSTRUCTIONS
1029 ;; ----------------------------------------------------------------------
1030
1031 ;; Note that the H8/300 can only handle umulqihi3.
1032
1033 (define_insn "mulqihi3"
1034 [(set (match_operand:HI 0 "register_operand" "=r")
1035 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1036 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1037 "TARGET_H8300H || TARGET_H8300S"
1038 "mulxs.b %X2,%T0"
1039 [(set_attr "length" "4")
1040 (set_attr "cc" "set_zn")])
1041
1042 (define_insn "mulhisi3"
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1045 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1046 "TARGET_H8300H || TARGET_H8300S"
1047 "mulxs.w %T2,%S0"
1048 [(set_attr "length" "4")
1049 (set_attr "cc" "set_zn")])
1050
1051 (define_insn "umulqihi3"
1052 [(set (match_operand:HI 0 "register_operand" "=r")
1053 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1054 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1055 ""
1056 "mulxu %X2,%T0"
1057 [(set_attr "length" "2")
1058 (set_attr "cc" "none_0hit")])
1059
1060 (define_insn "umulhisi3"
1061 [(set (match_operand:SI 0 "register_operand" "=r")
1062 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1063 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1064 "TARGET_H8300H || TARGET_H8300S"
1065 "mulxu.w %T2,%S0"
1066 [(set_attr "length" "2")
1067 (set_attr "cc" "none_0hit")])
1068
1069 ;; This is a "bridge" instruction. Combine can't cram enough insns
1070 ;; together to crate a MAC instruction directly, but it can create
1071 ;; this instruction, which then allows combine to create the real
1072 ;; MAC insn.
1073 ;;
1074 ;; Unfortunately, if combine doesn't create a MAC instruction, this
1075 ;; insn must generate reasonably correct code. Egad.
1076 (define_insn ""
1077 [(set (match_operand:SI 0 "register_operand" "=a")
1078 (mult:SI
1079 (sign_extend:SI
1080 (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1081 (sign_extend:SI
1082 (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
1083 "TARGET_MAC"
1084 "clrmac\;mac @%2+,@%1+"
1085 [(set_attr "length" "6")
1086 (set_attr "cc" "none_0hit")])
1087
1088 (define_insn ""
1089 [(set (match_operand:SI 0 "register_operand" "=a")
1090 (plus:SI (mult:SI
1091 (sign_extend:SI (mem:HI
1092 (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1093 (sign_extend:SI (mem:HI
1094 (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
1095 (match_operand:SI 3 "register_operand" "0")))]
1096 "TARGET_MAC"
1097 "mac @%2+,@%1+"
1098 [(set_attr "length" "4")
1099 (set_attr "cc" "none_0hit")])
1100
1101 ;; ----------------------------------------------------------------------
1102 ;; DIVIDE/MOD INSTRUCTIONS
1103 ;; ----------------------------------------------------------------------
1104
1105 (define_insn "udivmodqi4"
1106 [(set (match_operand:QI 0 "register_operand" "=r")
1107 (truncate:QI
1108 (udiv:HI
1109 (match_operand:HI 1 "register_operand" "0")
1110 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1111 (set (match_operand:QI 3 "register_operand" "=r")
1112 (truncate:QI
1113 (umod:HI
1114 (match_dup 1)
1115 (zero_extend:HI (match_dup 2)))))]
1116 ""
1117 "*
1118 {
1119 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1120 return \"divxu.b\\t%X2,%T0\";
1121 else
1122 return \"divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1123 }"
1124 [(set_attr "length" "4")
1125 (set_attr "cc" "clobber")])
1126
1127 (define_insn "divmodqi4"
1128 [(set (match_operand:QI 0 "register_operand" "=r")
1129 (truncate:QI
1130 (div:HI
1131 (match_operand:HI 1 "register_operand" "0")
1132 (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1133 (set (match_operand:QI 3 "register_operand" "=r")
1134 (truncate:QI
1135 (mod:HI
1136 (match_dup 1)
1137 (sign_extend:HI (match_dup 2)))))]
1138 "TARGET_H8300H || TARGET_H8300S"
1139 "*
1140 {
1141 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1142 return \"divxs.b\\t%X2,%T0\";
1143 else
1144 return \"divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1145 }"
1146 [(set_attr "length" "6")
1147 (set_attr "cc" "clobber")])
1148
1149 (define_insn "udivmodhi4"
1150 [(set (match_operand:HI 0 "register_operand" "=r")
1151 (truncate:HI
1152 (udiv:SI
1153 (match_operand:SI 1 "register_operand" "0")
1154 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1155 (set (match_operand:HI 3 "register_operand" "=r")
1156 (truncate:HI
1157 (umod:SI
1158 (match_dup 1)
1159 (zero_extend:SI (match_dup 2)))))]
1160 "TARGET_H8300H || TARGET_H8300S"
1161 "*
1162 {
1163 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1164 return \"divxu.w\\t%T2,%S0\";
1165 else
1166 return \"divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1167 }"
1168 [(set_attr "length" "4")
1169 (set_attr "cc" "clobber")])
1170
1171 (define_insn "divmodhi4"
1172 [(set (match_operand:HI 0 "register_operand" "=r")
1173 (truncate:HI
1174 (div:SI
1175 (match_operand:SI 1 "register_operand" "0")
1176 (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1177 (set (match_operand:HI 3 "register_operand" "=r")
1178 (truncate:HI
1179 (mod:SI
1180 (match_dup 1)
1181 (sign_extend:SI (match_dup 2)))))]
1182 "TARGET_H8300H || TARGET_H8300S"
1183 "*
1184 {
1185 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1186 return \"divxs.w\\t%T2,%S0\";
1187 else
1188 return \"divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1189 }"
1190 [(set_attr "length" "6")
1191 (set_attr "cc" "clobber")])
1192 \f
1193 ;; ----------------------------------------------------------------------
1194 ;; AND INSTRUCTIONS
1195 ;; ----------------------------------------------------------------------
1196
1197 (define_insn "*andqi3_1"
1198 [(set (match_operand:QI 0 "bit_operand" "=r,U")
1199 (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1200 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1201 "register_operand (operands[0], QImode)
1202 || single_zero_operand (operands[2], QImode)"
1203 "@
1204 and %X2,%X0
1205 bclr %W2,%R0"
1206 [(set_attr "length" "2,8")
1207 (set_attr "cc" "set_znv,none_0hit")])
1208
1209 (define_expand "andqi3"
1210 [(set (match_operand:QI 0 "bit_operand" "")
1211 (and:QI (match_operand:QI 1 "bit_operand" "")
1212 (match_operand:QI 2 "nonmemory_operand" "")))]
1213 ""
1214 "
1215 {
1216 if (fix_bit_operand (operands, 0, AND))
1217 DONE;
1218 }")
1219
1220 (define_expand "andhi3"
1221 [(set (match_operand:HI 0 "register_operand" "")
1222 (and:HI (match_operand:HI 1 "register_operand" "")
1223 (match_operand:HI 2 "nonmemory_operand" "")))]
1224 ""
1225 "")
1226
1227 (define_insn "*andorqi3"
1228 [(set (match_operand:QI 0 "register_operand" "=r")
1229 (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
1230 (match_operand:QI 3 "single_one_operand" "n"))
1231 (match_operand:QI 1 "register_operand" "0")))]
1232 ""
1233 "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
1234 [(set_attr "length" "6")
1235 (set_attr "cc" "clobber")])
1236
1237 (define_insn "*andorhi3"
1238 [(set (match_operand:HI 0 "register_operand" "=r")
1239 (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
1240 (match_operand:HI 3 "single_one_operand" "n"))
1241 (match_operand:HI 1 "register_operand" "0")))]
1242 ""
1243 "*
1244 {
1245 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1246 if (INTVAL (operands[3]) > 128)
1247 {
1248 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1249 return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\";
1250 }
1251 return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\";
1252 }"
1253 [(set_attr "length" "6")
1254 (set_attr "cc" "clobber")])
1255
1256 (define_insn "*andorsi3"
1257 [(set (match_operand:SI 0 "register_operand" "=r")
1258 (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
1259 (match_operand:SI 3 "single_one_operand" "n"))
1260 (match_operand:SI 1 "register_operand" "0")))]
1261 "(INTVAL (operands[3]) & 0xffff) != 0"
1262 "*
1263 {
1264 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1265 if (INTVAL (operands[3]) > 128)
1266 {
1267 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1268 return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\";
1269 }
1270 return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\";
1271 }"
1272 [(set_attr "length" "6")
1273 (set_attr "cc" "clobber")])
1274
1275 (define_insn "*andorsi3_shift_8"
1276 [(set (match_operand:SI 0 "register_operand" "=r")
1277 (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1278 (const_int 8))
1279 (const_int 65280))
1280 (match_operand:SI 1 "register_operand" "0")))]
1281 ""
1282 "or.b\\t%w2,%x0"
1283 [(set_attr "length" "2")
1284 (set_attr "cc" "clobber")])
1285
1286 (define_expand "andsi3"
1287 [(set (match_operand:SI 0 "register_operand" "")
1288 (and:SI (match_operand:SI 1 "register_operand" "")
1289 (match_operand:SI 2 "nonmemory_operand" "")))]
1290 ""
1291 "")
1292
1293 ;; ----------------------------------------------------------------------
1294 ;; OR INSTRUCTIONS
1295 ;; ----------------------------------------------------------------------
1296
1297 (define_insn "*iorqi3_1"
1298 [(set (match_operand:QI 0 "bit_operand" "=r,U")
1299 (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1300 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1301 "register_operand (operands[0], QImode)
1302 || single_one_operand (operands[2], QImode)"
1303 "@
1304 or\\t%X2,%X0
1305 bset\\t%V2,%R0"
1306 [(set_attr "length" "2,8")
1307 (set_attr "cc" "set_znv,none_0hit")])
1308
1309 (define_expand "iorqi3"
1310 [(set (match_operand:QI 0 "bit_operand" "")
1311 (ior:QI (match_operand:QI 1 "bit_operand" "")
1312 (match_operand:QI 2 "nonmemory_operand" "")))]
1313 ""
1314 "
1315 {
1316 if (fix_bit_operand (operands, 1, IOR))
1317 DONE;
1318 }")
1319
1320 (define_expand "iorhi3"
1321 [(set (match_operand:HI 0 "register_operand" "")
1322 (ior:HI (match_operand:HI 1 "register_operand" "")
1323 (match_operand:HI 2 "nonmemory_operand" "")))]
1324 ""
1325 "")
1326
1327 (define_expand "iorsi3"
1328 [(set (match_operand:SI 0 "register_operand" "")
1329 (ior:SI (match_operand:SI 1 "register_operand" "")
1330 (match_operand:SI 2 "nonmemory_operand" "")))]
1331 ""
1332 "")
1333
1334 ;; ----------------------------------------------------------------------
1335 ;; XOR INSTRUCTIONS
1336 ;; ----------------------------------------------------------------------
1337
1338 (define_insn "*xorqi3_1"
1339 [(set (match_operand:QI 0 "bit_operand" "=r,U")
1340 (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1341 (match_operand:QI 2 "nonmemory_operand" "rn,n")))]
1342 "register_operand (operands[0], QImode)
1343 || single_one_operand (operands[2], QImode)"
1344 "@
1345 xor\\t%X2,%X0
1346 bnot\\t%V2,%R0"
1347 [(set_attr "length" "2,8")
1348 (set_attr "cc" "set_znv,none_0hit")])
1349
1350 (define_expand "xorqi3"
1351 [(set (match_operand:QI 0 "bit_operand" "")
1352 (xor:QI (match_operand:QI 1 "bit_operand" "")
1353 (match_operand:QI 2 "nonmemory_operand" "")))]
1354 ""
1355 "
1356 {
1357 if (fix_bit_operand (operands, 1, XOR))
1358 DONE;
1359 }")
1360
1361 (define_expand "xorhi3"
1362 [(set (match_operand:HI 0 "register_operand" "")
1363 (xor:HI (match_operand:HI 1 "register_operand" "")
1364 (match_operand:HI 2 "nonmemory_operand" "")))]
1365 ""
1366 "")
1367
1368 (define_expand "xorsi3"
1369 [(set (match_operand:SI 0 "register_operand" "")
1370 (xor:SI (match_operand:SI 1 "register_operand" "")
1371 (match_operand:SI 2 "nonmemory_operand" "")))]
1372 ""
1373 "")
1374
1375 ;; ----------------------------------------------------------------------
1376 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1377 ;; ----------------------------------------------------------------------
1378
1379 (define_insn "*logicalhi3"
1380 [(set (match_operand:HI 0 "register_operand" "=r")
1381 (match_operator:HI 3 "bit_operator"
1382 [(match_operand:HI 1 "register_operand" "%0")
1383 (match_operand:HI 2 "nonmemory_operand" "rn")]))]
1384 ""
1385 "* return output_logical_op (HImode, operands);"
1386 [(set (attr "length")
1387 (symbol_ref "compute_logical_op_length (HImode, operands)"))
1388 (set (attr "cc")
1389 (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
1390
1391 (define_insn "*logicalsi3"
1392 [(set (match_operand:SI 0 "register_operand" "=r")
1393 (match_operator:SI 3 "bit_operator"
1394 [(match_operand:SI 1 "register_operand" "%0")
1395 (match_operand:SI 2 "nonmemory_operand" "rn")]))]
1396 ""
1397 "* return output_logical_op (SImode, operands);"
1398 [(set (attr "length")
1399 (symbol_ref "compute_logical_op_length (SImode, operands)"))
1400 (set (attr "cc")
1401 (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
1402 \f
1403 ;; ----------------------------------------------------------------------
1404 ;; NEGATION INSTRUCTIONS
1405 ;; ----------------------------------------------------------------------
1406
1407 (define_insn "negqi2"
1408 [(set (match_operand:QI 0 "register_operand" "=r")
1409 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1410 ""
1411 "neg %X0"
1412 [(set_attr "length" "2")
1413 (set_attr "cc" "set_zn")])
1414
1415 (define_expand "neghi2"
1416 [(set (match_operand:HI 0 "register_operand" "")
1417 (neg:HI (match_operand:HI 1 "register_operand" "")))]
1418 ""
1419 "
1420 {
1421 if (TARGET_H8300)
1422 {
1423 emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1424 DONE;
1425 }
1426 }")
1427
1428 (define_expand "neghi2_h8300"
1429 [(set (match_dup 2)
1430 (not:HI (match_operand:HI 1 "register_operand" "")))
1431 (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
1432 (set (match_operand:HI 0 "register_operand" "")
1433 (match_dup 2))]
1434 ""
1435 "operands[2] = gen_reg_rtx (HImode);")
1436
1437 (define_insn "*neghi2_h8300hs"
1438 [(set (match_operand:HI 0 "register_operand" "=r")
1439 (neg:HI (match_operand:HI 1 "register_operand" "0")))]
1440 "TARGET_H8300H || TARGET_H8300S"
1441 "neg %T0"
1442 [(set_attr "length" "2")
1443 (set_attr "cc" "set_zn")])
1444
1445 (define_expand "negsi2"
1446 [(set (match_operand:SI 0 "register_operand" "")
1447 (neg:SI (match_operand:SI 1 "register_operand" "")))]
1448 ""
1449 "
1450 {
1451 if (TARGET_H8300)
1452 {
1453 emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1454 DONE;
1455 }
1456 }")
1457
1458 (define_expand "negsi2_h8300"
1459 [(set (match_dup 2)
1460 (not:SI (match_operand:SI 1 "register_operand" "")))
1461 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
1462 (set (match_operand:SI 0 "register_operand" "")
1463 (match_dup 2))]
1464 ""
1465 "operands[2] = gen_reg_rtx (SImode);")
1466
1467 (define_insn "*negsi2_h8300hs"
1468 [(set (match_operand:SI 0 "register_operand" "=r")
1469 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
1470 "TARGET_H8300H || TARGET_H8300S"
1471 "neg %S0"
1472 [(set_attr "length" "2")
1473 (set_attr "cc" "set_zn")])
1474
1475 (define_expand "negsf2"
1476 [(set (match_operand:SF 0 "register_operand" "")
1477 (neg:SF (match_operand:SF 1 "register_operand" "")))]
1478 ""
1479 "")
1480
1481 (define_insn "*negsf2_h8300"
1482 [(set (match_operand:SF 0 "register_operand" "=r")
1483 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1484 "TARGET_H8300"
1485 "xor.b\\t#128,%z0"
1486 [(set_attr "cc" "clobber")
1487 (set_attr "length" "2")])
1488
1489 (define_insn "*negsf2_h8300hs"
1490 [(set (match_operand:SF 0 "register_operand" "=r")
1491 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1492 "TARGET_H8300H || TARGET_H8300S"
1493 "xor.w\\t#32768,%e0"
1494 [(set_attr "cc" "clobber")
1495 (set_attr "length" "4")])
1496 \f
1497 ;; ----------------------------------------------------------------------
1498 ;; ABSOLUTE VALUE INSTRUCTIONS
1499 ;; ----------------------------------------------------------------------
1500
1501 (define_expand "abssf2"
1502 [(set (match_operand:SF 0 "register_operand" "")
1503 (abs:SF (match_operand:SF 1 "register_operand" "")))]
1504 ""
1505 "")
1506
1507 (define_insn "*abssf2_h8300"
1508 [(set (match_operand:SF 0 "register_operand" "=r")
1509 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1510 "TARGET_H8300"
1511 "and.b\\t#127,%z0"
1512 [(set_attr "cc" "clobber")
1513 (set_attr "length" "2")])
1514
1515 (define_insn "*abssf2_h8300hs"
1516 [(set (match_operand:SF 0 "register_operand" "=r")
1517 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1518 "TARGET_H8300H || TARGET_H8300S"
1519 "and.w\\t#32767,%e0"
1520 [(set_attr "cc" "clobber")
1521 (set_attr "length" "4")])
1522 \f
1523 ;; ----------------------------------------------------------------------
1524 ;; NOT INSTRUCTIONS
1525 ;; ----------------------------------------------------------------------
1526
1527 (define_insn "one_cmplqi2"
1528 [(set (match_operand:QI 0 "register_operand" "=r")
1529 (not:QI (match_operand:QI 1 "register_operand" "0")))]
1530 ""
1531 "not %X0"
1532 [(set_attr "length" "2")
1533 (set_attr "cc" "set_znv")])
1534
1535 (define_expand "one_cmplhi2"
1536 [(set (match_operand:HI 0 "register_operand" "=r")
1537 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1538 ""
1539 "")
1540
1541 (define_insn "*one_cmplhi2_h8300"
1542 [(set (match_operand:HI 0 "register_operand" "=r")
1543 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1544 "TARGET_H8300"
1545 "not %s0\;not %t0"
1546 [(set_attr "cc" "clobber")
1547 (set_attr "length" "4")])
1548
1549 (define_insn "*one_cmplhi2_h8300hs"
1550 [(set (match_operand:HI 0 "register_operand" "=r")
1551 (not:HI (match_operand:HI 1 "register_operand" "0")))]
1552 "TARGET_H8300H || TARGET_H8300S"
1553 "not %T0"
1554 [(set_attr "cc" "set_znv")
1555 (set_attr "length" "2")])
1556
1557 (define_expand "one_cmplsi2"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1560 ""
1561 "")
1562
1563 (define_insn "*one_complsi2_h8300"
1564 [(set (match_operand:SI 0 "register_operand" "=r")
1565 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1566 "TARGET_H8300"
1567 "not %w0\;not %x0\;not %y0\;not %z0"
1568 [(set_attr "cc" "clobber")
1569 (set_attr "length" "8")])
1570
1571 (define_insn "*one_complsi2_h8300hs"
1572 [(set (match_operand:SI 0 "register_operand" "=r")
1573 (not:SI (match_operand:SI 1 "register_operand" "0")))]
1574 "TARGET_H8300H || TARGET_H8300S"
1575 "not %S0"
1576 [(set_attr "cc" "set_znv")
1577 (set_attr "length" "2")])
1578 \f
1579 ;; ----------------------------------------------------------------------
1580 ;; JUMP INSTRUCTIONS
1581 ;; ----------------------------------------------------------------------
1582
1583 ;; Conditional jump instructions
1584
1585 (define_expand "ble"
1586 [(set (pc)
1587 (if_then_else (le (cc0)
1588 (const_int 0))
1589 (label_ref (match_operand 0 "" ""))
1590 (pc)))]
1591 ""
1592 "")
1593
1594 (define_expand "bleu"
1595 [(set (pc)
1596 (if_then_else (leu (cc0)
1597 (const_int 0))
1598 (label_ref (match_operand 0 "" ""))
1599 (pc)))]
1600 ""
1601 "")
1602
1603 (define_expand "bge"
1604 [(set (pc)
1605 (if_then_else (ge (cc0)
1606 (const_int 0))
1607 (label_ref (match_operand 0 "" ""))
1608 (pc)))]
1609 ""
1610 "")
1611
1612 (define_expand "bgeu"
1613 [(set (pc)
1614 (if_then_else (geu (cc0)
1615 (const_int 0))
1616 (label_ref (match_operand 0 "" ""))
1617 (pc)))]
1618 ""
1619 "")
1620
1621 (define_expand "blt"
1622 [(set (pc)
1623 (if_then_else (lt (cc0)
1624 (const_int 0))
1625 (label_ref (match_operand 0 "" ""))
1626 (pc)))]
1627 ""
1628 "")
1629
1630 (define_expand "bltu"
1631 [(set (pc)
1632 (if_then_else (ltu (cc0)
1633 (const_int 0))
1634 (label_ref (match_operand 0 "" ""))
1635 (pc)))]
1636 ""
1637 "")
1638
1639 (define_expand "bgt"
1640 [(set (pc)
1641 (if_then_else (gt (cc0)
1642 (const_int 0))
1643 (label_ref (match_operand 0 "" ""))
1644 (pc)))]
1645 ""
1646 "")
1647
1648 (define_expand "bgtu"
1649 [(set (pc)
1650 (if_then_else (gtu (cc0)
1651 (const_int 0))
1652 (label_ref (match_operand 0 "" ""))
1653 (pc)))]
1654 ""
1655 "")
1656
1657 (define_expand "beq"
1658 [(set (pc)
1659 (if_then_else (eq (cc0)
1660 (const_int 0))
1661 (label_ref (match_operand 0 "" ""))
1662 (pc)))]
1663 ""
1664 "")
1665
1666 (define_expand "bne"
1667 [(set (pc)
1668 (if_then_else (ne (cc0)
1669 (const_int 0))
1670 (label_ref (match_operand 0 "" ""))
1671 (pc)))]
1672 ""
1673 "")
1674
1675 (define_insn "branch_true"
1676 [(set (pc)
1677 (if_then_else (match_operator 1 "comparison_operator"
1678 [(cc0) (const_int 0)])
1679 (label_ref (match_operand 0 "" ""))
1680 (pc)))]
1681 ""
1682 "*
1683 {
1684 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1685 && (GET_CODE (operands[1]) == GT
1686 || GET_CODE (operands[1]) == GE
1687 || GET_CODE (operands[1]) == LE
1688 || GET_CODE (operands[1]) == LT))
1689 {
1690 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1691 return 0;
1692 }
1693
1694 if (get_attr_length (insn) == 2)
1695 return \"b%j1 %l0\";
1696 else if (get_attr_length (insn) == 4)
1697 return \"b%j1 %l0:16\";
1698 else
1699 return \"b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\";
1700 }"
1701 [(set_attr "type" "branch")
1702 (set_attr "cc" "none")])
1703
1704 (define_insn "branch_false"
1705 [(set (pc)
1706 (if_then_else (match_operator 1 "comparison_operator"
1707 [(cc0) (const_int 0)])
1708 (pc)
1709 (label_ref (match_operand 0 "" ""))))]
1710 ""
1711 "*
1712 {
1713 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1714 && (GET_CODE (operands[1]) == GT
1715 || GET_CODE (operands[1]) == GE
1716 || GET_CODE (operands[1]) == LE
1717 || GET_CODE (operands[1]) == LT))
1718 {
1719 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1720 return 0;
1721 }
1722
1723 if (get_attr_length (insn) == 2)
1724 return \"b%k1 %l0\";
1725 else if (get_attr_length (insn) == 4)
1726 return \"b%k1 %l0:16\";
1727 else
1728 return \"b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\";
1729 }"
1730 [(set_attr "type" "branch")
1731 (set_attr "cc" "none")])
1732
1733 ;; Unconditional and other jump instructions.
1734
1735 (define_insn "jump"
1736 [(set (pc)
1737 (label_ref (match_operand 0 "" "")))]
1738 ""
1739 "*
1740 {
1741 if (get_attr_length (insn) == 2)
1742 return \"bra %l0\";
1743 else if (get_attr_length (insn) == 4)
1744 return \"bra %l0:16\";
1745 else
1746 return \"jmp @%l0\";
1747 }"
1748 [(set_attr "type" "branch")
1749 (set_attr "cc" "none")])
1750
1751 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1752
1753 (define_expand "tablejump"
1754 [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
1755 (use (label_ref (match_operand 1 "" "")))])]
1756 ""
1757 "")
1758
1759 (define_insn "*tablejump_h8300"
1760 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1761 (use (label_ref (match_operand 1 "" "")))]
1762 "TARGET_H8300"
1763 "jmp @%0"
1764 [(set_attr "cc" "none")
1765 (set_attr "length" "2")])
1766
1767 (define_insn "*tablejump_h8300hs_advanced"
1768 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1769 (use (label_ref (match_operand 1 "" "")))]
1770 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
1771 "jmp @%0"
1772 [(set_attr "cc" "none")
1773 (set_attr "length" "2")])
1774
1775 (define_insn "*tablejump_h8300hs_normal"
1776 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1777 (use (label_ref (match_operand 1 "" "")))]
1778 "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1779 "jmp @%S0"
1780 [(set_attr "cc" "none")
1781 (set_attr "length" "2")])
1782
1783 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1784
1785 (define_expand "indirect_jump"
1786 [(set (pc) (match_operand 0 "jump_address_operand" ""))]
1787 ""
1788 "")
1789
1790 (define_insn "*indirect_jump_h8300"
1791 [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1792 "TARGET_H8300"
1793 "jmp @%0"
1794 [(set_attr "cc" "none")
1795 (set_attr "length" "2")])
1796
1797 (define_insn "*indirect_jump_h8300hs_advanced"
1798 [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
1799 "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
1800 "jmp @%0"
1801 [(set_attr "cc" "none")
1802 (set_attr "length" "2")])
1803
1804 (define_insn "*indirect_jump_h8300hs_normal"
1805 [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
1806 "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
1807 "jmp @%S0"
1808 [(set_attr "cc" "none")
1809 (set_attr "length" "2")])
1810
1811 ;; Call subroutine with no return value.
1812
1813 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1814
1815 (define_insn "call"
1816 [(call (match_operand:QI 0 "call_insn_operand" "or")
1817 (match_operand:HI 1 "general_operand" "g"))]
1818 ""
1819 "*
1820 {
1821 if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1822 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1823 return \"jsr\\t@%0:8\";
1824 else
1825 return \"jsr\\t%0\";
1826 }"
1827 [(set_attr "cc" "clobber")
1828 (set (attr "length")
1829 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1830 (const_int 2)
1831 (const_int 4)))])
1832
1833 ;; Call subroutine, returning value in operand 0
1834 ;; (which must be a hard register).
1835
1836 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1837
1838 (define_insn "call_value"
1839 [(set (match_operand 0 "" "=r")
1840 (call (match_operand:QI 1 "call_insn_operand" "or")
1841 (match_operand:HI 2 "general_operand" "g")))]
1842 ""
1843 "*
1844 {
1845 if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1846 && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1847 return \"jsr\\t@%1:8\";
1848 else
1849 return \"jsr\\t%1\";
1850 }"
1851 [(set_attr "cc" "clobber")
1852 (set (attr "length")
1853 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1854 (const_int 2)
1855 (const_int 4)))])
1856
1857 (define_insn "nop"
1858 [(const_int 0)]
1859 ""
1860 "nop"
1861 [(set_attr "cc" "none")
1862 (set_attr "length" "2")])
1863 \f
1864 ;; ----------------------------------------------------------------------
1865 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
1866 ;; ----------------------------------------------------------------------
1867
1868 (define_expand "push_h8300"
1869 [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
1870 (match_operand:HI 0 "register_operand" ""))]
1871 "TARGET_H8300"
1872 "")
1873
1874 (define_expand "push_h8300hs_advanced"
1875 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
1876 (match_operand:SI 0 "register_operand" ""))]
1877 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1878 "")
1879
1880 (define_expand "push_h8300hs_normal"
1881 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
1882 (match_operand:SI 0 "register_operand" ""))]
1883 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1884 "")
1885
1886 (define_expand "pop_h8300"
1887 [(set (match_operand:HI 0 "register_operand" "")
1888 (mem:HI (post_inc:HI (reg:HI SP_REG))))]
1889 "TARGET_H8300"
1890 "")
1891
1892 (define_expand "pop_h8300hs_advanced"
1893 [(set (match_operand:SI 0 "register_operand" "")
1894 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
1895 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1896 "")
1897
1898 (define_expand "pop_h8300hs_normal"
1899 [(set (match_operand:SI 0 "register_operand" "")
1900 (mem:SI (post_inc:HI (reg:HI SP_REG))))]
1901 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1902 "")
1903
1904 (define_insn "stm_h8300s_2_advanced"
1905 [(parallel
1906 [(set (reg:SI SP_REG)
1907 (plus:SI (reg:SI SP_REG) (const_int -8)))
1908 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1909 (match_operand:SI 0 "register_operand" ""))
1910 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1911 (match_operand:SI 1 "register_operand" ""))])]
1912 "TARGET_H8300S && !TARGET_NORMAL_MODE
1913 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1914 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1915 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1916 "stm.l\\t%S0-%S1,@-er7"
1917 [(set_attr "cc" "none")
1918 (set_attr "length" "4")])
1919
1920 (define_insn "stm_h8300s_2_normal"
1921 [(parallel
1922 [(set (reg:HI SP_REG)
1923 (plus:HI (reg:HI SP_REG) (const_int -8)))
1924 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
1925 (match_operand:SI 0 "register_operand" ""))
1926 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
1927 (match_operand:SI 1 "register_operand" ""))])]
1928 "TARGET_H8300S && TARGET_NORMAL_MODE
1929 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1930 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1931 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1932 "stm.l\\t%S0-%S1,@-er7"
1933 [(set_attr "cc" "none")
1934 (set_attr "length" "4")])
1935
1936 (define_expand "stm_h8300s_2"
1937 [(use (match_operand:SI 0 "register_operand" ""))
1938 (use (match_operand:SI 1 "register_operand" ""))]
1939 "TARGET_H8300S
1940 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
1941 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
1942 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
1943 "
1944 {
1945 if (!TARGET_NORMAL_MODE)
1946 emit_insn (gen_stm_h8300s_2_advanced (operands[0], operands[1]));
1947 else
1948 emit_insn (gen_stm_h8300s_2_normal (operands[0], operands[1]));
1949 DONE;
1950 }")
1951
1952 (define_insn "stm_h8300s_3_advanced"
1953 [(parallel
1954 [(set (reg:SI SP_REG)
1955 (plus:SI (reg:SI SP_REG) (const_int -12)))
1956 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
1957 (match_operand:SI 0 "register_operand" ""))
1958 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
1959 (match_operand:SI 1 "register_operand" ""))
1960 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
1961 (match_operand:SI 2 "register_operand" ""))])]
1962 "TARGET_H8300S && !TARGET_NORMAL_MODE
1963 && ((REGNO (operands[0]) == 0
1964 && REGNO (operands[1]) == 1
1965 && REGNO (operands[2]) == 2)
1966 || (REGNO (operands[0]) == 4
1967 && REGNO (operands[1]) == 5
1968 && REGNO (operands[2]) == 6))"
1969 "stm.l\\t%S0-%S2,@-er7"
1970 [(set_attr "cc" "none")
1971 (set_attr "length" "4")])
1972
1973 (define_insn "stm_h8300s_3_normal"
1974 [(parallel
1975 [(set (reg:HI SP_REG)
1976 (plus:HI (reg:HI SP_REG) (const_int -12)))
1977 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
1978 (match_operand:SI 0 "register_operand" ""))
1979 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
1980 (match_operand:SI 1 "register_operand" ""))
1981 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
1982 (match_operand:SI 2 "register_operand" ""))])]
1983 "TARGET_H8300S && TARGET_NORMAL_MODE
1984 && ((REGNO (operands[0]) == 0
1985 && REGNO (operands[1]) == 1
1986 && REGNO (operands[2]) == 2)
1987 || (REGNO (operands[0]) == 4
1988 && REGNO (operands[1]) == 5
1989 && REGNO (operands[2]) == 6))"
1990 "stm.l\\t%S0-%S2,@-er7"
1991 [(set_attr "cc" "none")
1992 (set_attr "length" "4")])
1993
1994 (define_expand "stm_h8300s_3"
1995 [(use (match_operand:SI 0 "register_operand" ""))
1996 (use (match_operand:SI 1 "register_operand" ""))
1997 (use (match_operand:SI 2 "register_operand" ""))]
1998 "TARGET_H8300S
1999 && ((REGNO (operands[0]) == 0
2000 && REGNO (operands[1]) == 1
2001 && REGNO (operands[2]) == 2)
2002 || (REGNO (operands[0]) == 4
2003 && REGNO (operands[1]) == 5
2004 && REGNO (operands[2]) == 6))"
2005 "
2006 {
2007 if (!TARGET_NORMAL_MODE)
2008 emit_insn (gen_stm_h8300s_3_advanced (operands[0], operands[1],
2009 operands[2]));
2010 else
2011 emit_insn (gen_stm_h8300s_3_normal (operands[0], operands[1],
2012 operands[2]));
2013 DONE;
2014 }")
2015
2016 (define_insn "stm_h8300s_4_advanced"
2017 [(parallel
2018 [(set (reg:SI SP_REG)
2019 (plus:SI (reg:SI SP_REG) (const_int -16)))
2020 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
2021 (match_operand:SI 0 "register_operand" ""))
2022 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
2023 (match_operand:SI 1 "register_operand" ""))
2024 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
2025 (match_operand:SI 2 "register_operand" ""))
2026 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
2027 (match_operand:SI 3 "register_operand" ""))])]
2028 "TARGET_H8300S && !TARGET_NORMAL_MODE
2029 && REGNO (operands[0]) == 0
2030 && REGNO (operands[1]) == 1
2031 && REGNO (operands[2]) == 2
2032 && REGNO (operands[3]) == 3"
2033 "stm.l\\t%S0-%S3,@-er7"
2034 [(set_attr "cc" "none")
2035 (set_attr "length" "4")])
2036
2037 (define_insn "stm_h8300s_4_normal"
2038 [(parallel
2039 [(set (reg:HI SP_REG)
2040 (plus:HI (reg:HI SP_REG) (const_int -16)))
2041 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
2042 (match_operand:SI 0 "register_operand" ""))
2043 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
2044 (match_operand:SI 1 "register_operand" ""))
2045 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
2046 (match_operand:SI 2 "register_operand" ""))
2047 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
2048 (match_operand:SI 3 "register_operand" ""))])]
2049 "TARGET_H8300S && TARGET_NORMAL_MODE
2050 && REGNO (operands[0]) == 0
2051 && REGNO (operands[1]) == 1
2052 && REGNO (operands[2]) == 2
2053 && REGNO (operands[3]) == 3"
2054 "stm.l\\t%S0-%S3,@-er7"
2055 [(set_attr "cc" "none")
2056 (set_attr "length" "4")])
2057
2058 (define_expand "stm_h8300s_4"
2059 [(use (match_operand:SI 0 "register_operand" ""))
2060 (use (match_operand:SI 1 "register_operand" ""))
2061 (use (match_operand:SI 2 "register_operand" ""))
2062 (use (match_operand:SI 3 "register_operand" ""))]
2063 "TARGET_H8300S
2064 && REGNO (operands[0]) == 0
2065 && REGNO (operands[1]) == 1
2066 && REGNO (operands[2]) == 2
2067 && REGNO (operands[3]) == 3"
2068 "
2069 {
2070 if (!TARGET_NORMAL_MODE)
2071 emit_insn (gen_stm_h8300s_4_advanced (operands[0], operands[1],
2072 operands[2], operands[3]));
2073 else
2074 emit_insn (gen_stm_h8300s_4_normal (operands[0], operands[1],
2075 operands[2], operands[3]));
2076 DONE;
2077 }")
2078
2079 (define_insn "ldm_h8300s_2_advanced"
2080 [(parallel
2081 [(set (reg:SI SP_REG)
2082 (plus:SI (reg:SI SP_REG) (const_int 8)))
2083 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2084 (match_operand:SI 0 "register_operand" ""))
2085 (set (mem:SI (reg:SI SP_REG))
2086 (match_operand:SI 1 "register_operand" ""))])]
2087 "TARGET_H8300S && !TARGET_NORMAL_MODE
2088 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2089 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2090 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2091 "ldm.l\\t@er7+,%S0-%S1"
2092 [(set_attr "cc" "none")
2093 (set_attr "length" "4")])
2094
2095 (define_insn "ldm_h8300s_2_normal"
2096 [(parallel
2097 [(set (reg:HI SP_REG)
2098 (plus:HI (reg:HI SP_REG) (const_int 8)))
2099 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2100 (match_operand:SI 0 "register_operand" ""))
2101 (set (mem:SI (reg:HI SP_REG))
2102 (match_operand:SI 1 "register_operand" ""))])]
2103 "TARGET_H8300S && TARGET_NORMAL_MODE
2104 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2105 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2106 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2107 "ldm.l\\t@er7+,%S0-%S1"
2108 [(set_attr "cc" "none")
2109 (set_attr "length" "4")])
2110
2111 (define_expand "ldm_h8300s_2"
2112 [(use (match_operand:SI 0 "register_operand" ""))
2113 (use (match_operand:SI 1 "register_operand" ""))]
2114 "TARGET_H8300S
2115 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
2116 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
2117 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
2118 "
2119 {
2120 if (!TARGET_NORMAL_MODE)
2121 emit_insn (gen_ldm_h8300s_2_advanced (operands[0], operands[1]));
2122 else
2123 emit_insn (gen_ldm_h8300s_2_normal (operands[0], operands[1]));
2124 DONE;
2125 }")
2126
2127 (define_insn "ldm_h8300s_3_advanced"
2128 [(parallel
2129 [(set (reg:SI SP_REG)
2130 (plus:SI (reg:SI SP_REG) (const_int 12)))
2131 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
2132 (match_operand:SI 0 "register_operand" ""))
2133 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2134 (match_operand:SI 1 "register_operand" ""))
2135 (set (mem:SI (reg:SI SP_REG))
2136 (match_operand:SI 2 "register_operand" ""))])]
2137 "TARGET_H8300S && !TARGET_NORMAL_MODE
2138 && ((REGNO (operands[0]) == 0
2139 && REGNO (operands[1]) == 1
2140 && REGNO (operands[2]) == 2)
2141 || (REGNO (operands[0]) == 4
2142 && REGNO (operands[1]) == 5
2143 && REGNO (operands[2]) == 6))"
2144 "ldm.l\\t@er7+,%S0-%S2"
2145 [(set_attr "cc" "none")
2146 (set_attr "length" "4")])
2147
2148 (define_insn "ldm_h8300s_3_normal"
2149 [(parallel
2150 [(set (reg:HI SP_REG)
2151 (plus:HI (reg:HI SP_REG) (const_int 12)))
2152 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
2153 (match_operand:SI 0 "register_operand" ""))
2154 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2155 (match_operand:SI 1 "register_operand" ""))
2156 (set (mem:SI (reg:HI SP_REG))
2157 (match_operand:SI 2 "register_operand" ""))])]
2158 "TARGET_H8300S && TARGET_NORMAL_MODE
2159 && ((REGNO (operands[0]) == 0
2160 && REGNO (operands[1]) == 1
2161 && REGNO (operands[2]) == 2)
2162 || (REGNO (operands[0]) == 4
2163 && REGNO (operands[1]) == 5
2164 && REGNO (operands[2]) == 6))"
2165 "ldm.l\\t@er7+,%S0-%S2"
2166 [(set_attr "cc" "none")
2167 (set_attr "length" "4")])
2168
2169 (define_expand "ldm_h8300s_3"
2170 [(use (match_operand:SI 0 "register_operand" ""))
2171 (use (match_operand:SI 1 "register_operand" ""))
2172 (use (match_operand:SI 2 "register_operand" ""))]
2173 "TARGET_H8300S
2174 && ((REGNO (operands[0]) == 0
2175 && REGNO (operands[1]) == 1
2176 && REGNO (operands[2]) == 2)
2177 || (REGNO (operands[0]) == 4
2178 && REGNO (operands[1]) == 5
2179 && REGNO (operands[2]) == 6))"
2180 "
2181 {
2182 if (!TARGET_NORMAL_MODE)
2183 emit_insn (gen_ldm_h8300s_3_advanced (operands[0], operands[1],
2184 operands[2]));
2185 else
2186 emit_insn (gen_ldm_h8300s_3_normal (operands[0], operands[1],
2187 operands[2]));
2188 DONE;
2189 }")
2190
2191 (define_insn "ldm_h8300s_4_advanced"
2192 [(parallel
2193 [(set (reg:SI SP_REG)
2194 (plus:SI (reg:SI SP_REG) (const_int 16)))
2195 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 12)))
2196 (match_operand:SI 0 "register_operand" ""))
2197 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8)))
2198 (match_operand:SI 1 "register_operand" ""))
2199 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4)))
2200 (match_operand:SI 2 "register_operand" ""))
2201 (set (mem:SI (reg:SI SP_REG))
2202 (match_operand:SI 3 "register_operand" ""))])]
2203 "TARGET_H8300S && !TARGET_NORMAL_MODE
2204 && REGNO (operands[0]) == 0
2205 && REGNO (operands[1]) == 1
2206 && REGNO (operands[2]) == 2
2207 && REGNO (operands[3]) == 3"
2208 "ldm.l\\t@er7+,%S0-%S3"
2209 [(set_attr "cc" "none")
2210 (set_attr "length" "4")])
2211
2212 (define_insn "ldm_h8300s_4_normal"
2213 [(parallel
2214 [(set (reg:HI SP_REG)
2215 (plus:HI (reg:HI SP_REG) (const_int 16)))
2216 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 12)))
2217 (match_operand:SI 0 "register_operand" ""))
2218 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8)))
2219 (match_operand:SI 1 "register_operand" ""))
2220 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4)))
2221 (match_operand:SI 2 "register_operand" ""))
2222 (set (mem:SI (reg:HI SP_REG))
2223 (match_operand:SI 3 "register_operand" ""))])]
2224 "TARGET_H8300S && !TARGET_NORMAL_MODE
2225 && REGNO (operands[0]) == 0
2226 && REGNO (operands[1]) == 1
2227 && REGNO (operands[2]) == 2
2228 && REGNO (operands[3]) == 3"
2229 "ldm.l\\t@er7+,%S0-%S3"
2230 [(set_attr "cc" "none")
2231 (set_attr "length" "4")])
2232
2233 (define_expand "ldm_h8300s_4"
2234 [(use (match_operand:SI 0 "register_operand" ""))
2235 (use (match_operand:SI 1 "register_operand" ""))
2236 (use (match_operand:SI 2 "register_operand" ""))
2237 (use (match_operand:SI 3 "register_operand" ""))]
2238 "TARGET_H8300S && !TARGET_NORMAL_MODE
2239 && REGNO (operands[0]) == 0
2240 && REGNO (operands[1]) == 1
2241 && REGNO (operands[2]) == 2
2242 && REGNO (operands[3]) == 3"
2243 "
2244 {
2245 if (!TARGET_NORMAL_MODE)
2246 emit_insn (gen_ldm_h8300s_4_advanced (operands[0], operands[1],
2247 operands[2], operands[3]));
2248 else
2249 emit_insn (gen_ldm_h8300s_4_normal (operands[0], operands[1],
2250 operands[2], operands[3]));
2251 DONE;
2252 }")
2253
2254 (define_expand "return"
2255 [(return)]
2256 "h8300_can_use_return_insn_p ()"
2257 "")
2258
2259 (define_insn "*return_1"
2260 [(return)]
2261 "reload_completed"
2262 "*
2263 {
2264 if (h8300_current_function_interrupt_function_p ())
2265 return \"rte\";
2266 else
2267 return \"rts\";
2268 }"
2269 [(set_attr "cc" "none")
2270 (set_attr "length" "2")])
2271
2272 (define_expand "prologue"
2273 [(const_int 0)]
2274 ""
2275 "h8300_expand_prologue (); DONE;")
2276
2277 (define_expand "epilogue"
2278 [(return)]
2279 ""
2280 "h8300_expand_epilogue ();")
2281
2282 (define_insn "monitor_prologue"
2283 [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2284 ""
2285 "*
2286 {
2287 if (TARGET_H8300)
2288 return \"subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr\";
2289 else if (TARGET_H8300H)
2290 return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
2291 else if (TARGET_H8300S)
2292 return \"stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
2293 abort ();
2294 }"
2295 [(set_attr "length" "20")
2296 (set_attr "cc" "clobber")])
2297 \f
2298 ;; ----------------------------------------------------------------------
2299 ;; EXTEND INSTRUCTIONS
2300 ;; ----------------------------------------------------------------------
2301
2302 (define_expand "zero_extendqihi2"
2303 [(set (match_operand:HI 0 "register_operand" "")
2304 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2305 ""
2306 "")
2307
2308 (define_insn "*zero_extendqihi2_h8300"
2309 [(set (match_operand:HI 0 "register_operand" "=r,r")
2310 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2311 "TARGET_H8300"
2312 "@
2313 mov.b #0,%t0
2314 #"
2315 [(set_attr "length" "2,10")
2316 (set_attr "cc" "clobber,clobber")])
2317
2318 (define_insn "*zero_extendqihi2_h8300hs"
2319 [(set (match_operand:HI 0 "register_operand" "=r,r")
2320 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2321 "TARGET_H8300H || TARGET_H8300S"
2322 "@
2323 extu.w %T0
2324 #"
2325 [(set_attr "length" "2,10")
2326 (set_attr "cc" "set_znv,set_znv")])
2327
2328 ;; Split the zero extension of a general operand (actually a memory
2329 ;; operand) into a load of the operand and the actual zero extension
2330 ;; so that 1) the length will be accurate, and 2) the zero extensions
2331 ;; appearing at the end of basic blocks may be merged.
2332
2333 (define_split
2334 [(set (match_operand:HI 0 "register_operand" "")
2335 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2336 "reload_completed"
2337 [(set (match_dup 2)
2338 (match_dup 1))
2339 (set (match_dup 0)
2340 (zero_extend:HI (match_dup 2)))]
2341 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2342
2343 (define_expand "zero_extendqisi2"
2344 [(set (match_operand:SI 0 "register_operand" "")
2345 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2346 ""
2347 "")
2348
2349 (define_insn "*zero_extendqisi2_h8300"
2350 [(set (match_operand:SI 0 "register_operand" "=r,r")
2351 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2352 "TARGET_H8300"
2353 "@
2354 mov.b #0,%x0\;sub.w %e0,%e0
2355 mov.b %R1,%w0\;mov.b #0,%x0\;sub.w %e0,%e0"
2356 [(set_attr "length" "4,8")
2357 (set_attr "cc" "clobber,clobber")])
2358
2359 (define_insn "*zero_extendqisi2_h8300hs"
2360 [(set (match_operand:SI 0 "register_operand" "=r,r")
2361 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2362 "TARGET_H8300H || TARGET_H8300S"
2363 "#")
2364
2365 (define_split
2366 [(set (match_operand:SI 0 "register_operand" "")
2367 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2368 "(TARGET_H8300H || TARGET_H8300S)
2369 && reg_overlap_mentioned_p (operands[0], operands[1])
2370 && reload_completed"
2371 [(set (match_dup 2)
2372 (match_dup 1))
2373 (set (match_dup 3)
2374 (zero_extend:HI (match_dup 2)))
2375 (set (match_dup 0)
2376 (zero_extend:SI (match_dup 3)))]
2377 "operands[2] = gen_lowpart (QImode, operands[0]);
2378 operands[3] = gen_lowpart (HImode, operands[0]);")
2379
2380 (define_split
2381 [(set (match_operand:SI 0 "register_operand" "")
2382 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2383 "(TARGET_H8300H || TARGET_H8300S)
2384 && !reg_overlap_mentioned_p (operands[0], operands[1])
2385 && reload_completed"
2386 [(set (match_dup 0)
2387 (const_int 0))
2388 (set (strict_low_part (match_dup 2))
2389 (match_dup 1))]
2390 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2391
2392 (define_expand "zero_extendhisi2"
2393 [(set (match_operand:SI 0 "register_operand" "")
2394 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2395 ""
2396 "")
2397
2398 ;; %e prints the high part of a CONST_INT, not the low part. Arggh.
2399 (define_insn "*zero_extendhisi2_h8300"
2400 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2401 (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2402 "TARGET_H8300"
2403 "@
2404 sub.w %e0,%e0
2405 mov.w %f1,%f0\;sub.w %e0,%e0
2406 mov.w %e1,%f0\;sub.w %e0,%e0"
2407 [(set_attr "length" "2,4,6")
2408 (set_attr "cc" "clobber,clobber,clobber")])
2409
2410 (define_insn "*zero_extendhisi2_h8300hs"
2411 [(set (match_operand:SI 0 "register_operand" "=r")
2412 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2413 "TARGET_H8300H || TARGET_H8300S"
2414 "extu.l %S0"
2415 [(set_attr "length" "2")
2416 (set_attr "cc" "set_znv")])
2417
2418 (define_expand "extendqihi2"
2419 [(set (match_operand:HI 0 "register_operand" "")
2420 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2421 ""
2422 "")
2423
2424 (define_insn "*extendqihi2_h8300"
2425 [(set (match_operand:HI 0 "register_operand" "=r,r")
2426 (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2427 "TARGET_H8300"
2428 "@
2429 bld #7,%s0\;subx %t0,%t0
2430 mov.b %R1,%s0\;bld #7,%s0\;subx %t0,%t0"
2431 [(set_attr "length" "4,8")
2432 (set_attr "cc" "clobber,clobber")])
2433
2434 (define_insn "*extendqihi2_h8300hs"
2435 [(set (match_operand:HI 0 "register_operand" "=r")
2436 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2437 "TARGET_H8300H || TARGET_H8300S"
2438 "exts.w %T0"
2439 [(set_attr "length" "2")
2440 (set_attr "cc" "set_znv")])
2441
2442 (define_expand "extendqisi2"
2443 [(set (match_operand:SI 0 "register_operand" "")
2444 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2445 ""
2446 "")
2447
2448 (define_insn "*extendqisi2_h8300"
2449 [(set (match_operand:SI 0 "register_operand" "")
2450 (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2451 "TARGET_H8300"
2452 "@
2453 bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0
2454 mov.b %R1,%w0\;bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0"
2455 [(set_attr "length" "8,12")
2456 (set_attr "cc" "clobber,clobber")])
2457
2458 ;; The following pattern is needed because without the pattern, the
2459 ;; combiner would split (sign_extend:SI (reg:QI)) into into two 24-bit
2460 ;; shifts, one ashift and one ashiftrt.
2461
2462 (define_insn_and_split "*extendqisi2_h8300hs"
2463 [(set (match_operand:SI 0 "register_operand" "=r")
2464 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2465 "(TARGET_H8300H || TARGET_H8300S)"
2466 "#"
2467 "&& reload_completed"
2468 [(set (match_dup 2)
2469 (sign_extend:HI (match_dup 1)))
2470 (set (match_dup 0)
2471 (sign_extend:SI (match_dup 2)))]
2472 "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
2473
2474 (define_expand "extendhisi2"
2475 [(set (match_operand:SI 0 "register_operand" "")
2476 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2477 ""
2478 "")
2479
2480 (define_insn "*extendhisi2_h8300"
2481 [(set (match_operand:SI 0 "register_operand" "=r,r")
2482 (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2483 "TARGET_H8300"
2484 "@
2485 bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0
2486 mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0"
2487 [(set_attr "length" "6,10")
2488 (set_attr "cc" "clobber,clobber")])
2489
2490 (define_insn "*extendhisi2_h8300hs"
2491 [(set (match_operand:SI 0 "register_operand" "=r")
2492 (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2493 "TARGET_H8300H || TARGET_H8300S"
2494 "exts.l %S0"
2495 [(set_attr "length" "2")
2496 (set_attr "cc" "set_znv")])
2497 \f
2498 ;; ----------------------------------------------------------------------
2499 ;; SHIFTS
2500 ;; ----------------------------------------------------------------------
2501 ;;
2502 ;; We make some attempt to provide real efficient shifting. One example is
2503 ;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
2504 ;; reg and moving 0 into the former reg.
2505 ;;
2506 ;; We also try to achieve this in a uniform way. IE: We don't try to achieve
2507 ;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would
2508 ;; give the optimizer more cracks at the code. However, we wish to do things
2509 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2510 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2511 ;; 16 bit rotates. Also, if we emit complicated rtl, combine may not be able
2512 ;; to detect cases it can optimize.
2513 ;;
2514 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
2515 ;; easier "do it at insn emit time" route.
2516
2517 ;; QI BIT SHIFTS
2518
2519 (define_expand "ashlqi3"
2520 [(set (match_operand:QI 0 "register_operand" "")
2521 (ashift:QI (match_operand:QI 1 "register_operand" "")
2522 (match_operand:QI 2 "nonmemory_operand" "")))]
2523 ""
2524 "expand_a_shift (QImode, ASHIFT, operands); DONE;")
2525
2526 (define_expand "ashrqi3"
2527 [(set (match_operand:QI 0 "register_operand" "")
2528 (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2529 (match_operand:QI 2 "nonmemory_operand" "")))]
2530 ""
2531 "expand_a_shift (QImode, ASHIFTRT, operands); DONE;")
2532
2533 (define_expand "lshrqi3"
2534 [(set (match_operand:QI 0 "register_operand" "")
2535 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2536 (match_operand:QI 2 "nonmemory_operand" "")))]
2537 ""
2538 "expand_a_shift (QImode, LSHIFTRT, operands); DONE;")
2539
2540 (define_insn "*shiftqi"
2541 [(set (match_operand:QI 0 "register_operand" "=r,r")
2542 (match_operator:QI 3 "nshift_operator"
2543 [ (match_operand:QI 1 "register_operand" "0,0")
2544 (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2545 (clobber (match_scratch:QI 4 "=X,&r"))]
2546 ""
2547 "* return output_a_shift (operands);"
2548 [(set (attr "length")
2549 (symbol_ref "compute_a_shift_length (insn, operands)"))
2550 (set (attr "cc")
2551 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2552
2553 ;; HI BIT SHIFTS
2554
2555 (define_expand "ashlhi3"
2556 [(set (match_operand:HI 0 "register_operand" "")
2557 (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
2558 (match_operand:QI 2 "nonmemory_operand" "")))]
2559 ""
2560 "expand_a_shift (HImode, ASHIFT, operands); DONE;")
2561
2562 (define_expand "lshrhi3"
2563 [(set (match_operand:HI 0 "register_operand" "")
2564 (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
2565 (match_operand:QI 2 "nonmemory_operand" "")))]
2566 ""
2567 "expand_a_shift (HImode, LSHIFTRT, operands); DONE;")
2568
2569 (define_expand "ashrhi3"
2570 [(set (match_operand:HI 0 "register_operand" "")
2571 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2572 (match_operand:QI 2 "nonmemory_operand" "")))]
2573 ""
2574 "expand_a_shift (HImode, ASHIFTRT, operands); DONE;")
2575
2576 (define_insn "*shifthi"
2577 [(set (match_operand:HI 0 "register_operand" "=r,r")
2578 (match_operator:HI 3 "nshift_operator"
2579 [ (match_operand:HI 1 "register_operand" "0,0")
2580 (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
2581 (clobber (match_scratch:QI 4 "=X,&r"))]
2582 ""
2583 "* return output_a_shift (operands);"
2584 [(set (attr "length")
2585 (symbol_ref "compute_a_shift_length (insn, operands)"))
2586 (set (attr "cc")
2587 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2588
2589 ;; SI BIT SHIFTS
2590
2591 (define_expand "ashlsi3"
2592 [(set (match_operand:SI 0 "register_operand" "")
2593 (ashift:SI (match_operand:SI 1 "general_operand" "")
2594 (match_operand:QI 2 "nonmemory_operand" "")))]
2595 ""
2596 "expand_a_shift (SImode, ASHIFT, operands); DONE;")
2597
2598 (define_expand "lshrsi3"
2599 [(set (match_operand:SI 0 "register_operand" "")
2600 (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
2601 (match_operand:QI 2 "nonmemory_operand" "")))]
2602 ""
2603 "expand_a_shift (SImode, LSHIFTRT, operands); DONE;")
2604
2605 (define_expand "ashrsi3"
2606 [(set (match_operand:SI 0 "register_operand" "")
2607 (ashiftrt:SI (match_operand:SI 1 "general_operand" "")
2608 (match_operand:QI 2 "nonmemory_operand" "")))]
2609 ""
2610 "expand_a_shift (SImode, ASHIFTRT, operands); DONE;")
2611
2612 (define_insn "*shiftsi"
2613 [(set (match_operand:SI 0 "register_operand" "=r,r")
2614 (match_operator:SI 3 "nshift_operator"
2615 [ (match_operand:SI 1 "register_operand" "0,0")
2616 (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2617 (clobber (match_scratch:QI 4 "=X,&r"))]
2618 ""
2619 "* return output_a_shift (operands);"
2620 [(set (attr "length")
2621 (symbol_ref "compute_a_shift_length (insn, operands)"))
2622 (set (attr "cc")
2623 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2624
2625 ;; Split a variable shift into a loop. If the register containing
2626 ;; the shift count dies, then we just use that register.
2627
2628 (define_split
2629 [(parallel
2630 [(set (match_operand 0 "register_operand" "")
2631 (match_operator 2 "nshift_operator"
2632 [(match_dup 0)
2633 (match_operand:QI 1 "register_operand" "")]))
2634 (clobber (match_operand:QI 3 "register_operand" ""))])]
2635 "flow2_completed
2636 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2637 [(set (cc0)
2638 (match_dup 1))
2639 (set (pc)
2640 (if_then_else (le (cc0) (const_int 0))
2641 (label_ref (match_dup 5))
2642 (pc)))
2643 (match_dup 4)
2644 (parallel
2645 [(set (match_dup 0)
2646 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2647 (clobber (scratch:QI))])
2648 (set (match_dup 1)
2649 (plus:QI (match_dup 1) (const_int -1)))
2650 (set (cc0)
2651 (match_dup 1))
2652 (set (pc)
2653 (if_then_else (ne (cc0) (const_int 0))
2654 (label_ref (match_dup 4))
2655 (pc)))
2656 (match_dup 5)]
2657 "operands[4] = gen_label_rtx ();
2658 operands[5] = gen_label_rtx ();")
2659
2660 (define_split
2661 [(parallel
2662 [(set (match_operand 0 "register_operand" "")
2663 (match_operator 2 "nshift_operator"
2664 [(match_dup 0)
2665 (match_operand:QI 1 "register_operand" "")]))
2666 (clobber (match_operand:QI 3 "register_operand" ""))])]
2667 "flow2_completed
2668 && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2669 [(set (match_dup 3)
2670 (match_dup 1))
2671 (set (cc0)
2672 (match_dup 3))
2673 (set (pc)
2674 (if_then_else (le (cc0) (const_int 0))
2675 (label_ref (match_dup 5))
2676 (pc)))
2677 (match_dup 4)
2678 (parallel
2679 [(set (match_dup 0)
2680 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2681 (clobber (scratch:QI))])
2682 (set (match_dup 3)
2683 (plus:QI (match_dup 3) (const_int -1)))
2684 (set (cc0)
2685 (match_dup 3))
2686 (set (pc)
2687 (if_then_else (ne (cc0) (const_int 0))
2688 (label_ref (match_dup 4))
2689 (pc)))
2690 (match_dup 5)]
2691 "operands[4] = gen_label_rtx ();
2692 operands[5] = gen_label_rtx ();")
2693 \f
2694 ;; ----------------------------------------------------------------------
2695 ;; ROTATIONS
2696 ;; ----------------------------------------------------------------------
2697
2698 (define_expand "rotlqi3"
2699 [(set (match_operand:QI 0 "register_operand" "")
2700 (rotate:QI (match_operand:QI 1 "register_operand" "")
2701 (match_operand:QI 2 "nonmemory_operand" "")))]
2702 ""
2703 "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2704
2705 (define_insn "*rotlqi3_1"
2706 [(set (match_operand:QI 0 "register_operand" "=r")
2707 (rotate:QI (match_operand:QI 1 "register_operand" "0")
2708 (match_operand:QI 2 "immediate_operand" "")))]
2709 ""
2710 "* return output_a_rotate (ROTATE, operands);"
2711 [(set (attr "length")
2712 (symbol_ref "compute_a_rotate_length (operands)"))
2713 (set_attr "cc" "clobber")])
2714
2715 (define_expand "rotlhi3"
2716 [(set (match_operand:HI 0 "register_operand" "")
2717 (rotate:HI (match_operand:HI 1 "register_operand" "")
2718 (match_operand:QI 2 "nonmemory_operand" "")))]
2719 ""
2720 "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2721
2722 (define_insn "*rotlhi3_1"
2723 [(set (match_operand:HI 0 "register_operand" "=r")
2724 (rotate:HI (match_operand:HI 1 "register_operand" "0")
2725 (match_operand:QI 2 "immediate_operand" "")))]
2726 ""
2727 "* return output_a_rotate (ROTATE, operands);"
2728 [(set (attr "length")
2729 (symbol_ref "compute_a_rotate_length (operands)"))
2730 (set_attr "cc" "clobber")])
2731
2732 (define_expand "rotlsi3"
2733 [(set (match_operand:SI 0 "register_operand" "")
2734 (rotate:SI (match_operand:SI 1 "register_operand" "")
2735 (match_operand:QI 2 "nonmemory_operand" "")))]
2736 "TARGET_H8300H || TARGET_H8300S"
2737 "if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;")
2738
2739 (define_insn "*rotlsi3_1"
2740 [(set (match_operand:SI 0 "register_operand" "=r")
2741 (rotate:SI (match_operand:SI 1 "register_operand" "0")
2742 (match_operand:QI 2 "immediate_operand" "")))]
2743 "TARGET_H8300H || TARGET_H8300S"
2744 "* return output_a_rotate (ROTATE, operands);"
2745 [(set (attr "length")
2746 (symbol_ref "compute_a_rotate_length (operands)"))
2747 (set_attr "cc" "clobber")])
2748 \f
2749 ;; -----------------------------------------------------------------
2750 ;; BIT FIELDS
2751 ;; -----------------------------------------------------------------
2752 ;; The H8/300 has given 1/8th of its opcode space to bitfield
2753 ;; instructions so let's use them as well as we can.
2754
2755 ;; You'll never believe all these patterns perform one basic action --
2756 ;; load a bit from the source, optionally invert the bit, then store it
2757 ;; in the destination (which is known to be zero).
2758 ;;
2759 ;; Combine obviously need some work to better identify this situation and
2760 ;; canonicalize the form better.
2761
2762 ;;
2763 ;; Normal loads with a 16bit destination.
2764 ;;
2765
2766 (define_insn ""
2767 [(set (match_operand:HI 0 "register_operand" "=&r")
2768 (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2769 (const_int 1)
2770 (match_operand:HI 2 "immediate_operand" "n")))]
2771 "TARGET_H8300"
2772 "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0"
2773 [(set_attr "cc" "clobber")
2774 (set_attr "length" "6")])
2775
2776 ;;
2777 ;; Inverted loads with a 16bit destination.
2778 ;;
2779
2780 (define_insn ""
2781 [(set (match_operand:HI 0 "register_operand" "=&r")
2782 (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2783 (match_operand:HI 3 "const_int_operand" "n"))
2784 (const_int 1)
2785 (match_operand:HI 2 "const_int_operand" "n")))]
2786 "TARGET_H8300
2787 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2788 "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
2789 [(set_attr "cc" "clobber")
2790 (set_attr "length" "8")])
2791
2792 ;;
2793 ;; Normal loads with a 32bit destination.
2794 ;;
2795
2796 (define_insn "*extzv_1_r_h8300"
2797 [(set (match_operand:SI 0 "register_operand" "=&r")
2798 (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
2799 (const_int 1)
2800 (match_operand 2 "const_int_operand" "n")))]
2801 "TARGET_H8300
2802 && INTVAL (operands[2]) < 16"
2803 "* return output_simode_bld (0, operands);"
2804 [(set_attr "cc" "clobber")
2805 (set_attr "length" "8")])
2806
2807 (define_insn "*extzv_1_r_h8300hs"
2808 [(set (match_operand:SI 0 "register_operand" "=r,r")
2809 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2810 (const_int 1)
2811 (match_operand 2 "const_int_operand" "n,n")))]
2812 "(TARGET_H8300H || TARGET_H8300S)
2813 && INTVAL (operands[2]) < 16"
2814 "* return output_simode_bld (0, operands);"
2815 [(set_attr "cc" "set_znv,set_znv")
2816 (set_attr "length" "8,6")])
2817
2818 ;;
2819 ;; Inverted loads with a 32bit destination.
2820 ;;
2821
2822 (define_insn "*extzv_1_r_inv_h8300"
2823 [(set (match_operand:SI 0 "register_operand" "=&r")
2824 (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
2825 (match_operand:HI 3 "const_int_operand" "n"))
2826 (const_int 1)
2827 (match_operand 2 "const_int_operand" "n")))]
2828 "TARGET_H8300
2829 && INTVAL (operands[2]) < 16
2830 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2831 "* return output_simode_bld (1, operands);"
2832 [(set_attr "cc" "clobber")
2833 (set_attr "length" "8")])
2834
2835 (define_insn "*extzv_1_r_inv_h8300hs"
2836 [(set (match_operand:SI 0 "register_operand" "=r,r")
2837 (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
2838 (match_operand 3 "const_int_operand" "n,n"))
2839 (const_int 1)
2840 (match_operand 2 "const_int_operand" "n,n")))]
2841 "(TARGET_H8300H || TARGET_H8300S)
2842 && INTVAL (operands[2]) < 16
2843 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2844 "* return output_simode_bld (1, operands);"
2845 [(set_attr "cc" "set_znv,set_znv")
2846 (set_attr "length" "8,6")])
2847
2848 (define_expand "insv"
2849 [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2850 (match_operand:HI 1 "general_operand" "")
2851 (match_operand:HI 2 "general_operand" ""))
2852 (match_operand:HI 3 "general_operand" ""))]
2853 "TARGET_H8300"
2854 "
2855 {
2856 /* We only have single bit bit-field instructions. */
2857 if (INTVAL (operands[1]) != 1)
2858 FAIL;
2859
2860 /* For now, we don't allow memory operands. */
2861 if (GET_CODE (operands[0]) == MEM
2862 || GET_CODE (operands[3]) == MEM)
2863 FAIL;
2864 }")
2865
2866 (define_insn ""
2867 [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
2868 (const_int 1)
2869 (match_operand:HI 1 "immediate_operand" "n"))
2870 (match_operand:HI 2 "register_operand" "r"))]
2871 ""
2872 "bld #0,%R2\;bst %Z1,%Y0 ; i1"
2873 [(set_attr "cc" "clobber")
2874 (set_attr "length" "4")])
2875
2876 (define_expand "extzv"
2877 [(set (match_operand:HI 0 "register_operand" "")
2878 (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
2879 (match_operand:HI 2 "general_operand" "")
2880 (match_operand:HI 3 "general_operand" "")))]
2881 "TARGET_H8300"
2882 "
2883 {
2884 /* We only have single bit bit-field instructions. */
2885 if (INTVAL (operands[2]) != 1)
2886 FAIL;
2887
2888 /* For now, we don't allow memory operands. */
2889 if (GET_CODE (operands[1]) == MEM)
2890 FAIL;
2891 }")
2892
2893 ;; BAND, BOR, and BXOR patterns
2894
2895 (define_insn ""
2896 [(set (match_operand:HI 0 "bit_operand" "=Ur")
2897 (match_operator:HI 4 "bit_operator"
2898 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2899 (const_int 1)
2900 (match_operand:HI 2 "immediate_operand" "n"))
2901 (match_operand:HI 3 "bit_operand" "0")]))]
2902 ""
2903 "bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1"
2904 [(set_attr "cc" "clobber")
2905 (set_attr "length" "6")])
2906
2907 (define_insn ""
2908 [(set (match_operand:HI 0 "bit_operand" "=Ur")
2909 (match_operator:HI 5 "bit_operator"
2910 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2911 (const_int 1)
2912 (match_operand:HI 2 "immediate_operand" "n"))
2913 (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
2914 (const_int 1)
2915 (match_operand:HI 4 "immediate_operand" "n"))]))]
2916 ""
2917 "bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3"
2918 [(set_attr "cc" "clobber")
2919 (set_attr "length" "6")])
2920 \f
2921 ;; -----------------------------------------------------------------
2922 ;; COMBINE PATTERNS
2923 ;; -----------------------------------------------------------------
2924
2925 ;; insv:SI
2926
2927 (define_insn "*insv_si_1_n"
2928 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2929 (const_int 1)
2930 (match_operand:SI 1 "const_int_operand" "n"))
2931 (match_operand:SI 2 "register_operand" "r"))]
2932 "(TARGET_H8300H || TARGET_H8300S)
2933 && INTVAL (operands[1]) < 16"
2934 "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
2935 [(set_attr "cc" "clobber")
2936 (set_attr "length" "4")])
2937
2938 (define_insn "*insv_si_1_n_lshiftrt"
2939 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2940 (const_int 1)
2941 (match_operand:SI 1 "const_int_operand" "n"))
2942 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2943 (match_operand:SI 3 "const_int_operand" "n")))]
2944 "(TARGET_H8300H || TARGET_H8300S)
2945 && INTVAL (operands[1]) < 16
2946 && INTVAL (operands[3]) < 16"
2947 "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
2948 [(set_attr "cc" "clobber")
2949 (set_attr "length" "4")])
2950
2951 (define_insn "*insv_si_1_n_lshiftrt_16"
2952 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2953 (const_int 1)
2954 (match_operand:SI 1 "const_int_operand" "n"))
2955 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2956 (const_int 16)))]
2957 "(TARGET_H8300H || TARGET_H8300S)
2958 && INTVAL (operands[1]) < 16"
2959 "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
2960 [(set_attr "cc" "clobber")
2961 (set_attr "length" "6")])
2962
2963 (define_insn "*insv_si_8_8"
2964 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2965 (const_int 8)
2966 (const_int 8))
2967 (match_operand:SI 1 "register_operand" "r"))]
2968 "TARGET_H8300H || TARGET_H8300S"
2969 "mov.b\\t%w1,%x0"
2970 [(set_attr "cc" "clobber")
2971 (set_attr "length" "2")])
2972
2973 (define_insn "*insv_si_8_8_lshiftrt_8"
2974 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2975 (const_int 8)
2976 (const_int 8))
2977 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2978 (const_int 8)))]
2979 "TARGET_H8300H || TARGET_H8300S"
2980 "mov.b\\t%x1,%x0"
2981 [(set_attr "cc" "clobber")
2982 (set_attr "length" "2")])
2983
2984 ;; extzv:SI
2985
2986 (define_insn "*extzv_8_8"
2987 [(set (match_operand:SI 0 "register_operand" "=r,r")
2988 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2989 (const_int 8)
2990 (const_int 8)))]
2991 "TARGET_H8300H || TARGET_H8300S"
2992 "@
2993 mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
2994 sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
2995 [(set_attr "cc" "set_znv,clobber")
2996 (set_attr "length" "6,4")])
2997
2998 (define_insn "*extzv_8_16"
2999 [(set (match_operand:SI 0 "register_operand" "=r")
3000 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3001 (const_int 8)
3002 (const_int 16)))]
3003 "TARGET_H8300H || TARGET_H8300S"
3004 "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3005 [(set_attr "cc" "set_znv")
3006 (set_attr "length" "6")])
3007
3008 (define_insn "*extzv_16_8"
3009 [(set (match_operand:SI 0 "register_operand" "=r")
3010 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3011 (const_int 16)
3012 (const_int 8)))
3013 (clobber (match_scratch:SI 2 "=&r"))]
3014 "TARGET_H8300H"
3015 "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3016 [(set_attr "length" "8")
3017 (set_attr "cc" "set_znv")])
3018
3019 ;; Extract the exponent of a float.
3020
3021 (define_insn_and_split "*extzv_8_23"
3022 [(set (match_operand:SI 0 "register_operand" "=r")
3023 (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3024 (const_int 8)
3025 (const_int 23)))]
3026 "(TARGET_H8300H || TARGET_H8300S)"
3027 "#"
3028 "&& reload_completed"
3029 [(parallel [(set (match_dup 0)
3030 (ashift:SI (match_dup 0)
3031 (const_int 1)))
3032 (clobber (scratch:QI))])
3033 (parallel [(set (match_dup 0)
3034 (lshiftrt:SI (match_dup 0)
3035 (const_int 24)))
3036 (clobber (scratch:QI))])]
3037 "")
3038
3039 ;; and:SI
3040
3041 ;; ((SImode) HImode) << 15
3042
3043 (define_insn_and_split "*twoshifts_l16_r1"
3044 [(set (match_operand:SI 0 "register_operand" "=r")
3045 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3046 (const_int 15))
3047 (const_int 2147450880)))]
3048 "(TARGET_H8300H || TARGET_H8300S)"
3049 "#"
3050 "&& reload_completed"
3051 [(parallel [(set (match_dup 0)
3052 (ashift:SI (match_dup 0)
3053 (const_int 16)))
3054 (clobber (scratch:QI))])
3055 (parallel [(set (match_dup 0)
3056 (lshiftrt:SI (match_dup 0)
3057 (const_int 1)))
3058 (clobber (scratch:QI))])]
3059 "")
3060
3061 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3062
3063 (define_insn_and_split "*andsi3_ashift_n_lower"
3064 [(set (match_operand:SI 0 "register_operand" "=r,r")
3065 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3066 (match_operand:QI 2 "const_int_operand" "S,n"))
3067 (match_operand:SI 3 "const_int_operand" "n,n")))
3068 (clobber (match_scratch:QI 4 "=X,&r"))]
3069 "(TARGET_H8300H || TARGET_H8300S)
3070 && INTVAL (operands[2]) <= 15
3071 && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
3072 "#"
3073 "&& reload_completed"
3074 [(parallel [(set (match_dup 5)
3075 (ashift:HI (match_dup 5)
3076 (match_dup 2)))
3077 (clobber (match_dup 4))])
3078 (set (match_dup 0)
3079 (zero_extend:SI (match_dup 5)))]
3080 "operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3081
3082 ;; Accept (A >> 30) & 2 and the like.
3083
3084 (define_insn "*andsi3_lshiftrt_n_sb"
3085 [(set (match_operand:SI 0 "register_operand" "=r")
3086 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3087 (match_operand:SI 2 "const_int_operand" "n"))
3088 (match_operand:SI 3 "single_one_operand" "n")))]
3089 "(TARGET_H8300H || TARGET_H8300S)
3090 && exact_log2 (INTVAL (operands[3])) < 16
3091 && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3092 "*
3093 {
3094 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3095 return \"shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0\";
3096 }"
3097 [(set_attr "length" "8")
3098 (set_attr "cc" "clobber")])
3099
3100 (define_insn_and_split "*andsi3_lshiftrt_9_sb"
3101 [(set (match_operand:SI 0 "register_operand" "=r")
3102 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3103 (const_int 9))
3104 (const_int 4194304)))]
3105 "(TARGET_H8300H || TARGET_H8300S)"
3106 "#"
3107 "&& reload_completed"
3108 [(set (match_dup 0)
3109 (and:SI (lshiftrt:SI (match_dup 0)
3110 (const_int 25))
3111 (const_int 64)))
3112 (parallel [(set (match_dup 0)
3113 (ashift:SI (match_dup 0)
3114 (const_int 16)))
3115 (clobber (scratch:QI))])]
3116 "")
3117
3118 ;; plus:SI
3119
3120 (define_insn "*addsi3_upper"
3121 [(set (match_operand:SI 0 "register_operand" "=r")
3122 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3123 (const_int 65536))
3124 (match_operand:SI 2 "register_operand" "0")))]
3125 "TARGET_H8300H || TARGET_H8300S"
3126 "add.w\\t%f1,%e0"
3127 [(set_attr "length" "2")
3128 (set_attr "cc" "clobber")])
3129
3130 (define_insn "*addsi3_lshiftrt_16_zexthi"
3131 [(set (match_operand:SI 0 "register_operand" "=r")
3132 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3133 (const_int 16))
3134 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3135 "TARGET_H8300H || TARGET_H8300S"
3136 "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3137 [(set_attr "cc" "clobber")
3138 (set_attr "length" "6")])
3139
3140 (define_insn_and_split "*addsi3_and_r_1"
3141 [(set (match_operand:SI 0 "register_operand" "=r")
3142 (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3143 (const_int 1))
3144 (match_operand:SI 2 "register_operand" "0")))]
3145 "(TARGET_H8300H || TARGET_H8300S)"
3146 "#"
3147 "&& reload_completed"
3148 [(set (cc0)
3149 (zero_extract:SI (match_dup 1)
3150 (const_int 1)
3151 (const_int 0)))
3152 (set (pc)
3153 (if_then_else (eq (cc0)
3154 (const_int 0))
3155 (label_ref (match_dup 3))
3156 (pc)))
3157 (set (match_dup 2)
3158 (plus:SI (match_dup 2)
3159 (const_int 1)))
3160 (match_dup 3)]
3161 "operands[3] = gen_label_rtx ();")
3162
3163 (define_insn_and_split "*addsi3_and_not_r_1"
3164 [(set (match_operand:SI 0 "register_operand" "=r")
3165 (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3166 (const_int 1))
3167 (match_operand:SI 2 "register_operand" "0")))]
3168 "(TARGET_H8300H || TARGET_H8300S)"
3169 "#"
3170 "&& reload_completed"
3171 [(set (cc0)
3172 (zero_extract:SI (match_dup 1)
3173 (const_int 1)
3174 (const_int 0)))
3175 (set (pc)
3176 (if_then_else (ne (cc0)
3177 (const_int 0))
3178 (label_ref (match_dup 3))
3179 (pc)))
3180 (set (match_dup 2)
3181 (plus:SI (match_dup 2)
3182 (const_int 1)))
3183 (match_dup 3)]
3184 "operands[3] = gen_label_rtx ();")
3185
3186 ;; [ix]or:HI
3187
3188 (define_insn "*ixorhi3_zext"
3189 [(set (match_operand:HI 0 "register_operand" "=r")
3190 (match_operator:HI 1 "iorxor_operator"
3191 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
3192 (match_operand:HI 3 "register_operand" "0")]))]
3193 ""
3194 "%c1.b\\t%X2,%s0"
3195 [(set_attr "cc" "clobber")
3196 (set_attr "length" "2")])
3197
3198 ;; [ix]or:SI
3199
3200 (define_insn "*ixorsi3_zext_qi"
3201 [(set (match_operand:SI 0 "register_operand" "=r")
3202 (match_operator:SI 1 "iorxor_operator"
3203 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
3204 (match_operand:SI 3 "register_operand" "0")]))]
3205 ""
3206 "%c1.b\\t%X2,%w0"
3207 [(set_attr "cc" "clobber")
3208 (set_attr "length" "2")])
3209
3210 (define_insn "*ixorsi3_zext_hi"
3211 [(set (match_operand:SI 0 "register_operand" "=r")
3212 (match_operator:SI 1 "iorxor_operator"
3213 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
3214 (match_operand:SI 3 "register_operand" "0")]))]
3215 "TARGET_H8300H || TARGET_H8300S"
3216 "%c1.w\\t%T2,%f0"
3217 [(set_attr "cc" "clobber")
3218 (set_attr "length" "2")])
3219
3220 (define_insn "*ixorsi3_ashift_16"
3221 [(set (match_operand:SI 0 "register_operand" "=r")
3222 (match_operator:SI 1 "iorxor_operator"
3223 [(ashift:SI (match_operand:SI 2 "register_operand" "r")
3224 (const_int 16))
3225 (match_operand:SI 3 "register_operand" "0")]))]
3226 "TARGET_H8300H || TARGET_H8300S"
3227 "%c1.w\\t%f2,%e0"
3228 [(set_attr "cc" "clobber")
3229 (set_attr "length" "2")])
3230
3231 (define_insn "*ixorsi3_lshiftrt_16"
3232 [(set (match_operand:SI 0 "register_operand" "=r")
3233 (match_operator:SI 1 "iorxor_operator"
3234 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3235 (const_int 16))
3236 (match_operand:SI 3 "register_operand" "0")]))]
3237 "TARGET_H8300H || TARGET_H8300S"
3238 "%c1.w\\t%e2,%f0"
3239 [(set_attr "cc" "clobber")
3240 (set_attr "length" "2")])
3241
3242 ;; ior:HI
3243
3244 (define_insn "*iorhi3_ashift_8"
3245 [(set (match_operand:HI 0 "register_operand" "=r")
3246 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
3247 (const_int 8))
3248 (match_operand:HI 2 "register_operand" "0")))]
3249 ""
3250 "or.b\\t%s1,%t0"
3251 [(set_attr "cc" "clobber")
3252 (set_attr "length" "2")])
3253
3254 (define_insn "*iorhi3_lshiftrt_8"
3255 [(set (match_operand:HI 0 "register_operand" "=r")
3256 (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3257 (const_int 8))
3258 (match_operand:HI 2 "register_operand" "0")))]
3259 ""
3260 "or.b\\t%t1,%s0"
3261 [(set_attr "cc" "clobber")
3262 (set_attr "length" "2")])
3263
3264 (define_insn "*iorhi3_two_qi"
3265 [(set (match_operand:HI 0 "register_operand" "=r")
3266 (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
3267 (ashift:HI (match_operand:HI 2 "register_operand" "r")
3268 (const_int 8))))]
3269 ""
3270 "mov.b\\t%s2,%t0"
3271 [(set_attr "cc" "clobber")
3272 (set_attr "length" "2")])
3273
3274 (define_insn "*iorhi3_two_qi_mem"
3275 [(set (match_operand:HI 0 "register_operand" "=&r")
3276 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
3277 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
3278 (const_int 8))))]
3279 ""
3280 "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
3281 [(set_attr "cc" "clobber")
3282 (set_attr "length" "16")])
3283
3284 (define_split
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
3287 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
3288 (const_int 8))))]
3289 "(TARGET_H8300H || TARGET_H8300S)
3290 && reload_completed
3291 && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
3292 [(set (match_dup 0)
3293 (match_dup 3))]
3294 "operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));")
3295
3296 ;; ior:SI
3297
3298 (define_insn "*iorsi3_two_hi"
3299 [(set (match_operand:SI 0 "register_operand" "=r")
3300 (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
3301 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3302 (const_int 16))))]
3303 "TARGET_H8300H || TARGET_H8300S"
3304 "mov.w\\t%f2,%e0"
3305 [(set_attr "cc" "clobber")
3306 (set_attr "length" "2")])
3307
3308 (define_insn_and_split "*iorsi3_two_qi_zext"
3309 [(set (match_operand:SI 0 "register_operand" "=&r")
3310 (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
3311
3312 (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3313 (const_int 8))
3314 (const_int 65280))))]
3315 "(TARGET_H8300H || TARGET_H8300S)"
3316 "#"
3317 "&& reload_completed"
3318 [(set (match_dup 3)
3319 (ior:HI (zero_extend:HI (match_dup 1))
3320 (ashift:HI (subreg:HI (match_dup 2) 0)
3321 (const_int 8))))
3322 (set (match_dup 0)
3323 (zero_extend:SI (match_dup 3)))]
3324 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3325
3326 (define_insn "*iorsi3_e2f"
3327 [(set (match_operand:SI 0 "register_operand" "=r")
3328 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3329 (const_int -65536))
3330 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3331 (const_int 16))))]
3332 "TARGET_H8300H || TARGET_H8300S"
3333 "mov.w\\t%e2,%f0"
3334 [(set_attr "length" "2")
3335 (set_attr "cc" "clobber")])
3336
3337 (define_insn_and_split "*iorsi3_two_qi_sext"
3338 [(set (match_operand:SI 0 "register_operand" "=r")
3339 (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
3340 (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
3341 (const_int 8))))]
3342 "(TARGET_H8300H || TARGET_H8300S)"
3343 "#"
3344 "&& reload_completed"
3345 [(set (match_dup 3)
3346 (ior:HI (zero_extend:HI (match_dup 1))
3347 (ashift:HI (match_dup 4)
3348 (const_int 8))))
3349 (set (match_dup 0)
3350 (sign_extend:SI (match_dup 3)))]
3351 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3352 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3353
3354 (define_insn "*iorsi3_w"
3355 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3356 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
3357 (const_int -256))
3358 (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
3359 "TARGET_H8300H || TARGET_H8300S"
3360 "mov.b\\t%X2,%w0"
3361 [(set_attr "length" "2,8")
3362 (set_attr "cc" "clobber,clobber")])
3363
3364 (define_insn "*iorsi3_ashift_31"
3365 [(set (match_operand:SI 0 "register_operand" "=&r")
3366 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3367 (const_int 31))
3368 (match_operand:SI 2 "register_operand" "0")))]
3369 "TARGET_H8300H || TARGET_H8300S"
3370 "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
3371 [(set_attr "length" "6")
3372 (set_attr "cc" "set_znv")])
3373
3374 (define_insn "*iorsi3_and_ashift"
3375 [(set (match_operand:SI 0 "register_operand" "=r")
3376 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3377 (match_operand:SI 2 "const_int_operand" "n"))
3378 (match_operand:SI 3 "single_one_operand" "n"))
3379 (match_operand:SI 4 "register_operand" "0")))]
3380 "(TARGET_H8300H || TARGET_H8300S)
3381 && (INTVAL (operands[3]) & ~0xffff) == 0"
3382 "*
3383 {
3384 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3385 - INTVAL (operands[2]));
3386 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3387 operands[2] = srcpos;
3388 operands[3] = dstpos;
3389 return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
3390 }"
3391 [(set_attr "length" "6")
3392 (set_attr "cc" "clobber")])
3393
3394 (define_insn "*iorsi3_and_lshiftrt"
3395 [(set (match_operand:SI 0 "register_operand" "=r")
3396 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3397 (match_operand:SI 2 "const_int_operand" "n"))
3398 (match_operand:SI 3 "single_one_operand" "n"))
3399 (match_operand:SI 4 "register_operand" "0")))]
3400 "(TARGET_H8300H || TARGET_H8300S)
3401 && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
3402 "*
3403 {
3404 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3405 + INTVAL (operands[2]));
3406 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3407 operands[2] = srcpos;
3408 operands[3] = dstpos;
3409 return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
3410 }"
3411 [(set_attr "length" "6")
3412 (set_attr "cc" "clobber")])
3413
3414 (define_insn "*iorsi3_zero_extract"
3415 [(set (match_operand:SI 0 "register_operand" "=r")
3416 (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3417 (const_int 1)
3418 (match_operand:SI 2 "const_int_operand" "n"))
3419 (match_operand:SI 3 "register_operand" "0")))]
3420 "(TARGET_H8300H || TARGET_H8300S)
3421 && INTVAL (operands[2]) < 16"
3422 "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
3423 [(set_attr "length" "6")
3424 (set_attr "cc" "clobber")])
3425
3426 (define_insn "*iorsi3_and_lshiftrt_n_sb"
3427 [(set (match_operand:SI 0 "register_operand" "=r")
3428 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3429 (const_int 30))
3430 (const_int 2))
3431 (match_operand:SI 2 "register_operand" "0")))]
3432 "(TARGET_H8300H || TARGET_H8300S)"
3433 "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
3434 [(set_attr "length" "8")
3435 (set_attr "cc" "clobber")])
3436
3437 (define_insn "*iorsi3_and_lshiftrt_9_sb"
3438 [(set (match_operand:SI 0 "register_operand" "=r")
3439 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3440 (const_int 9))
3441 (const_int 4194304))
3442 (match_operand:SI 2 "register_operand" "0")))
3443 (clobber (match_scratch:HI 3 "=&r"))]
3444 "(TARGET_H8300H || TARGET_H8300S)"
3445 "*
3446 {
3447 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3448 return \"shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
3449 else
3450 return \"rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
3451 }"
3452 [(set_attr "length" "10")
3453 (set_attr "cc" "clobber")])
3454
3455 ;; Used to OR the exponent of a float.
3456
3457 (define_insn "*iorsi3_shift"
3458 [(set (match_operand:SI 0 "register_operand" "=r")
3459 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3460 (const_int 23))
3461 (match_operand:SI 2 "register_operand" "0")))
3462 (clobber (match_scratch:SI 3 "=&r"))]
3463 "TARGET_H8300H || TARGET_H8300S"
3464 "#")
3465
3466 (define_split
3467 [(parallel
3468 [(set (match_operand:SI 0 "register_operand" "")
3469 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3470 (const_int 23))
3471 (match_dup 0)))
3472 (clobber (match_operand:SI 2 "register_operand" ""))])]
3473 "(TARGET_H8300H || TARGET_H8300S)
3474 && flow2_completed
3475 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3476 && REGNO (operands[0]) != REGNO (operands[1])"
3477 [(parallel [(set (match_dup 3)
3478 (ashift:HI (match_dup 3)
3479 (const_int 7)))
3480 (clobber (scratch:QI))])
3481 (set (match_dup 0)
3482 (ior:SI (ashift:SI (match_dup 1)
3483 (const_int 16))
3484 (match_dup 0)))]
3485 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
3486
3487 (define_split
3488 [(parallel
3489 [(set (match_operand:SI 0 "register_operand" "")
3490 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3491 (const_int 23))
3492 (match_dup 0)))
3493 (clobber (match_operand:SI 2 "register_operand" ""))])]
3494 "(TARGET_H8300H || TARGET_H8300S)
3495 && flow2_completed
3496 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3497 && REGNO (operands[0]) != REGNO (operands[1]))"
3498 [(set (match_dup 2)
3499 (match_dup 1))
3500 (parallel [(set (match_dup 3)
3501 (ashift:HI (match_dup 3)
3502 (const_int 7)))
3503 (clobber (scratch:QI))])
3504 (set (match_dup 0)
3505 (ior:SI (ashift:SI (match_dup 2)
3506 (const_int 16))
3507 (match_dup 0)))]
3508 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3509
3510 (define_insn "*iorsi2_and_1_lshiftrt_1"
3511 [(set (match_operand:SI 0 "register_operand" "=r")
3512 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3513 (const_int 1))
3514 (lshiftrt:SI (match_dup 1)
3515 (const_int 1))))]
3516 "TARGET_H8300H || TARGET_H8300S"
3517 "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
3518 [(set_attr "length" "6")
3519 (set_attr "cc" "clobber")])
3520
3521 (define_insn_and_split "*iorsi3_ashift_16_ashift_24"
3522 [(set (match_operand:SI 0 "register_operand" "=r")
3523 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3524 (const_int 16))
3525 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3526 (const_int 24))))]
3527 "(TARGET_H8300H || TARGET_H8300S)"
3528 "#"
3529 "&& reload_completed"
3530 [(set (match_dup 3)
3531 (ior:HI (ashift:HI (match_dup 4)
3532 (const_int 8))
3533 (match_dup 3)))
3534 (parallel [(set (match_dup 0)
3535 (ashift:SI (match_dup 0)
3536 (const_int 16)))
3537 (clobber (scratch:QI))])]
3538 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3539 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3540
3541 (define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
3542 [(set (match_operand:SI 0 "register_operand" "=&r")
3543 (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
3544 (const_int 16))
3545 (const_int 16711680))
3546 (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3547 (const_int 24))))]
3548 "(TARGET_H8300H || TARGET_H8300S)"
3549 "#"
3550 "&& reload_completed"
3551 [(set (match_dup 3)
3552 (ior:HI (zero_extend:HI (match_dup 1))
3553 (ashift:HI (subreg:HI (match_dup 2) 0)
3554 (const_int 8))))
3555 (parallel [(set (match_dup 0)
3556 (ashift:SI (match_dup 0)
3557 (const_int 16)))
3558 (clobber (scratch:QI))])]
3559 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3560
3561 ;; Used to add the exponent of a float.
3562
3563 (define_insn "*addsi3_shift"
3564 [(set (match_operand:SI 0 "register_operand" "=r")
3565 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3566 (const_int 8388608))
3567 (match_operand:SI 2 "register_operand" "0")))
3568 (clobber (match_scratch:SI 3 "=&r"))]
3569 "TARGET_H8300H || TARGET_H8300S"
3570 "#")
3571
3572 (define_split
3573 [(parallel
3574 [(set (match_operand:SI 0 "register_operand" "")
3575 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3576 (const_int 8388608))
3577 (match_dup 0)))
3578 (clobber (match_operand:SI 2 "register_operand" ""))])]
3579 "(TARGET_H8300H || TARGET_H8300S)
3580 && flow2_completed
3581 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3582 && REGNO (operands[0]) != REGNO (operands[1])"
3583 [(parallel [(set (match_dup 3)
3584 (ashift:HI (match_dup 3)
3585 (const_int 7)))
3586 (clobber (scratch:QI))])
3587 (set (match_dup 0)
3588 (plus:SI (mult:SI (match_dup 1)
3589 (const_int 65536))
3590 (match_dup 0)))]
3591 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
3592
3593 (define_split
3594 [(parallel
3595 [(set (match_operand:SI 0 "register_operand" "")
3596 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3597 (const_int 8388608))
3598 (match_dup 0)))
3599 (clobber (match_operand:SI 2 "register_operand" ""))])]
3600 "(TARGET_H8300H || TARGET_H8300S)
3601 && flow2_completed
3602 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3603 && REGNO (operands[0]) != REGNO (operands[1]))"
3604 [(set (match_dup 2)
3605 (match_dup 1))
3606 (parallel [(set (match_dup 3)
3607 (ashift:HI (match_dup 3)
3608 (const_int 7)))
3609 (clobber (scratch:QI))])
3610 (set (match_dup 0)
3611 (plus:SI (mult:SI (match_dup 2)
3612 (const_int 65536))
3613 (match_dup 0)))]
3614 "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
3615
3616 ;; ashift:SI
3617
3618 (define_insn_and_split "*ashiftsi_sextqi_7"
3619 [(set (match_operand:SI 0 "register_operand" "=r")
3620 (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
3621 (const_int 7)))]
3622 "(TARGET_H8300H || TARGET_H8300S)"
3623 "#"
3624 "&& reload_completed"
3625 [(parallel [(set (match_dup 2)
3626 (ashift:HI (match_dup 2)
3627 (const_int 8)))
3628 (clobber (scratch:QI))])
3629 (set (match_dup 0)
3630 (sign_extend:SI (match_dup 2)))
3631 (parallel [(set (match_dup 0)
3632 (ashiftrt:SI (match_dup 0)
3633 (const_int 1)))
3634 (clobber (scratch:QI))])]
3635 "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3636
3637 ;; Storing a part of HImode to QImode.
3638
3639 (define_insn ""
3640 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3641 (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3642 (const_int 8)) 1))]
3643 ""
3644 "mov.b\\t%t1,%R0"
3645 [(set_attr "cc" "set_znv")
3646 (set_attr "length" "8")])
3647
3648 ;; Storing a part of SImode to QImode.
3649
3650 (define_insn ""
3651 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3652 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3653 (const_int 8)) 3))]
3654 ""
3655 "mov.b\\t%x1,%R0"
3656 [(set_attr "cc" "set_znv")
3657 (set_attr "length" "8")])
3658
3659 (define_insn ""
3660 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3661 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3662 (const_int 16)) 3))
3663 (clobber (match_scratch:SI 2 "=&r"))]
3664 "TARGET_H8300H || TARGET_H8300S"
3665 "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
3666 [(set_attr "cc" "set_znv")
3667 (set_attr "length" "10")])
3668
3669 (define_insn ""
3670 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3671 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3672 (const_int 24)) 3))
3673 (clobber (match_scratch:SI 2 "=&r"))]
3674 "TARGET_H8300H || TARGET_H8300S"
3675 "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
3676 [(set_attr "cc" "set_znv")
3677 (set_attr "length" "10")])
3678
3679 (define_insn_and_split ""
3680 [(set (pc)
3681 (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3682 (const_int 1)
3683 (const_int 7))
3684 (const_int 0))
3685 (label_ref (match_operand 1 "" ""))
3686 (pc)))]
3687 ""
3688 "#"
3689 ""
3690 [(set (cc0)
3691 (match_dup 0))
3692 (set (pc)
3693 (if_then_else (ge (cc0)
3694 (const_int 0))
3695 (label_ref (match_dup 1))
3696 (pc)))]
3697 "")
3698
3699 (define_insn_and_split ""
3700 [(set (pc)
3701 (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3702 (const_int 1)
3703 (const_int 7))
3704 (const_int 0))
3705 (label_ref (match_operand 1 "" ""))
3706 (pc)))]
3707 ""
3708 "#"
3709 ""
3710 [(set (cc0)
3711 (match_dup 0))
3712 (set (pc)
3713 (if_then_else (lt (cc0)
3714 (const_int 0))
3715 (label_ref (match_dup 1))
3716 (pc)))]
3717 "")
3718 \f
3719 ;; -----------------------------------------------------------------
3720 ;; PEEPHOLE PATTERNS
3721 ;; -----------------------------------------------------------------
3722
3723 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
3724
3725 (define_peephole2
3726 [(parallel
3727 [(set (match_operand:HI 0 "register_operand" "")
3728 (lshiftrt:HI (match_dup 0)
3729 (match_operand:HI 1 "const_int_operand" "")))
3730 (clobber (match_operand:HI 2 "" ""))])
3731 (set (match_dup 0)
3732 (and:HI (match_dup 0)
3733 (match_operand:HI 3 "const_int_operand" "")))]
3734 "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
3735 [(set (match_dup 0)
3736 (and:HI (match_dup 0)
3737 (const_int 255)))
3738 (parallel
3739 [(set (match_dup 0)
3740 (lshiftrt:HI (match_dup 0)
3741 (match_dup 1)))
3742 (clobber (match_dup 2))])]
3743 "")
3744
3745 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
3746
3747 (define_peephole2
3748 [(parallel
3749 [(set (match_operand:HI 0 "register_operand" "")
3750 (ashift:HI (match_dup 0)
3751 (match_operand:HI 1 "const_int_operand" "")))
3752 (clobber (match_operand:HI 2 "" ""))])
3753 (set (match_dup 0)
3754 (and:HI (match_dup 0)
3755 (match_operand:HI 3 "const_int_operand" "")))]
3756 "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
3757 [(set (match_dup 0)
3758 (and:HI (match_dup 0)
3759 (const_int 255)))
3760 (parallel
3761 [(set (match_dup 0)
3762 (ashift:HI (match_dup 0)
3763 (match_dup 1)))
3764 (clobber (match_dup 2))])]
3765 "")
3766
3767 ;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
3768
3769 (define_peephole2
3770 [(parallel
3771 [(set (match_operand:SI 0 "register_operand" "")
3772 (lshiftrt:SI (match_dup 0)
3773 (match_operand:SI 1 "const_int_operand" "")))
3774 (clobber (match_operand:SI 2 "" ""))])
3775 (set (match_dup 0)
3776 (and:SI (match_dup 0)
3777 (match_operand:SI 3 "const_int_operand" "")))]
3778 "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
3779 [(set (match_dup 0)
3780 (and:SI (match_dup 0)
3781 (const_int 255)))
3782 (parallel
3783 [(set (match_dup 0)
3784 (lshiftrt:SI (match_dup 0)
3785 (match_dup 1)))
3786 (clobber (match_dup 2))])]
3787 "")
3788
3789 ;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
3790
3791 (define_peephole2
3792 [(parallel
3793 [(set (match_operand:SI 0 "register_operand" "")
3794 (ashift:SI (match_dup 0)
3795 (match_operand:SI 1 "const_int_operand" "")))
3796 (clobber (match_operand:SI 2 "" ""))])
3797 (set (match_dup 0)
3798 (and:SI (match_dup 0)
3799 (match_operand:SI 3 "const_int_operand" "")))]
3800 "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
3801 [(set (match_dup 0)
3802 (and:SI (match_dup 0)
3803 (const_int 255)))
3804 (parallel
3805 [(set (match_dup 0)
3806 (ashift:SI (match_dup 0)
3807 (match_dup 1)))
3808 (clobber (match_dup 2))])]
3809 "")
3810
3811 ;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
3812
3813 (define_peephole2
3814 [(parallel
3815 [(set (match_operand:SI 0 "register_operand" "")
3816 (lshiftrt:SI (match_dup 0)
3817 (match_operand:SI 1 "const_int_operand" "")))
3818 (clobber (match_operand:SI 2 "" ""))])
3819 (set (match_dup 0)
3820 (and:SI (match_dup 0)
3821 (match_operand:SI 3 "const_int_operand" "")))]
3822 "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
3823 [(set (match_dup 0)
3824 (and:SI (match_dup 0)
3825 (const_int 65535)))
3826 (parallel
3827 [(set (match_dup 0)
3828 (lshiftrt:SI (match_dup 0)
3829 (match_dup 1)))
3830 (clobber (match_dup 2))])]
3831 "")
3832
3833 ;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
3834
3835 (define_peephole2
3836 [(parallel
3837 [(set (match_operand:SI 0 "register_operand" "")
3838 (ashift:SI (match_dup 0)
3839 (match_operand:SI 1 "const_int_operand" "")))
3840 (clobber (match_operand:SI 2 "" ""))])
3841 (set (match_dup 0)
3842 (and:SI (match_dup 0)
3843 (match_operand:SI 3 "const_int_operand" "")))]
3844 "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
3845 [(set (match_dup 0)
3846 (and:SI (match_dup 0)
3847 (const_int 65535)))
3848 (parallel
3849 [(set (match_dup 0)
3850 (ashift:SI (match_dup 0)
3851 (match_dup 1)))
3852 (clobber (match_dup 2))])]
3853 "")
3854
3855 ;; Convert a QImode push into an SImode push so that the
3856 ;; define_peephole2 below can cram multiple pushes into one stm.l.
3857
3858 (define_peephole2
3859 [(parallel [(set (reg:SI SP_REG)
3860 (plus:SI (reg:SI SP_REG) (const_int -4)))
3861 (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
3862 (match_operand:QI 0 "register_operand" ""))])]
3863 "TARGET_H8300S && !TARGET_NORMAL_MODE"
3864 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3865 (match_dup 0))]
3866 "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3867
3868 (define_peephole2
3869 [(parallel [(set (reg:HI SP_REG)
3870 (plus:HI (reg:HI SP_REG) (const_int -4)))
3871 (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
3872 (match_operand:QI 0 "register_operand" ""))])]
3873 "TARGET_H8300S && TARGET_NORMAL_MODE"
3874 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3875 (match_dup 0))]
3876 "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3877
3878 ;; Convert a HImode push into an SImode push so that the
3879 ;; define_peephole2 below can cram multiple pushes into one stm.l.
3880
3881 (define_peephole2
3882 [(parallel [(set (reg:SI SP_REG)
3883 (plus:SI (reg:SI SP_REG) (const_int -4)))
3884 (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
3885 (match_operand:HI 0 "register_operand" ""))])]
3886 "TARGET_H8300S && !TARGET_NORMAL_MODE"
3887 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3888 (match_dup 0))]
3889 "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3890
3891 (define_peephole2
3892 [(parallel [(set (reg:HI SP_REG)
3893 (plus:HI (reg:HI SP_REG) (const_int -4)))
3894 (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
3895 (match_operand:HI 0 "register_operand" ""))])]
3896 "TARGET_H8300S && TARGET_NORMAL_MODE"
3897 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3898 (match_dup 0))]
3899 "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
3900
3901 ;; Cram four pushes into stm.l.
3902
3903 (define_peephole2
3904 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3905 (match_operand:SI 0 "register_operand" ""))
3906 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3907 (match_operand:SI 1 "register_operand" ""))
3908 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3909 (match_operand:SI 2 "register_operand" ""))
3910 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3911 (match_operand:SI 3 "register_operand" ""))]
3912 "TARGET_H8300S && !TARGET_NORMAL_MODE
3913 && REGNO (operands[0]) == 0
3914 && REGNO (operands[1]) == 1
3915 && REGNO (operands[2]) == 2
3916 && REGNO (operands[3]) == 3"
3917 [(parallel [(set (reg:SI SP_REG)
3918 (plus:SI (reg:SI SP_REG)
3919 (const_int -16)))
3920 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
3921 (match_dup 0))
3922 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
3923 (match_dup 1))
3924 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
3925 (match_dup 2))
3926 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
3927 (match_dup 3))])]
3928 "")
3929
3930 (define_peephole2
3931 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3932 (match_operand:SI 0 "register_operand" ""))
3933 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3934 (match_operand:SI 1 "register_operand" ""))
3935 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3936 (match_operand:SI 2 "register_operand" ""))
3937 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3938 (match_operand:SI 3 "register_operand" ""))]
3939 "TARGET_H8300S && TARGET_NORMAL_MODE
3940 && REGNO (operands[0]) == 0
3941 && REGNO (operands[1]) == 1
3942 && REGNO (operands[2]) == 2
3943 && REGNO (operands[3]) == 3"
3944 [(parallel [(set (reg:HI SP_REG)
3945 (plus:HI (reg:HI SP_REG)
3946 (const_int -16)))
3947 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
3948 (match_dup 0))
3949 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
3950 (match_dup 1))
3951 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
3952 (match_dup 2))
3953 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
3954 (match_dup 3))])]
3955 "")
3956
3957 ;; Cram three pushes into stm.l.
3958
3959 (define_peephole2
3960 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3961 (match_operand:SI 0 "register_operand" ""))
3962 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3963 (match_operand:SI 1 "register_operand" ""))
3964 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3965 (match_operand:SI 2 "register_operand" ""))]
3966 "TARGET_H8300S && !TARGET_NORMAL_MODE
3967 && ((REGNO (operands[0]) == 0
3968 && REGNO (operands[1]) == 1
3969 && REGNO (operands[2]) == 2)
3970 || (REGNO (operands[0]) == 4
3971 && REGNO (operands[1]) == 5
3972 && REGNO (operands[2]) == 6))"
3973 [(parallel [(set (reg:SI SP_REG)
3974 (plus:SI (reg:SI SP_REG)
3975 (const_int -12)))
3976 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
3977 (match_dup 0))
3978 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
3979 (match_dup 1))
3980 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
3981 (match_dup 2))])]
3982 "")
3983
3984 (define_peephole2
3985 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3986 (match_operand:SI 0 "register_operand" ""))
3987 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3988 (match_operand:SI 1 "register_operand" ""))
3989 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
3990 (match_operand:SI 2 "register_operand" ""))]
3991 "TARGET_H8300S && TARGET_NORMAL_MODE
3992 && ((REGNO (operands[0]) == 0
3993 && REGNO (operands[1]) == 1
3994 && REGNO (operands[2]) == 2)
3995 || (REGNO (operands[0]) == 4
3996 && REGNO (operands[1]) == 5
3997 && REGNO (operands[2]) == 6))"
3998 [(parallel [(set (reg:HI SP_REG)
3999 (plus:HI (reg:HI SP_REG)
4000 (const_int -12)))
4001 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4002 (match_dup 0))
4003 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4004 (match_dup 1))
4005 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4006 (match_dup 2))])]
4007 "")
4008
4009 ;; Cram two pushes into stm.l.
4010
4011 (define_peephole2
4012 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4013 (match_operand:SI 0 "register_operand" ""))
4014 (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4015 (match_operand:SI 1 "register_operand" ""))]
4016 "TARGET_H8300S && !TARGET_NORMAL_MODE
4017 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
4018 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
4019 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
4020 [(parallel [(set (reg:SI SP_REG)
4021 (plus:SI (reg:SI SP_REG)
4022 (const_int -8)))
4023 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4024 (match_dup 0))
4025 (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4026 (match_dup 1))])]
4027 "")
4028
4029 (define_peephole2
4030 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4031 (match_operand:SI 0 "register_operand" ""))
4032 (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4033 (match_operand:SI 1 "register_operand" ""))]
4034 "TARGET_H8300S && TARGET_NORMAL_MODE
4035 && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1)
4036 || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3)
4037 || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))"
4038 [(parallel [(set (reg:HI SP_REG)
4039 (plus:HI (reg:HI SP_REG)
4040 (const_int -8)))
4041 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4042 (match_dup 0))
4043 (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4044 (match_dup 1))])]
4045 "")
4046
4047 ;; Turn
4048 ;;
4049 ;; mov.w #2,r0
4050 ;; add.w r7,r0 (6 bytes)
4051 ;;
4052 ;; into
4053 ;;
4054 ;; mov.w r7,r0
4055 ;; adds #2,r0 (4 bytes)
4056
4057 (define_peephole2
4058 [(set (match_operand:HI 0 "register_operand" "")
4059 (match_operand:HI 1 "const_int_operand" ""))
4060 (set (match_dup 0)
4061 (plus:HI (match_dup 0)
4062 (match_operand:HI 2 "register_operand" "")))]
4063 "REG_P (operands[0]) && REG_P (operands[2])
4064 && REGNO (operands[0]) != REGNO (operands[2])
4065 && (CONST_OK_FOR_J (INTVAL (operands[1]))
4066 || CONST_OK_FOR_L (INTVAL (operands[1]))
4067 || CONST_OK_FOR_N (INTVAL (operands[1])))"
4068 [(set (match_dup 0)
4069 (match_dup 2))
4070 (set (match_dup 0)
4071 (plus:HI (match_dup 0)
4072 (match_dup 1)))]
4073 "")
4074
4075 ;; Turn
4076 ;;
4077 ;; sub.l er0,er0
4078 ;; add.b #4,r0l
4079 ;; add.l er7,er0 (6 bytes)
4080 ;;
4081 ;; into
4082 ;;
4083 ;; mov.l er7,er0
4084 ;; adds #4,er0 (4 bytes)
4085
4086 (define_peephole2
4087 [(set (match_operand:SI 0 "register_operand" "")
4088 (match_operand:SI 1 "const_int_operand" ""))
4089 (set (match_dup 0)
4090 (plus:SI (match_dup 0)
4091 (match_operand:SI 2 "register_operand" "")))]
4092 "(TARGET_H8300H || TARGET_H8300S)
4093 && REG_P (operands[0]) && REG_P (operands[2])
4094 && REGNO (operands[0]) != REGNO (operands[2])
4095 && (CONST_OK_FOR_L (INTVAL (operands[1]))
4096 || CONST_OK_FOR_N (INTVAL (operands[1])))"
4097 [(set (match_dup 0)
4098 (match_dup 2))
4099 (set (match_dup 0)
4100 (plus:SI (match_dup 0)
4101 (match_dup 1)))]
4102 "")
4103
4104 ;; Turn
4105 ;;
4106 ;; mov.l er7,er0
4107 ;; add.l #10,er0 (takes 8 bytes)
4108 ;;
4109 ;; into
4110 ;;
4111 ;; sub.l er0,er0
4112 ;; add.b #10,r0l
4113 ;; add.l er7,er0 (takes 6 bytes)
4114
4115 (define_peephole2
4116 [(set (match_operand:SI 0 "register_operand" "")
4117 (match_operand:SI 1 "register_operand" ""))
4118 (set (match_dup 0)
4119 (plus:SI (match_dup 0)
4120 (match_operand:SI 2 "const_int_operand" "")))]
4121 "(TARGET_H8300H || TARGET_H8300S)
4122 && REG_P (operands[0]) && REG_P (operands[1])
4123 && REGNO (operands[0]) != REGNO (operands[1])
4124 && !CONST_OK_FOR_L (INTVAL (operands[2]))
4125 && !CONST_OK_FOR_N (INTVAL (operands[2]))
4126 && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4127 || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4128 || INTVAL (operands[2]) == 0xffff
4129 || INTVAL (operands[2]) == 0xfffe)"
4130 [(set (match_dup 0)
4131 (match_dup 2))
4132 (set (match_dup 0)
4133 (plus:SI (match_dup 0)
4134 (match_dup 1)))]
4135 "")
4136
4137 ;; Turn
4138 ;;
4139 ;; subs #1,er4
4140 ;; mov.w r4,r4
4141 ;; bne .L2028
4142 ;;
4143 ;; into
4144 ;;
4145 ;; dec.w #1,r4
4146 ;; bne .L2028
4147
4148 (define_peephole2
4149 [(set (match_operand:HI 0 "register_operand" "")
4150 (plus:HI (match_dup 0)
4151 (match_operand 1 "incdec_operand" "")))
4152 (set (cc0)
4153 (match_dup 0))
4154 (set (pc)
4155 (if_then_else (match_operator 3 "eqne_operator"
4156 [(cc0) (const_int 0)])
4157 (label_ref (match_operand 2 "" ""))
4158 (pc)))]
4159 "TARGET_H8300H || TARGET_H8300S"
4160 [(set (match_operand:HI 0 "register_operand" "")
4161 (unspec:HI [(match_dup 0)
4162 (match_dup 1)]
4163 UNSPEC_INCDEC))
4164 (set (cc0)
4165 (match_dup 0))
4166 (set (pc)
4167 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4168 (label_ref (match_dup 2))
4169 (pc)))]
4170 "")
4171
4172 ;; The SImode version of the previous pattern.
4173
4174 (define_peephole2
4175 [(set (match_operand:SI 0 "register_operand" "")
4176 (plus:SI (match_dup 0)
4177 (match_operand 1 "incdec_operand" "")))
4178 (set (cc0)
4179 (match_dup 0))
4180 (set (pc)
4181 (if_then_else (match_operator 3 "eqne_operator"
4182 [(cc0) (const_int 0)])
4183 (label_ref (match_operand 2 "" ""))
4184 (pc)))]
4185 "TARGET_H8300H || TARGET_H8300S"
4186 [(set (match_operand:SI 0 "register_operand" "")
4187 (unspec:SI [(match_dup 0)
4188 (match_dup 1)]
4189 UNSPEC_INCDEC))
4190 (set (cc0)
4191 (match_dup 0))
4192 (set (pc)
4193 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4194 (label_ref (match_dup 2))
4195 (pc)))]
4196 "")
4197
4198 (define_peephole2
4199 [(parallel [(set (cc0)
4200 (zero_extract:SI (match_operand:QI 0 "register_operand" "")
4201 (const_int 1)
4202 (const_int 7)))
4203 (clobber (scratch:QI))])
4204 (set (pc)
4205 (if_then_else (match_operator 1 "eqne_operator"
4206 [(cc0) (const_int 0)])
4207 (label_ref (match_operand 2 "" ""))
4208 (pc)))]
4209 "(TARGET_H8300H || TARGET_H8300S)"
4210 [(set (cc0)
4211 (match_dup 0))
4212 (set (pc)
4213 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4214 (label_ref (match_dup 2))
4215 (pc)))]
4216 "operands[3] = ((GET_CODE (operands[1]) == EQ)
4217 ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
4218 : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));")
4219
4220 ;; The next three peephole2's will try to transform
4221 ;;
4222 ;; mov.b A,r0l (or mov.l A,er0)
4223 ;; and.l #CST,er0
4224 ;;
4225 ;; into
4226 ;;
4227 ;; sub.l er0
4228 ;; mov.b A,r0l
4229 ;; and.b #CST,r0l (if CST is not 255)
4230
4231 (define_peephole2
4232 [(set (match_operand:QI 0 "register_operand" "")
4233 (match_operand:QI 1 "general_operand" ""))
4234 (set (match_operand:SI 2 "register_operand" "")
4235 (and:SI (match_dup 2)
4236 (const_int 255)))]
4237 "(TARGET_H8300H || TARGET_H8300S)
4238 && !reg_overlap_mentioned_p (operands[2], operands[1])
4239 && REGNO (operands[0]) == REGNO (operands[2])"
4240 [(set (match_dup 2)
4241 (const_int 0))
4242 (set (strict_low_part (match_dup 0))
4243 (match_dup 1))]
4244 "")
4245
4246 (define_peephole2
4247 [(set (match_operand:SI 0 "register_operand" "")
4248 (match_operand:SI 1 "general_operand" ""))
4249 (set (match_dup 0)
4250 (and:SI (match_dup 0)
4251 (const_int 255)))]
4252 "(TARGET_H8300H || TARGET_H8300S)
4253 && !reg_overlap_mentioned_p (operands[0], operands[1])
4254 && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
4255 [(set (match_dup 0)
4256 (const_int 0))
4257 (set (strict_low_part (match_dup 2))
4258 (match_dup 3))]
4259 "operands[2] = gen_lowpart (QImode, operands[0]);
4260 operands[3] = gen_lowpart (QImode, operands[1]);")
4261
4262 (define_peephole2
4263 [(set (match_operand 0 "register_operand" "")
4264 (match_operand 1 "general_operand" ""))
4265 (set (match_operand:SI 2 "register_operand" "")
4266 (and:SI (match_dup 2)
4267 (match_operand:SI 3 "const_int_qi_operand" "")))]
4268 "(TARGET_H8300H || TARGET_H8300S)
4269 && (GET_MODE (operands[0]) == QImode
4270 || GET_MODE (operands[0]) == HImode
4271 || GET_MODE (operands[0]) == SImode)
4272 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4273 && REGNO (operands[0]) == REGNO (operands[2])
4274 && !reg_overlap_mentioned_p (operands[2], operands[1])
4275 && !(GET_MODE (operands[1]) != QImode
4276 && GET_CODE (operands[1]) == MEM
4277 && MEM_VOLATILE_P (operands[1]))"
4278 [(set (match_dup 2)
4279 (const_int 0))
4280 (set (strict_low_part (match_dup 4))
4281 (match_dup 5))
4282 (set (match_dup 2)
4283 (and:SI (match_dup 2)
4284 (match_dup 6)))]
4285 "operands[4] = gen_lowpart (QImode, operands[0]);
4286 operands[5] = gen_lowpart (QImode, operands[1]);
4287 operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));")
4288
4289 (define_peephole2
4290 [(set (match_operand:SI 0 "register_operand" "")
4291 (match_operand:SI 1 "register_operand" ""))
4292 (set (match_dup 0)
4293 (and:SI (match_dup 0)
4294 (const_int 65280)))]
4295 "(TARGET_H8300H || TARGET_H8300S)
4296 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4297 [(set (match_dup 0)
4298 (const_int 0))
4299 (set (zero_extract:SI (match_dup 0)
4300 (const_int 8)
4301 (const_int 8))
4302 (lshiftrt:SI (match_dup 1)
4303 (const_int 8)))]
4304 "")
4305
4306 ;; If a load of mem:SI is followed by an AND that turns off the upper
4307 ;; half, then we can load mem:HI instead.
4308
4309 (define_peephole2
4310 [(set (match_operand:SI 0 "register_operand" "")
4311 (match_operand:SI 1 "memory_operand" ""))
4312 (set (match_dup 0)
4313 (and:SI (match_dup 0)
4314 (match_operand:SI 2 "const_int_operand" "")))]
4315 "(TARGET_H8300H || TARGET_H8300S)
4316 && !MEM_VOLATILE_P (operands[1])
4317 && (INTVAL (operands[2]) & ~0xffff) == 0
4318 && INTVAL (operands[2]) != 255"
4319 [(set (match_dup 3)
4320 (match_dup 4))
4321 (set (match_dup 0)
4322 (and:SI (match_dup 0)
4323 (match_dup 2)))]
4324 "operands[3] = gen_lowpart (HImode, operands[0]);
4325 operands[4] = gen_lowpart (HImode, operands[1]);")
4326
4327 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
4328 ;; the equivalent with shorter sequences. Here is the summary. Cases
4329 ;; are grouped for each define_peephole2.
4330 ;;
4331 ;; reg const_int use insn
4332 ;; --------------------------------------------------------
4333 ;; dead -2 eq/ne inc.l
4334 ;; dead -1 eq/ne inc.l
4335 ;; dead 1 eq/ne dec.l
4336 ;; dead 2 eq/ne dec.l
4337 ;;
4338 ;; dead 1 geu/ltu shar.l
4339 ;; dead 3 (H8S) geu/ltu shar.l
4340 ;;
4341 ;; ---- 255 geu/ltu mov.b
4342
4343 ;; Transform
4344 ;;
4345 ;; cmp.w #1,r0
4346 ;; bne .L1
4347 ;;
4348 ;; into
4349 ;;
4350 ;; dec.w #1,r0
4351 ;; bne .L1
4352
4353 (define_peephole2
4354 [(set (cc0)
4355 (compare (match_operand:HI 0 "register_operand" "")
4356 (match_operand:HI 1 "incdec_operand" "")))
4357 (set (pc)
4358 (if_then_else (match_operator 3 "eqne_operator"
4359 [(cc0) (const_int 0)])
4360 (label_ref (match_operand 2 "" ""))
4361 (pc)))]
4362 "(TARGET_H8300H || TARGET_H8300S)
4363 && peep2_reg_dead_p (1, operands[0])"
4364 [(set (match_dup 0)
4365 (unspec:HI [(match_dup 0)
4366 (match_dup 4)]
4367 UNSPEC_INCDEC))
4368 (set (cc0)
4369 (match_dup 0))
4370 (set (pc)
4371 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4372 (label_ref (match_dup 2))
4373 (pc)))]
4374 "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4375
4376 ;; Transform
4377 ;;
4378 ;; cmp.w #1,r0
4379 ;; bhi .L1
4380 ;;
4381 ;; into
4382 ;;
4383 ;; shar.w r0
4384 ;; bne .L1
4385
4386 (define_peephole2
4387 [(set (cc0)
4388 (compare (match_operand:HI 0 "register_operand" "")
4389 (match_operand:HI 1 "const_int_operand" "")))
4390 (set (pc)
4391 (if_then_else (match_operator 2 "gtle_operator"
4392 [(cc0) (const_int 0)])
4393 (label_ref (match_operand 3 "" ""))
4394 (pc)))]
4395 "(TARGET_H8300H || TARGET_H8300S)
4396 && peep2_reg_dead_p (1, operands[0])
4397 && (INTVAL (operands[1]) == 1
4398 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4399 [(parallel [(set (match_dup 0)
4400 (ashiftrt:HI (match_dup 0)
4401 (match_dup 5)))
4402 (clobber (scratch:QI))])
4403 (set (cc0)
4404 (match_dup 0))
4405 (set (pc)
4406 (if_then_else (match_dup 4)
4407 (label_ref (match_dup 3))
4408 (pc)))]
4409 "switch (GET_CODE (operands[2]))
4410 {
4411 case GTU:
4412 operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4413 break;
4414 case LEU:
4415 operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4416 break;
4417 default:
4418 operands[4] = operands[2];
4419 break;
4420 }
4421 operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4422
4423 ;; Transform
4424 ;;
4425 ;; cmp.w #255,r0
4426 ;; bhi .L1
4427 ;;
4428 ;; into
4429 ;;
4430 ;; mov.b r0h,r0h
4431 ;; bne .L1
4432
4433 (define_peephole2
4434 [(set (cc0)
4435 (compare (match_operand:HI 0 "register_operand" "")
4436 (const_int 255)))
4437 (set (pc)
4438 (if_then_else (match_operator 1 "gtle_operator"
4439 [(cc0) (const_int 0)])
4440 (label_ref (match_operand 2 "" ""))
4441 (pc)))]
4442 "TARGET_H8300H || TARGET_H8300S"
4443 [(set (cc0)
4444 (and:HI (match_dup 0)
4445 (const_int -256)))
4446 (set (pc)
4447 (if_then_else (match_dup 3)
4448 (label_ref (match_dup 2))
4449 (pc)))]
4450 "switch (GET_CODE (operands[1]))
4451 {
4452 case GTU:
4453 operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4454 break;
4455 case LEU:
4456 operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4457 break;
4458 default:
4459 operands[3] = operands[1];
4460 break;
4461 }")
4462
4463 ;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
4464 ;; the equivalent with shorter sequences. Here is the summary. Cases
4465 ;; are grouped for each define_peephole2.
4466 ;;
4467 ;; reg const_int use insn
4468 ;; --------------------------------------------------------
4469 ;; live -2 eq/ne copy and inc.l
4470 ;; live -1 eq/ne copy and inc.l
4471 ;; live 1 eq/ne copy and dec.l
4472 ;; live 2 eq/ne copy and dec.l
4473 ;;
4474 ;; dead -2 eq/ne inc.l
4475 ;; dead -1 eq/ne inc.l
4476 ;; dead 1 eq/ne dec.l
4477 ;; dead 2 eq/ne dec.l
4478 ;;
4479 ;; dead -131072 eq/ne inc.w and test
4480 ;; dead -65536 eq/ne inc.w and test
4481 ;; dead 65536 eq/ne dec.w and test
4482 ;; dead 131072 eq/ne dec.w and test
4483 ;;
4484 ;; dead 0x000000?? except 1 and 2 eq/ne xor.b and test
4485 ;; dead 0x0000??00 eq/ne xor.b and test
4486 ;; dead 0x0000ffff eq/ne not.w and test
4487 ;;
4488 ;; dead 0xffffff?? except -1 and -2 eq/ne xor.b and not.l
4489 ;; dead 0xffff??ff eq/ne xor.b and not.l
4490 ;; dead 0x40000000 (H8S) eq/ne rotl.l and dec.l
4491 ;; dead 0x80000000 eq/ne rotl.l and dec.l
4492 ;;
4493 ;; live 1 geu/ltu copy and shar.l
4494 ;; live 3 (H8S) geu/ltu copy and shar.l
4495 ;;
4496 ;; dead 1 geu/ltu shar.l
4497 ;; dead 3 (H8S) geu/ltu shar.l
4498 ;;
4499 ;; dead 3 (H8/300H) geu/ltu and.b and test
4500 ;; dead 7 geu/ltu and.b and test
4501 ;; dead 15 geu/ltu and.b and test
4502 ;; dead 31 geu/ltu and.b and test
4503 ;; dead 63 geu/ltu and.b and test
4504 ;; dead 127 geu/ltu and.b and test
4505 ;; dead 255 geu/ltu and.b and test
4506 ;;
4507 ;; ---- 65535 geu/ltu mov.w
4508
4509 ;; For a small constant, it is cheaper to actually do the subtraction
4510 ;; and then test the register.
4511
4512 (define_peephole2
4513 [(set (cc0)
4514 (compare (match_operand:SI 0 "register_operand" "")
4515 (match_operand:SI 1 "incdec_operand" "")))
4516 (set (pc)
4517 (if_then_else (match_operator 3 "eqne_operator"
4518 [(cc0) (const_int 0)])
4519 (label_ref (match_operand 2 "" ""))
4520 (pc)))]
4521 "(TARGET_H8300H || TARGET_H8300S)
4522 && peep2_reg_dead_p (1, operands[0])"
4523 [(set (match_dup 0)
4524 (unspec:SI [(match_dup 0)
4525 (match_dup 4)]
4526 UNSPEC_INCDEC))
4527 (set (cc0)
4528 (match_dup 0))
4529 (set (pc)
4530 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4531 (label_ref (match_dup 2))
4532 (pc)))]
4533 "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4534
4535 (define_peephole2
4536 [(set (cc0)
4537 (compare (match_operand:SI 0 "register_operand" "")
4538 (match_operand:SI 1 "const_int_operand" "")))
4539 (set (pc)
4540 (if_then_else (match_operator 3 "eqne_operator"
4541 [(cc0) (const_int 0)])
4542 (label_ref (match_operand 2 "" ""))
4543 (pc)))]
4544 "(TARGET_H8300H || TARGET_H8300S)
4545 && peep2_reg_dead_p (1, operands[0])
4546 && (INTVAL (operands[1]) == -131072
4547 || INTVAL (operands[1]) == -65536
4548 || INTVAL (operands[1]) == 65536
4549 || INTVAL (operands[1]) == 131072)"
4550 [(set (match_dup 0)
4551 (plus:SI (match_dup 0)
4552 (match_dup 4)))
4553 (set (cc0)
4554 (match_dup 0))
4555 (set (pc)
4556 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4557 (label_ref (match_dup 2))
4558 (pc)))]
4559 "operands[4] = GEN_INT (- INTVAL (operands[1]));")
4560
4561 ;; For certain (in)equality comparisons against a constant, we can
4562 ;; XOR the register with the constant, and test the register against
4563 ;; 0.
4564
4565 (define_peephole2
4566 [(set (cc0)
4567 (compare (match_operand:SI 0 "register_operand" "")
4568 (match_operand:SI 1 "const_int_operand" "")))
4569 (set (pc)
4570 (if_then_else (match_operator 3 "eqne_operator"
4571 [(cc0) (const_int 0)])
4572 (label_ref (match_operand 2 "" ""))
4573 (pc)))]
4574 "(TARGET_H8300H || TARGET_H8300S)
4575 && peep2_reg_dead_p (1, operands[0])
4576 && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
4577 || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
4578 || INTVAL (operands[1]) == 0x0000ffff)
4579 && INTVAL (operands[1]) != 1
4580 && INTVAL (operands[1]) != 2"
4581 [(set (match_dup 0)
4582 (xor:SI (match_dup 0)
4583 (match_dup 1)))
4584 (set (cc0)
4585 (match_dup 0))
4586 (set (pc)
4587 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4588 (label_ref (match_dup 2))
4589 (pc)))]
4590 "")
4591
4592 (define_peephole2
4593 [(set (cc0)
4594 (compare (match_operand:SI 0 "register_operand" "")
4595 (match_operand:SI 1 "const_int_operand" "")))
4596 (set (pc)
4597 (if_then_else (match_operator 3 "eqne_operator"
4598 [(cc0) (const_int 0)])
4599 (label_ref (match_operand 2 "" ""))
4600 (pc)))]
4601 "(TARGET_H8300H || TARGET_H8300S)
4602 && peep2_reg_dead_p (1, operands[0])
4603 && ((INTVAL (operands[1]) | 0x00ff) == -1
4604 || (INTVAL (operands[1]) | 0xff00) == -1)
4605 && INTVAL (operands[1]) != -1
4606 && INTVAL (operands[1]) != -2"
4607 [(set (match_dup 0)
4608 (xor:SI (match_dup 0)
4609 (match_dup 4)))
4610 (set (match_dup 0)
4611 (not:SI (match_dup 0)))
4612 (set (cc0)
4613 (match_dup 0))
4614 (set (pc)
4615 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4616 (label_ref (match_dup 2))
4617 (pc)))]
4618 "operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);")
4619
4620 (define_peephole2
4621 [(set (cc0)
4622 (compare (match_operand:SI 0 "register_operand" "")
4623 (match_operand:SI 1 "const_int_operand" "")))
4624 (set (pc)
4625 (if_then_else (match_operator 3 "eqne_operator"
4626 [(cc0) (const_int 0)])
4627 (label_ref (match_operand 2 "" ""))
4628 (pc)))]
4629 "(TARGET_H8300H || TARGET_H8300S)
4630 && peep2_reg_dead_p (1, operands[0])
4631 && (INTVAL (operands[1]) == -2147483647 - 1
4632 || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
4633 [(set (match_dup 0)
4634 (rotate:SI (match_dup 0)
4635 (match_dup 4)))
4636 (set (match_dup 0)
4637 (unspec:SI [(match_dup 0)
4638 (const_int -1)]
4639 UNSPEC_INCDEC))
4640 (set (cc0)
4641 (match_dup 0))
4642 (set (pc)
4643 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4644 (label_ref (match_dup 2))
4645 (pc)))]
4646 "operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);")
4647
4648 ;; Transform
4649 ;;
4650 ;; cmp.l #1,er0
4651 ;; bhi .L1
4652 ;;
4653 ;; into
4654 ;;
4655 ;; mov.l er0,er1
4656 ;; shar.l er1
4657 ;; bne .L1
4658
4659 ;; We avoid this transformation if we see more than one copy of the
4660 ;; same compare insn immediately before this one.
4661
4662 (define_peephole2
4663 [(match_scratch:SI 4 "r")
4664 (set (cc0)
4665 (compare (match_operand:SI 0 "register_operand" "")
4666 (match_operand:SI 1 "const_int_operand" "")))
4667 (set (pc)
4668 (if_then_else (match_operator 2 "gtle_operator"
4669 [(cc0) (const_int 0)])
4670 (label_ref (match_operand 3 "" ""))
4671 (pc)))]
4672 "(TARGET_H8300H || TARGET_H8300S)
4673 && !peep2_reg_dead_p (1, operands[0])
4674 && (INTVAL (operands[1]) == 1
4675 || (TARGET_H8300S && INTVAL (operands[1]) == 3))
4676 && !same_cmp_preceding_p (insn)"
4677 [(set (match_dup 4)
4678 (match_dup 0))
4679 (parallel [(set (match_dup 4)
4680 (ashiftrt:SI (match_dup 4)
4681 (match_dup 6)))
4682 (clobber (scratch:QI))])
4683 (set (cc0)
4684 (match_dup 4))
4685 (set (pc)
4686 (if_then_else (match_dup 5)
4687 (label_ref (match_dup 3))
4688 (pc)))]
4689 "switch (GET_CODE (operands[2]))
4690 {
4691 case GTU:
4692 operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4693 break;
4694 case LEU:
4695 operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4696 break;
4697 default:
4698 operands[5] = operands[2];
4699 break;
4700 }
4701 operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4702
4703 ;; Transform
4704 ;;
4705 ;; cmp.l #1,er0
4706 ;; bhi .L1
4707 ;;
4708 ;; into
4709 ;;
4710 ;; shar.l er0
4711 ;; bne .L1
4712
4713 (define_peephole2
4714 [(set (cc0)
4715 (compare (match_operand:SI 0 "register_operand" "")
4716 (match_operand:SI 1 "const_int_operand" "")))
4717 (set (pc)
4718 (if_then_else (match_operator 2 "gtle_operator"
4719 [(cc0) (const_int 0)])
4720 (label_ref (match_operand 3 "" ""))
4721 (pc)))]
4722 "(TARGET_H8300H || TARGET_H8300S)
4723 && peep2_reg_dead_p (1, operands[0])
4724 && (INTVAL (operands[1]) == 1
4725 || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
4726 [(parallel [(set (match_dup 0)
4727 (ashiftrt:SI (match_dup 0)
4728 (match_dup 5)))
4729 (clobber (scratch:QI))])
4730 (set (cc0)
4731 (match_dup 0))
4732 (set (pc)
4733 (if_then_else (match_dup 4)
4734 (label_ref (match_dup 3))
4735 (pc)))]
4736 "switch (GET_CODE (operands[2]))
4737 {
4738 case GTU:
4739 operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4740 break;
4741 case LEU:
4742 operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4743 break;
4744 default:
4745 operands[4] = operands[2];
4746 break;
4747 }
4748 operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
4749
4750 ;; Transform
4751 ;;
4752 ;; cmp.l #15,er0
4753 ;; bhi .L1
4754 ;;
4755 ;; into
4756 ;;
4757 ;; and #240,r0l
4758 ;; mov.l er0,er0
4759 ;; bne .L1
4760
4761 (define_peephole2
4762 [(set (cc0)
4763 (compare (match_operand:SI 0 "register_operand" "")
4764 (match_operand:SI 1 "const_int_operand" "")))
4765 (set (pc)
4766 (if_then_else (match_operator 2 "gtle_operator"
4767 [(cc0) (const_int 0)])
4768 (label_ref (match_operand 3 "" ""))
4769 (pc)))]
4770 "(TARGET_H8300H || TARGET_H8300S)
4771 && peep2_reg_dead_p (1, operands[0])
4772 && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
4773 || INTVAL (operands[1]) == 7
4774 || INTVAL (operands[1]) == 15
4775 || INTVAL (operands[1]) == 31
4776 || INTVAL (operands[1]) == 63
4777 || INTVAL (operands[1]) == 127
4778 || INTVAL (operands[1]) == 255)"
4779 [(set (match_dup 0)
4780 (and:SI (match_dup 0)
4781 (match_dup 5)))
4782 (set (cc0)
4783 (match_dup 0))
4784 (set (pc)
4785 (if_then_else (match_dup 4)
4786 (label_ref (match_dup 3))
4787 (pc)))]
4788 "switch (GET_CODE (operands[2]))
4789 {
4790 case GTU:
4791 operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4792 break;
4793 case LEU:
4794 operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4795 break;
4796 default:
4797 operands[4] = operands[2];
4798 break;
4799 }
4800 operands[5] = GEN_INT (~INTVAL (operands[1]));")
4801
4802 ;; Transform A <= 65535 to (A & 0xffff0000) == 0.
4803
4804 (define_peephole2
4805 [(set (cc0)
4806 (compare (match_operand:SI 0 "register_operand" "")
4807 (const_int 65535)))
4808 (set (pc)
4809 (if_then_else (match_operator 1 "gtle_operator"
4810 [(cc0) (const_int 0)])
4811 (label_ref (match_operand 2 "" ""))
4812 (pc)))]
4813 "TARGET_H8300H || TARGET_H8300S"
4814 [(set (cc0)
4815 (and:SI (match_dup 0)
4816 (const_int -65536)))
4817 (set (pc)
4818 (if_then_else (match_dup 3)
4819 (label_ref (match_dup 2))
4820 (pc)))]
4821 "switch (GET_CODE (operands[1]))
4822 {
4823 case GTU:
4824 operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
4825 break;
4826 case LEU:
4827 operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
4828 break;
4829 default:
4830 operands[3] = operands[1];
4831 break;
4832 }")
4833
4834 ;; For constants like -1, -2, 1, 2, it is still cheaper to make a copy
4835 ;; of the register being tested, do the subtraction on the copy, and
4836 ;; then test the copy. We avoid this transformation if we see more
4837 ;; than one copy of the same compare insn.
4838
4839 (define_peephole2
4840 [(match_scratch:SI 4 "r")
4841 (set (cc0)
4842 (compare (match_operand:SI 0 "register_operand" "")
4843 (match_operand:SI 1 "incdec_operand" "")))
4844 (set (pc)
4845 (if_then_else (match_operator 3 "eqne_operator"
4846 [(cc0) (const_int 0)])
4847 (label_ref (match_operand 2 "" ""))
4848 (pc)))]
4849 "(TARGET_H8300H || TARGET_H8300S)
4850 && !peep2_reg_dead_p (1, operands[0])
4851 && !same_cmp_following_p (insn)"
4852 [(set (match_dup 4)
4853 (match_dup 0))
4854 (set (match_dup 4)
4855 (unspec:SI [(match_dup 4)
4856 (match_dup 5)]
4857 UNSPEC_INCDEC))
4858 (set (cc0)
4859 (match_dup 4))
4860 (set (pc)
4861 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4862 (label_ref (match_dup 2))
4863 (pc)))]
4864 "operands[5] = GEN_INT (- INTVAL (operands[1]));")
4865
4866 ;; Narrow the mode of testing if possible.
4867
4868 (define_peephole2
4869 [(set (match_operand:HI 0 "register_operand" "")
4870 (and:HI (match_dup 0)
4871 (match_operand:HI 1 "const_int_qi_operand" "")))
4872 (set (cc0)
4873 (match_dup 0))
4874 (set (pc)
4875 (if_then_else (match_operator 3 "eqne_operator"
4876 [(cc0) (const_int 0)])
4877 (label_ref (match_operand 2 "" ""))
4878 (pc)))]
4879 "peep2_reg_dead_p (2, operands[0])"
4880 [(set (match_dup 4)
4881 (and:QI (match_dup 4)
4882 (match_dup 5)))
4883 (set (cc0)
4884 (match_dup 4))
4885 (set (pc)
4886 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4887 (label_ref (match_dup 2))
4888 (pc)))]
4889 "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
4890 operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
4891
4892 (define_peephole2
4893 [(set (match_operand:SI 0 "register_operand" "")
4894 (and:SI (match_dup 0)
4895 (match_operand:SI 1 "const_int_qi_operand" "")))
4896 (set (cc0)
4897 (match_dup 0))
4898 (set (pc)
4899 (if_then_else (match_operator 3 "eqne_operator"
4900 [(cc0) (const_int 0)])
4901 (label_ref (match_operand 2 "" ""))
4902 (pc)))]
4903 "peep2_reg_dead_p (2, operands[0])"
4904 [(set (match_dup 4)
4905 (and:QI (match_dup 4)
4906 (match_dup 5)))
4907 (set (cc0)
4908 (match_dup 4))
4909 (set (pc)
4910 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4911 (label_ref (match_dup 2))
4912 (pc)))]
4913 "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
4914 operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
4915
4916 (define_peephole2
4917 [(set (match_operand:SI 0 "register_operand" "")
4918 (and:SI (match_dup 0)
4919 (match_operand:SI 1 "const_int_hi_operand" "")))
4920 (set (cc0)
4921 (match_dup 0))
4922 (set (pc)
4923 (if_then_else (match_operator 3 "eqne_operator"
4924 [(cc0) (const_int 0)])
4925 (label_ref (match_operand 2 "" ""))
4926 (pc)))]
4927 "peep2_reg_dead_p (2, operands[0])"
4928 [(set (match_dup 4)
4929 (and:HI (match_dup 4)
4930 (match_dup 5)))
4931 (set (cc0)
4932 (match_dup 4))
4933 (set (pc)
4934 (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4935 (label_ref (match_dup 2))
4936 (pc)))]
4937 "operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
4938 operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);")
4939
4940 (define_peephole2
4941 [(set (match_operand:SI 0 "register_operand" "")
4942 (and:SI (match_dup 0)
4943 (match_operand:SI 1 "const_int_qi_operand" "")))
4944 (set (match_dup 0)
4945 (xor:SI (match_dup 0)
4946 (match_operand:SI 2 "const_int_qi_operand" "")))
4947 (set (cc0)
4948 (match_dup 0))
4949 (set (pc)
4950 (if_then_else (match_operator 4 "eqne_operator"
4951 [(cc0) (const_int 0)])
4952 (label_ref (match_operand 3 "" ""))
4953 (pc)))]
4954 "peep2_reg_dead_p (3, operands[0])
4955 && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
4956 [(set (match_dup 5)
4957 (and:QI (match_dup 5)
4958 (match_dup 6)))
4959 (set (match_dup 5)
4960 (xor:QI (match_dup 5)
4961 (match_dup 7)))
4962 (set (cc0)
4963 (match_dup 5))
4964 (set (pc)
4965 (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
4966 (label_ref (match_dup 3))
4967 (pc)))]
4968 "operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
4969 operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
4970 operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);")