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