]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/h8300/h8300.md
More cleanups. Merging patterns with iterators, split out peepholes, etc.
[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:HSI 0 "register_operand" "")
702 (plus:HSI (match_dup 0)
703 (match_operand:HSI 1 "two_insn_adds_subs_operand" "")))]
704 ""
705 [(const_int 0)]
706 {
707 split_adds_subs (<MODE>mode, 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 ;; ----------------------------------------------------------------------
726 ;; SUBTRACT INSTRUCTIONS
727 ;; ----------------------------------------------------------------------
728
729 (define_expand "sub<mode>3"
730 [(set (match_operand:QHSI 0 "register_operand" "")
731 (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
732 (match_operand:QHSI 2 "h8300_src_operand" "")))]
733 ""
734 {
735 })
736
737 (define_insn "*subqi3"
738 [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
739 (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
740 (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
741 "h8300_operands_match_p (operands)"
742 "sub.b %X2,%X0"
743 [(set_attr "length_table" "add")
744 (set_attr "cc" "set_zn")])
745
746 (define_insn "*sub<mode>3_h8300hs"
747 [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
748 (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
749 (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
750 "h8300_operands_match_p (operands)"
751 {
752 if (<MODE>mode == HImode)
753 return "sub.w %T2,%T0";
754 else if (<MODE>mode == SImode)
755 return "sub.l %S2,%S0";
756 gcc_unreachable ();
757 }
758 [(set_attr "length_table" "add")
759 (set_attr "cc" "set_zn")])
760
761 \f
762 ;; ----------------------------------------------------------------------
763 ;; MULTIPLY INSTRUCTIONS
764 ;; ----------------------------------------------------------------------
765
766 ;; Note that the H8/300 can only handle umulqihi3.
767
768 (define_expand "mulqihi3"
769 [(set (match_operand:HI 0 "register_operand" "")
770 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" ""))
771 ;; intentionally-mismatched modes
772 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
773 ""
774 {
775 if (GET_MODE (operands[2]) != VOIDmode)
776 operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
777 })
778
779 (define_insn "*mulqihi3_const"
780 [(set (match_operand:HI 0 "register_operand" "=r")
781 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
782 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
783 "TARGET_H8300SX"
784 "mulxs.b %X2,%T0"
785 [(set_attr "length" "4")
786 (set_attr "cc" "set_zn")])
787
788 (define_insn "*mulqihi3"
789 [(set (match_operand:HI 0 "register_operand" "=r")
790 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
791 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
792 ""
793 "mulxs.b %X2,%T0"
794 [(set_attr "length" "4")
795 (set_attr "cc" "set_zn")])
796
797 (define_expand "mulhisi3"
798 [(set (match_operand:SI 0 "register_operand" "")
799 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
800 ;; intentionally-mismatched modes
801 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
802 ""
803 {
804 if (GET_MODE (operands[2]) != VOIDmode)
805 operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
806 })
807
808 (define_insn "*mulhisi3_const"
809 [(set (match_operand:SI 0 "register_operand" "=r")
810 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
811 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
812 "TARGET_H8300SX"
813 "mulxs.w %T2,%S0"
814 [(set_attr "length" "4")
815 (set_attr "cc" "set_zn")])
816
817 (define_insn "*mulhisi3"
818 [(set (match_operand:SI 0 "register_operand" "=r")
819 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
820 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
821 ""
822 "mulxs.w %T2,%S0"
823 [(set_attr "length" "4")
824 (set_attr "cc" "set_zn")])
825
826 (define_expand "umulqihi3"
827 [(set (match_operand:HI 0 "register_operand" "")
828 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" ""))
829 ;; intentionally-mismatched modes
830 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
831 ""
832 {
833 if (GET_MODE (operands[2]) != VOIDmode)
834 operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]);
835 })
836
837 (define_insn "*umulqihi3_const"
838 [(set (match_operand:HI 0 "register_operand" "=r")
839 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
840 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
841 "TARGET_H8300SX"
842 "mulxu.b %X2,%T0"
843 [(set_attr "length" "4")
844 (set_attr "cc" "set_zn")])
845
846 (define_insn "*umulqihi3"
847 [(set (match_operand:HI 0 "register_operand" "=r")
848 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
849 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
850 ""
851 "mulxu.b %X2,%T0"
852 [(set_attr "length" "2")
853 (set_attr "cc" "none_0hit")])
854
855 (define_expand "umulhisi3"
856 [(set (match_operand:SI 0 "register_operand" "")
857 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
858 ;; intentionally-mismatched modes
859 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
860 ""
861 {
862 if (GET_MODE (operands[2]) != VOIDmode)
863 operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]);
864 })
865
866 (define_insn "*umulhisi3_const"
867 [(set (match_operand:SI 0 "register_operand" "=r")
868 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
869 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
870 "TARGET_H8300SX"
871 "mulxu.w %T2,%S0"
872 [(set_attr "length" "4")
873 (set_attr "cc" "set_zn")])
874
875 (define_insn "*umulhisi3"
876 [(set (match_operand:SI 0 "register_operand" "=r")
877 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
878 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
879 ""
880 "mulxu.w %T2,%S0"
881 [(set_attr "length" "2")
882 (set_attr "cc" "none_0hit")])
883
884 ;; We could have used mulu.[wl] here, but mulu.[lw] is only available
885 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
886 ;; on all H8SX variants.
887
888 (define_insn "mul<mode>3"
889 [(set (match_operand:HSI 0 "register_operand" "=r")
890 (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
891 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
892 "TARGET_H8300SX"
893 { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
894 [(set_attr "length" "4")
895 (set_attr "cc" "set_zn")])
896
897 (define_insn "smulsi3_highpart"
898 [(set (match_operand:SI 0 "register_operand" "=r")
899 (truncate:SI
900 (lshiftrt:DI
901 (mult:DI
902 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
903 (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
904 (const_int 32))))]
905 "TARGET_H8300SXMUL"
906 "muls/u.l\\t%S2,%S0"
907 [(set_attr "length" "4")
908 (set_attr "cc" "set_zn")])
909
910 (define_insn "umulsi3_highpart"
911 [(set (match_operand:SI 0 "register_operand" "=r")
912 (truncate:SI
913 (ashiftrt:DI
914 (mult:DI
915 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
916 (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
917 (const_int 32))))]
918 "TARGET_H8300SX"
919 "mulu/u.l\\t%S2,%S0"
920 [(set_attr "length" "4")
921 (set_attr "cc" "none_0hit")])
922
923 ;; This is a "bridge" instruction. Combine can't cram enough insns
924 ;; together to crate a MAC instruction directly, but it can create
925 ;; this instruction, which then allows combine to create the real
926 ;; MAC insn.
927 ;;
928 ;; Unfortunately, if combine doesn't create a MAC instruction, this
929 ;; insn must generate reasonably correct code. Egad.
930
931 (define_insn ""
932 [(set (match_operand:SI 0 "register_operand" "=a")
933 (mult:SI
934 (sign_extend:SI
935 (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
936 (sign_extend:SI
937 (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
938 "TARGET_MAC"
939 "clrmac\;mac @%2+,@%1+"
940 [(set_attr "length" "6")
941 (set_attr "cc" "none_0hit")])
942
943 (define_insn ""
944 [(set (match_operand:SI 0 "register_operand" "=a")
945 (plus:SI (mult:SI
946 (sign_extend:SI (mem:HI
947 (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
948 (sign_extend:SI (mem:HI
949 (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
950 (match_operand:SI 3 "register_operand" "0")))]
951 "TARGET_MAC"
952 "mac @%2+,@%1+"
953 [(set_attr "length" "4")
954 (set_attr "cc" "none_0hit")])
955
956 ;; ----------------------------------------------------------------------
957 ;; DIVIDE/MOD INSTRUCTIONS
958 ;; ----------------------------------------------------------------------
959
960 (define_insn "udiv<mode>3"
961 [(set (match_operand:HSI 0 "register_operand" "=r")
962 (udiv:HSI (match_operand:HSI 1 "register_operand" "0")
963 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
964 "TARGET_H8300SX"
965 { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
966 [(set_attr "length" "4")])
967
968 (define_insn "div<mode>3"
969 [(set (match_operand:HSI 0 "register_operand" "=r")
970 (div:HSI (match_operand:HSI 1 "register_operand" "0")
971 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
972 "TARGET_H8300SX"
973 { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
974 [(set_attr "length" "4")])
975
976 (define_insn "udivmodqi4"
977 [(set (match_operand:QI 0 "register_operand" "=r")
978 (truncate:QI
979 (udiv:HI
980 (match_operand:HI 1 "register_operand" "0")
981 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
982 (set (match_operand:QI 3 "register_operand" "=r")
983 (truncate:QI
984 (umod:HI
985 (match_dup 1)
986 (zero_extend:HI (match_dup 2)))))]
987 ""
988 {
989 if (find_reg_note (insn, REG_UNUSED, operands[3]))
990 return "divxu.b\\t%X2,%T0";
991 else
992 return "divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
993 }
994 [(set_attr "length" "4")])
995
996 (define_insn "divmodqi4"
997 [(set (match_operand:QI 0 "register_operand" "=r")
998 (truncate:QI
999 (div:HI
1000 (match_operand:HI 1 "register_operand" "0")
1001 (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1002 (set (match_operand:QI 3 "register_operand" "=r")
1003 (truncate:QI
1004 (mod:HI
1005 (match_dup 1)
1006 (sign_extend:HI (match_dup 2)))))]
1007 ""
1008 {
1009 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1010 return "divxs.b\\t%X2,%T0";
1011 else
1012 return "divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3";
1013 }
1014 [(set_attr "length" "6")])
1015
1016 (define_insn "udivmodhi4"
1017 [(set (match_operand:HI 0 "register_operand" "=r")
1018 (truncate:HI
1019 (udiv:SI
1020 (match_operand:SI 1 "register_operand" "0")
1021 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1022 (set (match_operand:HI 3 "register_operand" "=r")
1023 (truncate:HI
1024 (umod:SI
1025 (match_dup 1)
1026 (zero_extend:SI (match_dup 2)))))]
1027 ""
1028 {
1029 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1030 return "divxu.w\\t%T2,%S0";
1031 else
1032 return "divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1033 }
1034 [(set_attr "length" "4")])
1035
1036 (define_insn "divmodhi4"
1037 [(set (match_operand:HI 0 "register_operand" "=r")
1038 (truncate:HI
1039 (div:SI
1040 (match_operand:SI 1 "register_operand" "0")
1041 (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1042 (set (match_operand:HI 3 "register_operand" "=r")
1043 (truncate:HI
1044 (mod:SI
1045 (match_dup 1)
1046 (sign_extend:SI (match_dup 2)))))]
1047 ""
1048 {
1049 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1050 return "divxs.w\\t%T2,%S0";
1051 else
1052 return "divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3";
1053 }
1054 [(set_attr "length" "6")])
1055 \f
1056 ;; ----------------------------------------------------------------------
1057 ;; AND INSTRUCTIONS
1058 ;; ----------------------------------------------------------------------
1059
1060 (define_insn "bclrqi_msx"
1061 [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1062 (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1063 (match_operand:QI 2 "single_zero_operand" "Y0")))]
1064 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1065 "bclr\\t%W2,%0"
1066 [(set_attr "length" "8")])
1067
1068 (define_split
1069 [(set (match_operand:HI 0 "bit_register_indirect_operand")
1070 (and:HI (match_operand:HI 1 "bit_register_indirect_operand")
1071 (match_operand:HI 2 "single_zero_operand")))]
1072 "TARGET_H8300SX"
1073 [(set (match_dup 0)
1074 (and:QI (match_dup 1)
1075 (match_dup 2)))]
1076 {
1077 if (abs (INTVAL (operands[2])) > 0xFF)
1078 {
1079 operands[0] = adjust_address (operands[0], QImode, 0);
1080 operands[1] = adjust_address (operands[1], QImode, 0);
1081 operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1082 }
1083 else
1084 {
1085 operands[0] = adjust_address (operands[0], QImode, 1);
1086 operands[1] = adjust_address (operands[1], QImode, 1);
1087 }
1088 })
1089
1090 (define_insn "bclrhi_msx"
1091 [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1092 (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1093 (match_operand:HI 2 "single_zero_operand" "Y0")))]
1094 "TARGET_H8300SX"
1095 "bclr\\t%W2,%0"
1096 [(set_attr "length" "8")])
1097
1098 (define_insn "*andqi3_2"
1099 [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
1100 (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
1101 (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
1102 "TARGET_H8300SX"
1103 "@
1104 bclr\\t %W2,%R0
1105 and %X2,%X0
1106 bfld %2,%1,%R0"
1107 [(set_attr "length" "8,*,8")
1108 (set_attr "length_table" "*,logicb,*")
1109 (set_attr "cc" "none_0hit,set_znv,none_0hit")])
1110
1111 (define_insn "andqi3_1"
1112 [(set (match_operand:QI 0 "bit_operand" "=U,r")
1113 (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1114 (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
1115 "register_operand (operands[0], QImode)
1116 || single_zero_operand (operands[2], QImode)"
1117 "@
1118 bclr %W2,%R0
1119 and %X2,%X0"
1120 [(set_attr "length" "2,8")
1121 (set_attr "cc" "none_0hit,set_znv")])
1122
1123 (define_expand "and<mode>3"
1124 [(set (match_operand:QHSI 0 "register_operand" "")
1125 (and:QHSI (match_operand:QHSI 1 "register_operand" "")
1126 (match_operand:QHSI 2 "h8300_src_operand" "")))]
1127 ""
1128 "")
1129
1130 (define_insn "*andor<mode>3"
1131 [(set (match_operand:QHSI 0 "register_operand" "=r")
1132 (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
1133 (match_operand:QHSI 3 "single_one_operand" "n"))
1134 (match_operand:QHSI 1 "register_operand" "0")))]
1135 "(<MODE>mode == QImode
1136 || <MODE>mode == HImode
1137 || (<MODE>mode == SImode
1138 && (INTVAL (operands[3]) & 0xffff) != 0))"
1139 {
1140 if (<MODE>mode == QImode)
1141 return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
1142
1143 if (<MODE>mode == HImode)
1144 {
1145 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1146 if (INTVAL (operands[3]) > 128)
1147 {
1148 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1149 return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
1150 }
1151 return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
1152 }
1153
1154 if (<MODE>mode == SImode)
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,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
1161 }
1162 return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
1163 }
1164
1165 gcc_unreachable ();
1166
1167 }
1168 [(set_attr "length" "6")])
1169
1170 (define_insn "*andorsi3_shift_8"
1171 [(set (match_operand:SI 0 "register_operand" "=r")
1172 (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1173 (const_int 8))
1174 (const_int 65280))
1175 (match_operand:SI 1 "register_operand" "0")))]
1176 ""
1177 "or.b\\t%w2,%x0"
1178 [(set_attr "length" "2")])
1179
1180 ;; ----------------------------------------------------------------------
1181 ;; OR/XOR INSTRUCTIONS
1182 ;; ----------------------------------------------------------------------
1183
1184 (define_insn "b<code>qi_msx"
1185 [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1186 (ors:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1187 (match_operand:QI 2 "single_one_operand" "Y2")))]
1188 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
1189 { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
1190 [(set_attr "length" "8")])
1191
1192 (define_insn "b<code>hi_msx"
1193 [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1194 (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1195 (match_operand:HI 2 "single_one_operand" "Y2")))]
1196 "TARGET_H8300SX"
1197 { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
1198 [(set_attr "length" "8")])
1199
1200 (define_insn "<code>qi3_1"
1201 [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
1202 (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
1203 (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1204 "TARGET_H8300SX || register_operand (operands[0], QImode)
1205 || single_one_operand (operands[2], QImode)"
1206 {
1207 if (which_alternative == 0)
1208 return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
1209 else if (which_alternative == 1)
1210 return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
1211 gcc_unreachable ();
1212 }
1213 [(set_attr "length" "8,*")
1214 (set_attr "length_table" "*,logicb")
1215 (set_attr "cc" "none_0hit,set_znv")])
1216
1217 (define_expand "<code><mode>3"
1218 [(set (match_operand:QHSI 0 "register_operand" "")
1219 (ors:QHSI (match_operand:QHSI 1 "register_operand" "")
1220 (match_operand:QHSI 2 "h8300_src_operand" "")))]
1221 ""
1222 "")
1223
1224 ;; ----------------------------------------------------------------------
1225 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1226 ;; ----------------------------------------------------------------------
1227
1228 (define_insn "*logical<mode>3"
1229 [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
1230 (match_operator:HSI 3 "bit_operator"
1231 [(match_operand:HSI 1 "h8300_dst_operand" "%0")
1232 (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
1233 "h8300_operands_match_p (operands)"
1234 { return output_logical_op (<MODE>mode, operands); }
1235 [(set (attr "length")
1236 (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
1237 (set (attr "cc")
1238 (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
1239 \f
1240 ;; ----------------------------------------------------------------------
1241 ;; NEGATION INSTRUCTIONS
1242 ;; ----------------------------------------------------------------------
1243
1244 (define_expand "neg<mode>2"
1245 [(set (match_operand:QHSIF 0 "register_operand" "")
1246 (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
1247 ""
1248 "")
1249
1250 (define_insn "*neg<mode>2"
1251 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
1252 (neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
1253 ""
1254 {
1255 if (<MODE>mode == E_QImode)
1256 return "neg %X0";
1257 if (<MODE>mode == E_HImode)
1258 return "neg.w %T0";
1259 if (<MODE>mode == E_SImode)
1260 return "neg.l %S0";
1261 gcc_unreachable ();
1262 }
1263 [(set_attr "length_table" "unary")
1264 (set_attr "cc" "set_zn")])
1265
1266
1267 (define_insn "*negsf2_h8300hs"
1268 [(set (match_operand:SF 0 "register_operand" "=r")
1269 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1270 ""
1271 "xor.w\\t#32768,%e0"
1272 [(set_attr "length" "4")])
1273
1274 \f
1275 ;; ----------------------------------------------------------------------
1276 ;; ABSOLUTE VALUE INSTRUCTIONS
1277 ;; ----------------------------------------------------------------------
1278
1279 (define_insn "abssf2"
1280 [(set (match_operand:SF 0 "register_operand" "=r")
1281 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1282 ""
1283 "and.w\\t#32767,%e0"
1284 [(set_attr "length" "4")])
1285 \f
1286 ;; ----------------------------------------------------------------------
1287 ;; NOT INSTRUCTIONS
1288 ;; ----------------------------------------------------------------------
1289
1290 (define_insn "one_cmpl<mode>2"
1291 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
1292 (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
1293 ""
1294 {
1295 if (<MODE>mode == E_QImode)
1296 return "not %X0";
1297 if (<MODE>mode == E_HImode)
1298 return "not.w %T0";
1299 if (<MODE>mode == E_SImode)
1300 return "not.l %S0";
1301 gcc_unreachable ();
1302 }
1303 [(set_attr "length_table" "unary")
1304 (set_attr "cc" "set_znv")])
1305
1306 \f
1307 ;; ----------------------------------------------------------------------
1308 ;; JUMP INSTRUCTIONS
1309 ;; ----------------------------------------------------------------------
1310
1311 ;; Conditional jump instructions
1312
1313 (define_expand "cbranchqi4"
1314 [(use (match_operator 0 "ordered_comparison_operator"
1315 [(match_operand:QI 1 "h8300_dst_operand" "")
1316 (match_operand:QI 2 "h8300_src_operand" "")]))
1317 (use (match_operand 3 ""))]
1318 ""
1319 {
1320 h8300_expand_branch (operands);
1321 DONE;
1322 })
1323
1324 (define_expand "cbranchhi4"
1325 [(use (match_operator 0 "ordered_comparison_operator"
1326 [(match_operand:HI 1 "h8300_dst_operand" "")
1327 (match_operand:HI 2 "h8300_src_operand" "")]))
1328 (use (match_operand 3 ""))]
1329 ""
1330 {
1331 h8300_expand_branch (operands);
1332 DONE;
1333 })
1334
1335 (define_expand "cbranchsi4"
1336 [(use (match_operator 0 "ordered_comparison_operator"
1337 [(match_operand:SI 1 "h8300_dst_operand" "")
1338 (match_operand:SI 2 "h8300_src_operand" "")]))
1339 (use (match_operand 3 ""))]
1340 ""
1341 {
1342 h8300_expand_branch (operands);
1343 DONE;
1344 })
1345
1346 (define_insn "branch_true"
1347 [(set (pc)
1348 (if_then_else (match_operator 1 "comparison_operator"
1349 [(cc0) (const_int 0)])
1350 (label_ref (match_operand 0 "" ""))
1351 (pc)))]
1352 ""
1353 {
1354 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1355 && (GET_CODE (operands[1]) == GT
1356 || GET_CODE (operands[1]) == GE
1357 || GET_CODE (operands[1]) == LE
1358 || GET_CODE (operands[1]) == LT))
1359 {
1360 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1361 return 0;
1362 }
1363
1364 if (get_attr_length (insn) == 2)
1365 return "b%j1 %l0";
1366 else if (get_attr_length (insn) == 4)
1367 return "b%j1 %l0:16";
1368 else
1369 return "b%k1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1370 }
1371 [(set_attr "type" "branch")
1372 (set_attr "cc" "none")])
1373
1374 (define_insn "branch_false"
1375 [(set (pc)
1376 (if_then_else (match_operator 1 "comparison_operator"
1377 [(cc0) (const_int 0)])
1378 (pc)
1379 (label_ref (match_operand 0 "" ""))))]
1380 ""
1381 {
1382 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1383 && (GET_CODE (operands[1]) == GT
1384 || GET_CODE (operands[1]) == GE
1385 || GET_CODE (operands[1]) == LE
1386 || GET_CODE (operands[1]) == LT))
1387 {
1388 cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
1389 return 0;
1390 }
1391
1392 if (get_attr_length (insn) == 2)
1393 return "b%k1 %l0";
1394 else if (get_attr_length (insn) == 4)
1395 return "b%k1 %l0:16";
1396 else
1397 return "b%j1 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1398 }
1399 [(set_attr "type" "branch")
1400 (set_attr "cc" "none")])
1401
1402 (define_insn "*brabc"
1403 [(set (pc)
1404 (if_then_else (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1405 (const_int 1)
1406 (match_operand:QI 2 "immediate_operand" "n"))
1407 (const_int 0))
1408 (label_ref (match_operand 0 "" ""))
1409 (pc)))]
1410 "TARGET_H8300SX"
1411 {
1412 switch (get_attr_length (insn)
1413 - h8300_insn_length_from_table (insn, operands))
1414 {
1415 case 2:
1416 return "bra/bc %2,%R1,%l0";
1417 case 4:
1418 return "bra/bc %2,%R1,%l0:16";
1419 default:
1420 return "bra/bs %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1421 }
1422 }
1423 [(set_attr "type" "bitbranch")
1424 (set_attr "length_table" "bitbranch")
1425 (set_attr "cc" "none")])
1426
1427 (define_insn "*brabs"
1428 [(set (pc)
1429 (if_then_else (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
1430 (const_int 1)
1431 (match_operand:QI 2 "immediate_operand" "n"))
1432 (const_int 0))
1433 (label_ref (match_operand 0 "" ""))
1434 (pc)))]
1435 "TARGET_H8300SX"
1436 {
1437 switch (get_attr_length (insn)
1438 - h8300_insn_length_from_table (insn, operands))
1439 {
1440 case 2:
1441 return "bra/bs %2,%R1,%l0";
1442 case 4:
1443 return "bra/bs %2,%R1,%l0:16";
1444 default:
1445 return "bra/bc %2,%R1,.Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:";
1446 }
1447 }
1448 [(set_attr "type" "bitbranch")
1449 (set_attr "length_table" "bitbranch")
1450 (set_attr "cc" "none")])
1451
1452 ;; Unconditional and other jump instructions.
1453
1454 (define_insn "jump"
1455 [(set (pc)
1456 (label_ref (match_operand 0 "" "")))]
1457 ""
1458 {
1459 if (final_sequence != 0)
1460 {
1461 if (get_attr_length (insn) == 2)
1462 return "bra/s %l0";
1463 else
1464 {
1465 /* The branch isn't short enough to use bra/s. Output the
1466 branch and delay slot in their normal order.
1467
1468 If this is a backward branch, it will now be branching two
1469 bytes further than previously thought. The length-based
1470 test for bra vs. jump is very conservative though, so the
1471 branch will still be within range. */
1472 rtx_sequence *seq;
1473 int seen;
1474
1475 seq = final_sequence;
1476 final_sequence = 0;
1477 final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen);
1478 final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen);
1479 seq->insn (1)->set_deleted ();
1480 return "";
1481 }
1482 }
1483 else if (get_attr_length (insn) == 2)
1484 return "bra %l0";
1485 else if (get_attr_length (insn) == 4)
1486 return "bra %l0:16";
1487 else
1488 return "jmp @%l0";
1489 }
1490 [(set_attr "type" "branch")
1491 (set (attr "delay_slot")
1492 (if_then_else (match_test "TARGET_H8300SX")
1493 (const_string "jump")
1494 (const_string "none")))
1495 (set_attr "cc" "none")])
1496
1497 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1498
1499 (define_expand "tablejump"
1500 [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
1501 (use (label_ref (match_operand 1 "" "")))])]
1502 ""
1503 "")
1504
1505 (define_insn "tablejump<mode>"
1506 [(set (pc) (match_operand:P 0 "register_operand" "r"))
1507 (use (label_ref (match_operand 1 "" "")))]
1508 ""
1509 {
1510 if (<MODE>mode == E_HImode)
1511 return "jmp @%0";
1512 if (<MODE>mode == E_SImode)
1513 return "jmp @%S0";
1514 gcc_unreachable ();
1515 }
1516 [(set_attr "cc" "none")
1517 (set_attr "length" "2")])
1518
1519 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1520
1521 (define_expand "indirect_jump"
1522 [(set (pc) (match_operand 0 "jump_address_operand" ""))]
1523 ""
1524 "")
1525
1526 (define_insn "*indirect_jump_<mode>"
1527 [(set (pc) (match_operand:P 0 "jump_address_operand" "Vr"))]
1528 ""
1529 {
1530 if (<MODE>mode == E_HImode)
1531 return "jmp @%0";
1532 if (<MODE>mode == E_SImode)
1533 return "jmp @%S0";
1534 gcc_unreachable ();
1535 }
1536 [(set_attr "cc" "none")
1537 (set_attr "length" "2")])
1538
1539 ;; Call subroutine with no return value.
1540
1541 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1542
1543 (define_expand "call"
1544 [(call (match_operand:QI 0 "call_expander_operand" "")
1545 (match_operand 1 "general_operand" ""))]
1546 ""
1547 {
1548 if (!register_operand (XEXP (operands[0], 0), Pmode)
1549 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
1550 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
1551 })
1552
1553 (define_insn "call_insn_<mode>"
1554 [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
1555 (match_operand:P 1 "general_operand" "g"))]
1556 ""
1557 {
1558 rtx xoperands[1];
1559 xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
1560 gcc_assert (GET_MODE (operands[0]) == Pmode);
1561 if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
1562 && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
1563 output_asm_insn ("jsr\\t@%0:8", xoperands);
1564 else
1565 output_asm_insn ("jsr\\t%0", xoperands);
1566 return "";
1567 }
1568 [(set_attr "type" "call")
1569 (set (attr "length")
1570 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1571 (const_int 2)
1572 (const_int 4)))])
1573
1574 ;; Call subroutine, returning value in operand 0
1575 ;; (which must be a hard register).
1576
1577 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
1578
1579 (define_expand "call_value"
1580 [(set (match_operand 0 "" "")
1581 (call (match_operand:QI 1 "call_expander_operand" "")
1582 (match_operand 2 "general_operand" "")))]
1583 ""
1584 {
1585 if (!register_operand (XEXP (operands[1], 0), Pmode)
1586 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
1587 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
1588 })
1589
1590 (define_insn "call_value_insn_<mode>"
1591 [(set (match_operand 0 "" "=r")
1592 (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
1593 (match_operand:P 2 "general_operand" "g")))]
1594 ""
1595 {
1596 rtx xoperands[2];
1597 gcc_assert (GET_MODE (operands[1]) == Pmode);
1598 xoperands[0] = operands[0];
1599 xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
1600 if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
1601 && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
1602 output_asm_insn ("jsr\\t@%1:8", xoperands);
1603 else
1604 output_asm_insn ("jsr\\t%1", xoperands);
1605 return "";
1606 }
1607 [(set_attr "type" "call")
1608 (set (attr "length")
1609 (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1610 (const_int 2)
1611 (const_int 4)))])
1612
1613 (define_insn "nop"
1614 [(const_int 0)]
1615 ""
1616 "nop"
1617 [(set_attr "cc" "none")
1618 (set_attr "length" "2")])
1619 \f
1620 ;; ----------------------------------------------------------------------
1621 ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
1622 ;; ----------------------------------------------------------------------
1623
1624 (define_expand "push_h8300hs_advanced"
1625 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
1626 (match_operand:SI 0 "register_operand" ""))]
1627 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1628 "")
1629
1630 (define_expand "push_h8300hs_normal"
1631 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
1632 (match_operand:SI 0 "register_operand" ""))]
1633 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1634 "")
1635
1636 (define_expand "pop_h8300hs_advanced"
1637 [(set (match_operand:SI 0 "register_operand" "")
1638 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
1639 "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
1640 "")
1641
1642 (define_expand "pop_h8300hs_normal"
1643 [(set (match_operand:SI 0 "register_operand" "")
1644 (mem:SI (post_inc:HI (reg:HI SP_REG))))]
1645 "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
1646 "")
1647
1648 (define_insn "ldm_h8300sx"
1649 [(match_parallel 0 "h8300_ldm_parallel"
1650 [(set (match_operand:SI 1 "register_operand" "")
1651 (match_operand:SI 2 "memory_operand" ""))])]
1652 "TARGET_H8300S"
1653 {
1654 operands[3] = SET_DEST (XVECEXP (operands[0], 0,
1655 XVECLEN (operands[0], 0) - 2));
1656 return "ldm.l\t@er7+,%S1-%S3";
1657 }
1658 [(set_attr "cc" "none")
1659 (set_attr "length" "4")])
1660
1661 (define_insn "stm_h8300sx"
1662 [(match_parallel 0 "h8300_stm_parallel"
1663 [(set (match_operand:SI 1 "memory_operand" "")
1664 (match_operand:SI 2 "register_operand" ""))])]
1665 "TARGET_H8300S"
1666 {
1667 operands[3] = SET_SRC (XVECEXP (operands[0], 0,
1668 XVECLEN (operands[0], 0) - 2));
1669 return "stm.l\t%S2-%S3,@-er7";
1670 }
1671 [(set_attr "cc" "none")
1672 (set_attr "length" "4")])
1673
1674 (define_insn "return_h8sx"
1675 [(match_parallel 0 "h8300_return_parallel"
1676 [(return)
1677 (set (match_operand:SI 1 "register_operand" "")
1678 (match_operand:SI 2 "memory_operand" ""))])]
1679 "TARGET_H8300SX"
1680 {
1681 operands[3] = SET_DEST (XVECEXP (operands[0], 0,
1682 XVECLEN (operands[0], 0) - 2));
1683 if (h8300_current_function_interrupt_function_p ()
1684 || h8300_current_function_monitor_function_p ())
1685 return "rte/l\t%S1-%S3";
1686 else
1687 return "rts/l\t%S1-%S3";
1688 }
1689 [(set_attr "cc" "none")
1690 (set_attr "can_delay" "no")
1691 (set_attr "length" "2")])
1692
1693 (define_expand "return"
1694 [(return)]
1695 "h8300_can_use_return_insn_p ()"
1696 "")
1697
1698 (define_insn "*return_1"
1699 [(return)]
1700 "reload_completed"
1701 {
1702 if (h8300_current_function_interrupt_function_p ()
1703 || h8300_current_function_monitor_function_p ())
1704 return "rte";
1705 else
1706 return "rts";
1707 }
1708 [(set_attr "cc" "none")
1709 (set_attr "can_delay" "no")
1710 (set_attr "length" "2")])
1711
1712 (define_expand "prologue"
1713 [(const_int 0)]
1714 ""
1715 {
1716 h8300_expand_prologue ();
1717 DONE;
1718 })
1719
1720 (define_expand "epilogue"
1721 [(return)]
1722 ""
1723 {
1724 h8300_expand_epilogue ();
1725 DONE;
1726 })
1727
1728 (define_insn "monitor_prologue"
1729 [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
1730 ""
1731 {
1732 if (TARGET_H8300H && TARGET_NORMAL_MODE)
1733 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";
1734 else if (TARGET_H8300H)
1735 return "mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr";
1736 else if (TARGET_H8300S && TARGET_NEXR )
1737 return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr";
1738 else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
1739 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";
1740 else if (TARGET_H8300S && TARGET_NORMAL_MODE)
1741 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";
1742 else if (TARGET_H8300S)
1743 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";
1744 gcc_unreachable ();
1745 }
1746 [(set_attr "length" "20")])
1747 \f
1748 ;; ----------------------------------------------------------------------
1749 ;; EXTEND INSTRUCTIONS
1750 ;; ----------------------------------------------------------------------
1751
1752 (define_expand "zero_extendqi<mode>2"
1753 [(set (match_operand:HSI 0 "register_operand" "")
1754 (zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
1755 ""
1756 {
1757 if (TARGET_H8300SX)
1758 operands[1] = force_reg (QImode, operands[1]);
1759 })
1760
1761 (define_insn "*zero_extendqihi2_h8300hs"
1762 [(set (match_operand:HI 0 "register_operand" "=r,r")
1763 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1764 ""
1765 "@
1766 extu.w %T0
1767 #"
1768 [(set_attr "length" "2,10")
1769 (set_attr "cc" "set_znv,set_znv")])
1770
1771 ;; Split the zero extension of a general operand (actually a memory
1772 ;; operand) into a load of the operand and the actual zero extension
1773 ;; so that 1) the length will be accurate, and 2) the zero extensions
1774 ;; appearing at the end of basic blocks may be merged.
1775
1776 (define_split
1777 [(set (match_operand:HI 0 "register_operand" "")
1778 (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
1779 "reload_completed"
1780 [(set (match_dup 2)
1781 (match_dup 1))
1782 (set (match_dup 0)
1783 (zero_extend:HI (match_dup 2)))]
1784 {
1785 operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
1786 })
1787
1788 (define_insn "*zero_extendqisi2_h8300hs"
1789 [(set (match_operand:SI 0 "register_operand" "=r,r")
1790 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
1791 "!TARGET_H8300SX"
1792 "#")
1793
1794 (define_split
1795 [(set (match_operand:SI 0 "register_operand" "")
1796 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
1797 "!TARGET_H8300SX
1798 && reg_overlap_mentioned_p (operands[0], operands[1])
1799 && reload_completed"
1800 [(set (match_dup 2)
1801 (match_dup 1))
1802 (set (match_dup 3)
1803 (zero_extend:HI (match_dup 2)))
1804 (set (match_dup 0)
1805 (zero_extend:SI (match_dup 3)))]
1806 {
1807 operands[2] = gen_lowpart (QImode, operands[0]);
1808 operands[3] = gen_lowpart (HImode, operands[0]);
1809 })
1810
1811 (define_split
1812 [(set (match_operand:SI 0 "register_operand" "")
1813 (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
1814 "!TARGET_H8300SX
1815 && !reg_overlap_mentioned_p (operands[0], operands[1])
1816 && reload_completed"
1817 [(set (match_dup 0)
1818 (const_int 0))
1819 (set (strict_low_part (match_dup 2))
1820 (match_dup 1))]
1821 {
1822 operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
1823 })
1824
1825 (define_insn "*zero_extendqisi2_h8sx"
1826 [(set (match_operand:SI 0 "register_operand" "=r")
1827 (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
1828 "TARGET_H8300SX"
1829 "extu.l\t#2,%0"
1830 [(set_attr "length" "2")
1831 (set_attr "cc" "set_znv")])
1832
1833 (define_expand "zero_extendhisi2"
1834 [(set (match_operand:SI 0 "register_operand" "")
1835 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1836 ""
1837 "")
1838
1839 (define_insn "*zero_extendhisi2_h8300hs"
1840 [(set (match_operand:SI 0 "register_operand" "=r")
1841 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1842 ""
1843 "extu.l %S0"
1844 [(set_attr "length" "2")
1845 (set_attr "cc" "set_znv")])
1846
1847 (define_expand "extendqi<mode>2"
1848 [(set (match_operand:HSI 0 "register_operand" "")
1849 (sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
1850 ""
1851 "")
1852
1853 (define_insn "*extendqihi2_h8300hs"
1854 [(set (match_operand:HI 0 "register_operand" "=r")
1855 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
1856 ""
1857 "exts.w %T0"
1858 [(set_attr "length" "2")
1859 (set_attr "cc" "set_znv")])
1860
1861 ;; The following pattern is needed because without the pattern, the
1862 ;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
1863 ;; shifts, one ashift and one ashiftrt.
1864
1865 (define_insn_and_split "*extendqisi2_h8300hs"
1866 [(set (match_operand:SI 0 "register_operand" "=r")
1867 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
1868 "!TARGET_H8300SX"
1869 "#"
1870 "&& reload_completed"
1871 [(set (match_dup 2)
1872 (sign_extend:HI (match_dup 1)))
1873 (set (match_dup 0)
1874 (sign_extend:SI (match_dup 2)))]
1875 {
1876 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1877 })
1878
1879 (define_insn "*extendqisi2_h8sx"
1880 [(set (match_operand:SI 0 "register_operand" "=r")
1881 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
1882 "TARGET_H8300SX"
1883 "exts.l\t#2,%0"
1884 [(set_attr "length" "2")
1885 (set_attr "cc" "set_znv")])
1886
1887 (define_expand "extendhisi2"
1888 [(set (match_operand:SI 0 "register_operand" "")
1889 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1890 ""
1891 "")
1892
1893 (define_insn "*extendhisi2_h8300hs"
1894 [(set (match_operand:SI 0 "register_operand" "=r")
1895 (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1896 ""
1897 "exts.l %S0"
1898 [(set_attr "length" "2")
1899 (set_attr "cc" "set_znv")])
1900 \f
1901 ;; ----------------------------------------------------------------------
1902 ;; SHIFTS
1903 ;; ----------------------------------------------------------------------
1904 ;;
1905 ;; We make some attempt to provide real efficient shifting. One example is
1906 ;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
1907 ;; reg and moving 0 into the former reg.
1908 ;;
1909 ;; We also try to achieve this in a uniform way. IE: We don't try to achieve
1910 ;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would
1911 ;; give the optimizer more cracks at the code. However, we wish to do things
1912 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
1913 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
1914 ;; 16-bit rotates. Also, if we emit complicated rtl, combine may not be able
1915 ;; to detect cases it can optimize.
1916 ;;
1917 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
1918 ;; easier "do it at insn emit time" route.
1919
1920
1921 (define_expand "ashl<mode>3"
1922 [(set (match_operand:QHSI 0 "register_operand" "")
1923 (ashift:QHSI (match_operand:QHSI 1 "register_operand" "")
1924 (match_operand:QI 2 "nonmemory_operand" "")))]
1925 ""
1926 {
1927 if (expand_a_shift (<MODE>mode, ASHIFT, operands))
1928 DONE;
1929 })
1930
1931 (define_expand "ashr<mode>3"
1932 [(set (match_operand:QHSI 0 "register_operand" "")
1933 (ashiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
1934 (match_operand:QI 2 "nonmemory_operand" "")))]
1935 ""
1936 {
1937 if (expand_a_shift (<MODE>mode, ASHIFTRT, operands))
1938 DONE;
1939 })
1940
1941 (define_expand "lshr<mode>3"
1942 [(set (match_operand:QHSI 0 "register_operand" "")
1943 (lshiftrt:QHSI (match_operand:QHSI 1 "register_operand" "")
1944 (match_operand:QI 2 "nonmemory_operand" "")))]
1945 ""
1946 {
1947 if (expand_a_shift (<MODE>mode, LSHIFTRT, operands))
1948 DONE;
1949 })
1950
1951 ;; QI/HI/SI BIT SHIFTS
1952 ;; Sub-optimal WRT the scratch operand
1953
1954 (define_insn ""
1955 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
1956 (match_operator:QHSI 3 "h8sx_unary_shift_operator"
1957 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
1958 (match_operand:QI 2 "const_int_operand" "")]))]
1959 "h8300_operands_match_p (operands)"
1960 {
1961 if (<MODE>mode == E_QImode)
1962 return output_h8sx_shift (operands, 'b', 'X');
1963 if (<MODE>mode == E_HImode)
1964 return output_h8sx_shift (operands, 'w', 'T');
1965 if (<MODE>mode == E_SImode)
1966 return output_h8sx_shift (operands, 'l', 'S');
1967 gcc_unreachable ();
1968 }
1969 [(set_attr "length_table" "unary")
1970 (set_attr "cc" "set_znv")])
1971
1972 (define_insn ""
1973 [(set (match_operand:QHSI 0 "register_operand" "=r")
1974 (match_operator:QHSI 3 "h8sx_binary_shift_operator"
1975 [(match_operand:QHSI 1 "register_operand" "0")
1976 (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
1977 ""
1978 {
1979 if (<MODE>mode == QImode)
1980 return output_h8sx_shift (operands, 'b', 'X');
1981 if (<MODE>mode == HImode)
1982 return output_h8sx_shift (operands, 'w', 'T');
1983 if (<MODE>mode == SImode)
1984 return output_h8sx_shift (operands, 'l', 'S');
1985 gcc_unreachable ();
1986 }
1987 [(set_attr "length" "4")
1988 (set_attr "cc" "set_znv")])
1989
1990 (define_insn "*shiftqi"
1991 [(set (match_operand:QI 0 "register_operand" "=r,r")
1992 (match_operator:QI 3 "nshift_operator"
1993 [(match_operand:QI 1 "register_operand" "0,0")
1994 (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
1995 (clobber (match_scratch:QI 4 "=X,&r"))]
1996 ""
1997 {
1998 return output_a_shift (operands);
1999 }
2000 [(set (attr "length")
2001 (symbol_ref "compute_a_shift_length (insn, operands)"))
2002 (set (attr "cc")
2003 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2004
2005 (define_insn "*shifthi"
2006 [(set (match_operand:HI 0 "register_operand" "=r,r")
2007 (match_operator:HI 3 "nshift_operator"
2008 [(match_operand:HI 1 "register_operand" "0,0")
2009 (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
2010 (clobber (match_scratch:QI 4 "=X,&r"))]
2011 ""
2012 {
2013 return output_a_shift (operands);
2014 }
2015 [(set (attr "length")
2016 (symbol_ref "compute_a_shift_length (insn, operands)"))
2017 (set (attr "cc")
2018 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2019
2020 (define_insn "*shiftsi"
2021 [(set (match_operand:SI 0 "register_operand" "=r,r")
2022 (match_operator:SI 3 "nshift_operator"
2023 [(match_operand:SI 1 "register_operand" "0,0")
2024 (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
2025 (clobber (match_scratch:QI 4 "=X,&r"))]
2026 ""
2027 {
2028 return output_a_shift (operands);
2029 }
2030 [(set (attr "length")
2031 (symbol_ref "compute_a_shift_length (insn, operands)"))
2032 (set (attr "cc")
2033 (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2034
2035
2036 ;; Split a variable shift into a loop. If the register containing
2037 ;; the shift count dies, then we just use that register.
2038
2039 (define_split
2040 [(set (match_operand 0 "register_operand" "")
2041 (match_operator 2 "nshift_operator"
2042 [(match_dup 0)
2043 (match_operand:QI 1 "register_operand" "")]))
2044 (clobber (match_operand:QI 3 "register_operand" ""))]
2045 "epilogue_completed
2046 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2047 [(set (cc0) (compare (match_dup 1) (const_int 0)))
2048 (set (pc)
2049 (if_then_else (le (cc0) (const_int 0))
2050 (label_ref (match_dup 5))
2051 (pc)))
2052 (match_dup 4)
2053 (parallel
2054 [(set (match_dup 0)
2055 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2056 (clobber (scratch:QI))])
2057 (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
2058 (set (cc0) (compare (match_dup 1) (const_int 0)))
2059 (set (pc)
2060 (if_then_else (ne (cc0) (const_int 0))
2061 (label_ref (match_dup 4))
2062 (pc)))
2063 (match_dup 5)]
2064 {
2065 operands[4] = gen_label_rtx ();
2066 operands[5] = gen_label_rtx ();
2067 })
2068
2069 (define_split
2070 [(set (match_operand 0 "register_operand" "")
2071 (match_operator 2 "nshift_operator"
2072 [(match_dup 0)
2073 (match_operand:QI 1 "register_operand" "")]))
2074 (clobber (match_operand:QI 3 "register_operand" ""))]
2075 "epilogue_completed
2076 && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
2077 [(set (match_dup 3)
2078 (match_dup 1))
2079 (set (cc0) (compare (match_dup 3) (const_int 0)))
2080 (set (pc)
2081 (if_then_else (le (cc0) (const_int 0))
2082 (label_ref (match_dup 5))
2083 (pc)))
2084 (match_dup 4)
2085 (parallel
2086 [(set (match_dup 0)
2087 (match_op_dup 2 [(match_dup 0) (const_int 1)]))
2088 (clobber (scratch:QI))])
2089 (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
2090 (set (cc0) (compare (match_dup 3) (const_int 0)))
2091 (set (pc)
2092 (if_then_else (ne (cc0) (const_int 0))
2093 (label_ref (match_dup 4))
2094 (pc)))
2095 (match_dup 5)]
2096 {
2097 operands[4] = gen_label_rtx ();
2098 operands[5] = gen_label_rtx ();
2099 })
2100 \f
2101 ;; ----------------------------------------------------------------------
2102 ;; ROTATIONS
2103 ;; ----------------------------------------------------------------------
2104
2105 (define_expand "rotl<mode>3"
2106 [(set (match_operand:QHSI 0 "register_operand" "")
2107 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "")
2108 (match_operand:QI 2 "nonmemory_operand" "")))]
2109 ""
2110 {
2111 if (expand_a_rotate (operands))
2112 DONE;
2113 })
2114
2115 (define_insn "rotl<mode>3_1"
2116 [(set (match_operand:QHSI 0 "register_operand" "=r")
2117 (rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
2118 (match_operand:QI 2 "immediate_operand" "")))]
2119 ""
2120 {
2121 return output_a_rotate (ROTATE, operands);
2122 }
2123 [(set (attr "length")
2124 (symbol_ref "compute_a_rotate_length (operands)"))])
2125 \f
2126 ;; -----------------------------------------------------------------
2127 ;; BIT FIELDS
2128 ;; -----------------------------------------------------------------
2129 ;; The H8/300 has given 1/8th of its opcode space to bitfield
2130 ;; instructions so let's use them as well as we can.
2131
2132 ;; You'll never believe all these patterns perform one basic action --
2133 ;; load a bit from the source, optionally invert the bit, then store it
2134 ;; in the destination (which is known to be zero).
2135 ;;
2136 ;; Combine obviously need some work to better identify this situation and
2137 ;; canonicalize the form better.
2138
2139 ;;
2140 ;; Inverted loads with a 16bit destination.
2141 ;;
2142
2143 (define_insn ""
2144 [(set (match_operand:HI 0 "register_operand" "=&r")
2145 (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
2146 (match_operand:HI 3 "const_int_operand" "n"))
2147 (const_int 1)
2148 (match_operand:HI 2 "const_int_operand" "n")))]
2149 "(TARGET_H8300SX)
2150 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2151 "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0"
2152 [(set_attr "length" "8")])
2153
2154 ;;
2155 ;; Normal loads with a 32bit destination.
2156 ;;
2157
2158 (define_insn "*extzv_1_r_h8300hs"
2159 [(set (match_operand:SI 0 "register_operand" "=r,r")
2160 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2161 (const_int 1)
2162 (match_operand 2 "const_int_operand" "n,n")))]
2163 "INTVAL (operands[2]) < 16"
2164 {
2165 return output_simode_bld (0, operands);
2166 }
2167 [(set_attr "cc" "set_znv,set_znv")
2168 (set_attr "length" "8,6")])
2169
2170 ;;
2171 ;; Inverted loads with a 32bit destination.
2172 ;;
2173
2174 (define_insn "*extzv_1_r_inv_h8300hs"
2175 [(set (match_operand:SI 0 "register_operand" "=r,r")
2176 (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
2177 (match_operand 3 "const_int_operand" "n,n"))
2178 (const_int 1)
2179 (match_operand 2 "const_int_operand" "n,n")))]
2180 "INTVAL (operands[2]) < 16
2181 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
2182 {
2183 return output_simode_bld (1, operands);
2184 }
2185 [(set_attr "cc" "set_znv,set_znv")
2186 (set_attr "length" "8,6")])
2187
2188 (define_expand "insv"
2189 [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
2190 (match_operand:HI 1 "general_operand" "")
2191 (match_operand:HI 2 "general_operand" ""))
2192 (match_operand:HI 3 "general_operand" ""))]
2193 "TARGET_H8300SX"
2194 {
2195 if (GET_CODE (operands[1]) == CONST_INT
2196 && GET_CODE (operands[2]) == CONST_INT
2197 && INTVAL (operands[1]) <= 8
2198 && INTVAL (operands[2]) >= 0
2199 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
2200 && memory_operand (operands[0], GET_MODE (operands[0])))
2201 {
2202 /* If the source operand is zero, it's better to use AND rather
2203 than BFST. Likewise OR if the operand is all ones. */
2204 if (GET_CODE (operands[3]) == CONST_INT)
2205 {
2206 HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
2207 if ((INTVAL (operands[3]) & mask) == 0)
2208 FAIL;
2209 if ((INTVAL (operands[3]) & mask) == mask)
2210 FAIL;
2211 }
2212 if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
2213 {
2214 if (!can_create_pseudo_p ())
2215 FAIL;
2216 operands[0] = replace_equiv_address (operands[0], force_reg (Pmode,
2217 XEXP (operands[0], 0)));
2218 }
2219 operands[3] = gen_lowpart (QImode, operands[3]);
2220 if (! operands[3])
2221 FAIL;
2222 if (! register_operand (operands[3], QImode))
2223 {
2224 if (!can_create_pseudo_p ())
2225 FAIL;
2226 operands[3] = force_reg (QImode, operands[3]);
2227 }
2228 emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
2229 operands[3], operands[1], operands[2]));
2230 DONE;
2231 }
2232 FAIL;
2233 })
2234
2235 (define_insn ""
2236 [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
2237 (const_int 1)
2238 (match_operand:HI 1 "immediate_operand" "n"))
2239 (match_operand:HI 2 "register_operand" "r"))]
2240 ""
2241 "bld #0,%R2\;bst %Z1,%Y0 ; i1"
2242 [(set_attr "length" "4")])
2243
2244 (define_expand "extzv"
2245 [(set (match_operand:HI 0 "register_operand" "")
2246 (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
2247 (match_operand:HI 2 "general_operand" "")
2248 (match_operand:HI 3 "general_operand" "")))]
2249 "TARGET_H8300SX"
2250 {
2251 if (GET_CODE (operands[2]) == CONST_INT
2252 && GET_CODE (operands[3]) == CONST_INT
2253 && INTVAL (operands[2]) <= 8
2254 && INTVAL (operands[3]) >= 0
2255 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
2256 && memory_operand (operands[1], QImode))
2257 {
2258 rtx temp;
2259
2260 /* Optimize the case where we're extracting into a paradoxical
2261 subreg. It's only necessary to extend to the inner reg. */
2262 if (GET_CODE (operands[0]) == SUBREG
2263 && subreg_lowpart_p (operands[0])
2264 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
2265 < GET_MODE_SIZE (GET_MODE (operands[0])))
2266 && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
2267 == MODE_INT))
2268 operands[0] = SUBREG_REG (operands[0]);
2269
2270 if (!can_create_pseudo_p ())
2271 temp = gen_lowpart (QImode, operands[0]);
2272 else
2273 temp = gen_reg_rtx (QImode);
2274 if (! temp)
2275 FAIL;
2276 if (! bit_memory_operand (operands[1], QImode))
2277 {
2278 if (!can_create_pseudo_p ())
2279 FAIL;
2280 operands[1] = replace_equiv_address (operands[1],
2281 force_reg (Pmode, XEXP (operands[1], 0)));
2282 }
2283 emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
2284 convert_move (operands[0], temp, 1);
2285 DONE;
2286 }
2287 FAIL;
2288 })
2289
2290 ;; BAND, BOR, and BXOR patterns
2291
2292 (define_insn ""
2293 [(set (match_operand:HI 0 "bit_operand" "=Ur")
2294 (match_operator:HI 4 "bit_operator"
2295 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2296 (const_int 1)
2297 (match_operand:HI 2 "immediate_operand" "n"))
2298 (match_operand:HI 3 "bit_operand" "0")]))]
2299 ""
2300 "bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1"
2301 [(set_attr "length" "6")])
2302
2303 (define_insn ""
2304 [(set (match_operand:HI 0 "bit_operand" "=Ur")
2305 (match_operator:HI 5 "bit_operator"
2306 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
2307 (const_int 1)
2308 (match_operand:HI 2 "immediate_operand" "n"))
2309 (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
2310 (const_int 1)
2311 (match_operand:HI 4 "immediate_operand" "n"))]))]
2312 ""
2313 "bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3"
2314 [(set_attr "length" "6")])
2315
2316 (define_insn "bfld"
2317 [(set (match_operand:QI 0 "register_operand" "=r")
2318 (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
2319 (match_operand:QI 2 "immediate_operand" "n")
2320 (match_operand:QI 3 "immediate_operand" "n")))]
2321 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
2322 {
2323 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
2324 - (1 << INTVAL (operands[3])));
2325 return "bfld %2,%1,%R0";
2326 }
2327 [(set_attr "cc" "none_0hit")
2328 (set_attr "length_table" "bitfield")])
2329
2330 (define_insn "bfst"
2331 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
2332 (match_operand:QI 2 "immediate_operand" "n")
2333 (match_operand:QI 3 "immediate_operand" "n"))
2334 (match_operand:QI 1 "register_operand" "r"))]
2335 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
2336 {
2337 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
2338 - (1 << INTVAL (operands[3])));
2339 return "bfst %R1,%2,%0";
2340 }
2341 [(set_attr "cc" "none_0hit")
2342 (set_attr "length_table" "bitfield")])
2343
2344 (define_expand "cstoreqi4"
2345 [(use (match_operator 1 "eqne_operator"
2346 [(match_operand:QI 2 "h8300_dst_operand" "")
2347 (match_operand:QI 3 "h8300_src_operand" "")]))
2348 (clobber (match_operand:HI 0 "register_operand"))]
2349 "TARGET_H8300SX"
2350 {
2351 h8300_expand_store (operands);
2352 DONE;
2353 })
2354
2355 (define_expand "cstorehi4"
2356 [(use (match_operator 1 "eqne_operator"
2357 [(match_operand:HI 2 "h8300_dst_operand" "")
2358 (match_operand:HI 3 "h8300_src_operand" "")]))
2359 (clobber (match_operand:HI 0 "register_operand"))]
2360 "TARGET_H8300SX"
2361 {
2362 h8300_expand_store (operands);
2363 DONE;
2364 })
2365
2366 (define_expand "cstoresi4"
2367 [(use (match_operator 1 "eqne_operator"
2368 [(match_operand:SI 2 "h8300_dst_operand" "")
2369 (match_operand:SI 3 "h8300_src_operand" "")]))
2370 (clobber (match_operand:HI 0 "register_operand"))]
2371 "TARGET_H8300SX"
2372 {
2373 h8300_expand_store (operands);
2374 DONE;
2375 })
2376
2377 (define_insn "*bstzhireg"
2378 [(set (match_operand:HI 0 "register_operand" "=r")
2379 (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
2380 "TARGET_H8300SX"
2381 "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
2382 [(set_attr "cc" "clobber")])
2383
2384 (define_insn_and_split "*cmpstz"
2385 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
2386 (const_int 1)
2387 (match_operand:QI 1 "immediate_operand" "n,n"))
2388 (match_operator:QI 2 "eqne_operator"
2389 [(match_operand 3 "h8300_dst_operand" "r,rQ")
2390 (match_operand 4 "h8300_src_operand" "I,rQi")]))]
2391 "TARGET_H8300SX
2392 && (GET_MODE (operands[3]) == GET_MODE (operands[4])
2393 || GET_CODE (operands[4]) == CONST_INT)
2394 && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
2395 && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
2396 "#"
2397 "reload_completed"
2398 [(set (cc0) (match_dup 5))
2399 (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
2400 (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
2401 {
2402 operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
2403 }
2404 [(set_attr "cc" "set_znv,compare")])
2405
2406 (define_insn "*bstz"
2407 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
2408 (const_int 1)
2409 (match_operand:QI 1 "immediate_operand" "n"))
2410 (eq:QI (cc0) (const_int 0)))]
2411 "TARGET_H8300SX && reload_completed"
2412 "bstz %1,%0"
2413 [(set_attr "cc" "none_0hit")
2414 (set_attr "length_table" "unary")])
2415
2416 (define_insn "*bistz"
2417 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
2418 (const_int 1)
2419 (match_operand:QI 1 "immediate_operand" "n"))
2420 (ne:QI (cc0) (const_int 0)))]
2421 "TARGET_H8300SX && reload_completed"
2422 "bistz %1,%0"
2423 [(set_attr "cc" "none_0hit")
2424 (set_attr "length_table" "unary")])
2425
2426 (define_insn_and_split "*cmpcondbset"
2427 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
2428 (if_then_else:QI (match_operator 1 "eqne_operator"
2429 [(match_operand 2 "h8300_dst_operand" "r,rQ")
2430 (match_operand 3 "h8300_src_operand" "I,rQi")])
2431 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
2432 (match_operand:QI 5 "single_one_operand" "n,n"))
2433 (match_dup 4)))]
2434 "TARGET_H8300SX"
2435 "#"
2436 "reload_completed"
2437 [(set (cc0) (match_dup 6))
2438 (set (match_dup 0)
2439 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
2440 (ior:QI (match_dup 4) (match_dup 5))
2441 (match_dup 4)))]
2442 {
2443 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
2444 }
2445 [(set_attr "cc" "set_znv,compare")])
2446
2447 (define_insn "*condbset"
2448 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
2449 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
2450 [(cc0) (const_int 0)])
2451 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
2452 (match_operand:QI 1 "single_one_operand" "n"))
2453 (match_dup 3)))]
2454 "TARGET_H8300SX && reload_completed"
2455 "bset/%j2\t%V1,%0"
2456 [(set_attr "cc" "none_0hit")
2457 (set_attr "length_table" "logicb")])
2458
2459 (define_insn_and_split "*cmpcondbclr"
2460 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
2461 (if_then_else:QI (match_operator 1 "eqne_operator"
2462 [(match_operand 2 "h8300_dst_operand" "r,rQ")
2463 (match_operand 3 "h8300_src_operand" "I,rQi")])
2464 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
2465 (match_operand:QI 5 "single_zero_operand" "n,n"))
2466 (match_dup 4)))]
2467 "TARGET_H8300SX"
2468 "#"
2469 "reload_completed"
2470 [(set (cc0) (match_dup 6))
2471 (set (match_dup 0)
2472 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
2473 (and:QI (match_dup 4) (match_dup 5))
2474 (match_dup 4)))]
2475 {
2476 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
2477 }
2478 [(set_attr "cc" "set_znv,compare")])
2479
2480 (define_insn "*condbclr"
2481 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
2482 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
2483 [(cc0) (const_int 0)])
2484 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
2485 (match_operand:QI 1 "single_zero_operand" "n"))
2486 (match_dup 3)))]
2487 "TARGET_H8300SX && reload_completed"
2488 "bclr/%j2\t%W1,%0"
2489 [(set_attr "cc" "none_0hit")
2490 (set_attr "length_table" "logicb")])
2491
2492 (define_insn_and_split "*cmpcondbsetreg"
2493 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
2494 (if_then_else:QI (match_operator 1 "eqne_operator"
2495 [(match_operand 2 "h8300_dst_operand" "r,rQ")
2496 (match_operand 3 "h8300_src_operand" "I,rQi")])
2497 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
2498 (ashift:QI (const_int 1)
2499 (match_operand:QI 5 "register_operand" "r,r")))
2500 (match_dup 4)))]
2501 "TARGET_H8300SX"
2502 "#"
2503 "reload_completed"
2504 [(set (cc0) (match_dup 6))
2505 (set (match_dup 0)
2506 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
2507 (ior:QI (match_dup 4)
2508 (ashift:QI (const_int 1)
2509 (match_operand:QI 5 "register_operand" "r,r")))
2510 (match_dup 4)))]
2511 {
2512 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
2513 }
2514 [(set_attr "cc" "set_znv,compare")])
2515
2516 (define_insn "*condbsetreg"
2517 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
2518 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
2519 [(cc0) (const_int 0)])
2520 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
2521 (ashift:QI (const_int 1)
2522 (match_operand:QI 1 "register_operand" "r")))
2523 (match_dup 3)))]
2524 "TARGET_H8300SX && reload_completed"
2525 "bset/%j2\t%R1,%0"
2526 [(set_attr "cc" "none_0hit")
2527 (set_attr "length_table" "logicb")])
2528
2529 (define_insn_and_split "*cmpcondbclrreg"
2530 [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
2531 (if_then_else:QI (match_operator 1 "eqne_operator"
2532 [(match_operand 2 "h8300_dst_operand" "r,rQ")
2533 (match_operand 3 "h8300_src_operand" "I,rQi")])
2534 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
2535 (ashift:QI (const_int 1)
2536 (match_operand:QI 5 "register_operand" "r,r")))
2537 (match_dup 4)))]
2538 "TARGET_H8300SX"
2539 "#"
2540 "reload_completed"
2541 [(set (cc0) (match_dup 6))
2542 (set (match_dup 0)
2543 (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
2544 (and:QI (match_dup 4)
2545 (ashift:QI (const_int 1)
2546 (match_operand:QI 5 "register_operand" "r,r")))
2547 (match_dup 4)))]
2548 {
2549 operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
2550 }
2551 [(set_attr "cc" "set_znv,compare")])
2552
2553 (define_insn "*condbclrreg"
2554 [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
2555 (if_then_else:QI (match_operator:QI 2 "eqne_operator"
2556 [(cc0) (const_int 0)])
2557 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
2558 (ashift:QI (const_int 1)
2559 (match_operand:QI 1 "register_operand" "r")))
2560 (match_dup 3)))]
2561 "TARGET_H8300SX && reload_completed"
2562 "bclr/%j2\t%R1,%0"
2563 [(set_attr "cc" "none_0hit")
2564 (set_attr "length_table" "logicb")])
2565
2566 \f
2567 ;; -----------------------------------------------------------------
2568 ;; COMBINE PATTERNS
2569 ;; -----------------------------------------------------------------
2570
2571 ;; insv:SI
2572
2573 (define_insn "*insv_si_1_n"
2574 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2575 (const_int 1)
2576 (match_operand:SI 1 "const_int_operand" "n"))
2577 (match_operand:SI 2 "register_operand" "r"))]
2578 "INTVAL (operands[1]) < 16"
2579 "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
2580 [(set_attr "length" "4")])
2581
2582 (define_insn "*insv_si_1_n_lshiftrt"
2583 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2584 (const_int 1)
2585 (match_operand:SI 1 "const_int_operand" "n"))
2586 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2587 (match_operand:SI 3 "const_int_operand" "n")))]
2588 "INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16"
2589 "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
2590 [(set_attr "length" "4")])
2591
2592 (define_insn "*insv_si_1_n_lshiftrt_16"
2593 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2594 (const_int 1)
2595 (match_operand:SI 1 "const_int_operand" "n"))
2596 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2597 (const_int 16)))]
2598 "INTVAL (operands[1]) < 16"
2599 "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
2600 [(set_attr "length" "6")])
2601
2602 (define_insn "*insv_si_8_8"
2603 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2604 (const_int 8)
2605 (const_int 8))
2606 (match_operand:SI 1 "register_operand" "r"))]
2607 ""
2608 "mov.b\\t%w1,%x0"
2609 [(set_attr "length" "2")])
2610
2611 (define_insn "*insv_si_8_8_lshiftrt_8"
2612 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
2613 (const_int 8)
2614 (const_int 8))
2615 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2616 (const_int 8)))]
2617 ""
2618 "mov.b\\t%x1,%x0"
2619 [(set_attr "length" "2")])
2620
2621 ;; extzv:SI
2622
2623 (define_insn "*extzv_8_8"
2624 [(set (match_operand:SI 0 "register_operand" "=r,r")
2625 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
2626 (const_int 8)
2627 (const_int 8)))]
2628 ""
2629 "@
2630 mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
2631 sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
2632 [(set_attr "cc" "set_znv,clobber")
2633 (set_attr "length" "6,4")])
2634
2635 (define_insn "*extzv_8_16"
2636 [(set (match_operand:SI 0 "register_operand" "=r")
2637 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2638 (const_int 8)
2639 (const_int 16)))]
2640 ""
2641 "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
2642 [(set_attr "cc" "set_znv")
2643 (set_attr "length" "6")])
2644
2645 (define_insn "*extzv_16_8"
2646 [(set (match_operand:SI 0 "register_operand" "=r")
2647 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
2648 (const_int 16)
2649 (const_int 8)))
2650 (clobber (match_scratch:SI 2 "=&r"))]
2651 "TARGET_H8300H"
2652 "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
2653 [(set_attr "length" "8")
2654 (set_attr "cc" "set_znv")])
2655
2656 ;; Extract the exponent of a float.
2657
2658 (define_insn_and_split "*extzv_8_23"
2659 [(set (match_operand:SI 0 "register_operand" "=r")
2660 (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
2661 (const_int 8)
2662 (const_int 23)))]
2663 ""
2664 "#"
2665 "&& reload_completed"
2666 [(parallel [(set (match_dup 0)
2667 (ashift:SI (match_dup 0)
2668 (const_int 1)))
2669 (clobber (scratch:QI))])
2670 (parallel [(set (match_dup 0)
2671 (lshiftrt:SI (match_dup 0)
2672 (const_int 24)))
2673 (clobber (scratch:QI))])]
2674 "")
2675
2676 ;; and:SI
2677
2678 ;; ((SImode) HImode) << 15
2679
2680 (define_insn_and_split "*twoshifts_l16_r1"
2681 [(set (match_operand:SI 0 "register_operand" "=r")
2682 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2683 (const_int 15))
2684 (const_int 2147450880)))]
2685 ""
2686 "#"
2687 "&& reload_completed"
2688 [(parallel [(set (match_dup 0)
2689 (ashift:SI (match_dup 0)
2690 (const_int 16)))
2691 (clobber (scratch:QI))])
2692 (parallel [(set (match_dup 0)
2693 (lshiftrt:SI (match_dup 0)
2694 (const_int 1)))
2695 (clobber (scratch:QI))])]
2696 "")
2697
2698 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
2699
2700 (define_insn_and_split "*andsi3_ashift_n_lower"
2701 [(set (match_operand:SI 0 "register_operand" "=r,r")
2702 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
2703 (match_operand:QI 2 "const_int_operand" "S,n"))
2704 (match_operand:SI 3 "const_int_operand" "n,n")))
2705 (clobber (match_scratch:QI 4 "=X,&r"))]
2706 "INTVAL (operands[2]) <= 15
2707 && UINTVAL (operands[3]) == ((HOST_WIDE_INT_M1U << INTVAL (operands[2]))
2708 & 0xffff)"
2709 "#"
2710 "&& reload_completed"
2711 [(parallel [(set (match_dup 5)
2712 (ashift:HI (match_dup 5)
2713 (match_dup 2)))
2714 (clobber (match_dup 4))])
2715 (set (match_dup 0)
2716 (zero_extend:SI (match_dup 5)))]
2717 {
2718 operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
2719 })
2720
2721 ;; Accept (A >> 30) & 2 and the like.
2722
2723 (define_insn "*andsi3_lshiftrt_n_sb"
2724 [(set (match_operand:SI 0 "register_operand" "=r")
2725 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
2726 (match_operand:SI 2 "const_int_operand" "n"))
2727 (match_operand:SI 3 "single_one_operand" "n")))]
2728 "exact_log2 (INTVAL (operands[3])) < 16
2729 && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
2730 {
2731 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
2732 return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
2733 }
2734 [(set_attr "length" "8")])
2735
2736 (define_insn_and_split "*andsi3_lshiftrt_9_sb"
2737 [(set (match_operand:SI 0 "register_operand" "=r")
2738 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
2739 (const_int 9))
2740 (const_int 4194304)))]
2741 ""
2742 "#"
2743 "&& reload_completed"
2744 [(set (match_dup 0)
2745 (and:SI (lshiftrt:SI (match_dup 0)
2746 (const_int 25))
2747 (const_int 64)))
2748 (parallel [(set (match_dup 0)
2749 (ashift:SI (match_dup 0)
2750 (const_int 16)))
2751 (clobber (scratch:QI))])]
2752 "")
2753
2754 ;; plus:SI
2755
2756 (define_insn "*addsi3_upper"
2757 [(set (match_operand:SI 0 "register_operand" "=r")
2758 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2759 (const_int 65536))
2760 (match_operand:SI 2 "register_operand" "0")))]
2761 ""
2762 "add.w\\t%f1,%e0"
2763 [(set_attr "length" "2")])
2764
2765 (define_insn "*addsi3_lshiftrt_16_zexthi"
2766 [(set (match_operand:SI 0 "register_operand" "=r")
2767 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2768 (const_int 16))
2769 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
2770 ""
2771 "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
2772 [(set_attr "length" "6")])
2773
2774 (define_insn_and_split "*addsi3_and_r_1"
2775 [(set (match_operand:SI 0 "register_operand" "=r")
2776 (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
2777 (const_int 1))
2778 (match_operand:SI 2 "register_operand" "0")))]
2779 ""
2780 "#"
2781 "&& reload_completed"
2782 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
2783 (const_int 1)
2784 (const_int 0))
2785 (const_int 0)))
2786 (set (pc)
2787 (if_then_else (eq (cc0)
2788 (const_int 0))
2789 (label_ref (match_dup 3))
2790 (pc)))
2791 (set (match_dup 2)
2792 (plus:SI (match_dup 2)
2793 (const_int 1)))
2794 (match_dup 3)]
2795 {
2796 operands[3] = gen_label_rtx ();
2797 })
2798
2799 (define_insn_and_split "*addsi3_and_not_r_1"
2800 [(set (match_operand:SI 0 "register_operand" "=r")
2801 (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2802 (const_int 1))
2803 (match_operand:SI 2 "register_operand" "0")))]
2804 ""
2805 "#"
2806 "&& reload_completed"
2807 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
2808 (const_int 1)
2809 (const_int 0))
2810 (const_int 0)))
2811 (set (pc)
2812 (if_then_else (ne (cc0)
2813 (const_int 0))
2814 (label_ref (match_dup 3))
2815 (pc)))
2816 (set (match_dup 2)
2817 (plus:SI (match_dup 2)
2818 (const_int 1)))
2819 (match_dup 3)]
2820 {
2821 operands[3] = gen_label_rtx ();
2822 })
2823
2824 ;; [ix]or:HI
2825
2826 (define_insn "*ixorhi3_zext"
2827 [(set (match_operand:HI 0 "register_operand" "=r")
2828 (match_operator:HI 1 "iorxor_operator"
2829 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
2830 (match_operand:HI 3 "register_operand" "0")]))]
2831 ""
2832 "%c1.b\\t%X2,%s0"
2833 [(set_attr "length" "2")])
2834
2835 ;; [ix]or:SI
2836
2837 (define_insn "*ixorsi3_zext_qi"
2838 [(set (match_operand:SI 0 "register_operand" "=r")
2839 (match_operator:SI 1 "iorxor_operator"
2840 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
2841 (match_operand:SI 3 "register_operand" "0")]))]
2842 ""
2843 "%c1.b\\t%X2,%w0"
2844 [(set_attr "length" "2")])
2845
2846 (define_insn "*ixorsi3_zext_hi"
2847 [(set (match_operand:SI 0 "register_operand" "=r")
2848 (match_operator:SI 1 "iorxor_operator"
2849 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
2850 (match_operand:SI 3 "register_operand" "0")]))]
2851 ""
2852 "%c1.w\\t%T2,%f0"
2853 [(set_attr "length" "2")])
2854
2855 (define_insn "*ixorsi3_ashift_16"
2856 [(set (match_operand:SI 0 "register_operand" "=r")
2857 (match_operator:SI 1 "iorxor_operator"
2858 [(ashift:SI (match_operand:SI 2 "register_operand" "r")
2859 (const_int 16))
2860 (match_operand:SI 3 "register_operand" "0")]))]
2861 ""
2862 "%c1.w\\t%f2,%e0"
2863 [(set_attr "length" "2")])
2864
2865 (define_insn "*ixorsi3_lshiftrt_16"
2866 [(set (match_operand:SI 0 "register_operand" "=r")
2867 (match_operator:SI 1 "iorxor_operator"
2868 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2869 (const_int 16))
2870 (match_operand:SI 3 "register_operand" "0")]))]
2871 ""
2872 "%c1.w\\t%e2,%f0"
2873 [(set_attr "length" "2")])
2874
2875 ;; ior:HI
2876
2877 (define_insn "*iorhi3_ashift_8"
2878 [(set (match_operand:HI 0 "register_operand" "=r")
2879 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
2880 (const_int 8))
2881 (match_operand:HI 2 "register_operand" "0")))]
2882 ""
2883 "or.b\\t%s1,%t0"
2884 [(set_attr "length" "2")])
2885
2886 (define_insn "*iorhi3_lshiftrt_8"
2887 [(set (match_operand:HI 0 "register_operand" "=r")
2888 (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
2889 (const_int 8))
2890 (match_operand:HI 2 "register_operand" "0")))]
2891 ""
2892 "or.b\\t%t1,%s0"
2893 [(set_attr "length" "2")])
2894
2895 (define_insn "*iorhi3_two_qi"
2896 [(set (match_operand:HI 0 "register_operand" "=r")
2897 (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
2898 (ashift:HI (match_operand:HI 2 "register_operand" "r")
2899 (const_int 8))))]
2900 ""
2901 "mov.b\\t%s2,%t0"
2902 [(set_attr "length" "2")])
2903
2904 (define_insn "*iorhi3_two_qi_mem"
2905 [(set (match_operand:HI 0 "register_operand" "=&r")
2906 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
2907 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
2908 (const_int 8))))]
2909 ""
2910 "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
2911 [(set_attr "length" "16")])
2912
2913 (define_split
2914 [(set (match_operand:HI 0 "register_operand" "")
2915 (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
2916 (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
2917 (const_int 8))))]
2918 "reload_completed
2919 && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
2920 [(set (match_dup 0)
2921 (match_dup 3))]
2922 {
2923 operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
2924 })
2925
2926 ;; ior:SI
2927
2928 (define_insn "*iorsi3_two_hi"
2929 [(set (match_operand:SI 0 "register_operand" "=r")
2930 (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
2931 (ashift:SI (match_operand:SI 2 "register_operand" "r")
2932 (const_int 16))))]
2933 ""
2934 "mov.w\\t%f2,%e0"
2935 [(set_attr "length" "2")])
2936
2937 (define_insn_and_split "*iorsi3_two_qi_zext"
2938 [(set (match_operand:SI 0 "register_operand" "=&r")
2939 (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
2940 (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
2941 (const_int 8))
2942 (const_int 65280))))]
2943 ""
2944 "#"
2945 "&& reload_completed"
2946 [(set (match_dup 3)
2947 (ior:HI (zero_extend:HI (match_dup 1))
2948 (ashift:HI (subreg:HI (match_dup 2) 0)
2949 (const_int 8))))
2950 (set (match_dup 0)
2951 (zero_extend:SI (match_dup 3)))]
2952 {
2953 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
2954 })
2955
2956 (define_insn "*iorsi3_e2f"
2957 [(set (match_operand:SI 0 "register_operand" "=r")
2958 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
2959 (const_int -65536))
2960 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2961 (const_int 16))))]
2962 ""
2963 "mov.w\\t%e2,%f0"
2964 [(set_attr "length" "2")])
2965
2966 (define_insn_and_split "*iorsi3_two_qi_sext"
2967 [(set (match_operand:SI 0 "register_operand" "=r")
2968 (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
2969 (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
2970 (const_int 8))))]
2971 ""
2972 "#"
2973 "&& reload_completed"
2974 [(set (match_dup 3)
2975 (ior:HI (zero_extend:HI (match_dup 1))
2976 (ashift:HI (match_dup 4)
2977 (const_int 8))))
2978 (set (match_dup 0)
2979 (sign_extend:SI (match_dup 3)))]
2980 {
2981 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
2982 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
2983 })
2984
2985 (define_insn "*iorsi3_w"
2986 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2987 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
2988 (const_int -256))
2989 (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
2990 ""
2991 "mov.b\\t%X2,%w0"
2992 [(set_attr "length" "2,8")])
2993
2994 (define_insn "*iorsi3_ashift_31"
2995 [(set (match_operand:SI 0 "register_operand" "=&r")
2996 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2997 (const_int 31))
2998 (match_operand:SI 2 "register_operand" "0")))]
2999 ""
3000 "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
3001 [(set_attr "length" "6")
3002 (set_attr "cc" "set_znv")])
3003
3004 (define_insn "*iorsi3_and_ashift"
3005 [(set (match_operand:SI 0 "register_operand" "=r")
3006 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3007 (match_operand:SI 2 "const_int_operand" "n"))
3008 (match_operand:SI 3 "single_one_operand" "n"))
3009 (match_operand:SI 4 "register_operand" "0")))]
3010 "(INTVAL (operands[3]) & ~0xffff) == 0"
3011 {
3012 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3013 - INTVAL (operands[2]));
3014 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3015 operands[2] = srcpos;
3016 operands[3] = dstpos;
3017 return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3018 }
3019 [(set_attr "length" "6")])
3020
3021 (define_insn "*iorsi3_and_lshiftrt"
3022 [(set (match_operand:SI 0 "register_operand" "=r")
3023 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3024 (match_operand:SI 2 "const_int_operand" "n"))
3025 (match_operand:SI 3 "single_one_operand" "n"))
3026 (match_operand:SI 4 "register_operand" "0")))]
3027 "((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
3028 {
3029 rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
3030 + INTVAL (operands[2]));
3031 rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
3032 operands[2] = srcpos;
3033 operands[3] = dstpos;
3034 return "bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0";
3035 }
3036 [(set_attr "length" "6")])
3037
3038 (define_insn "*iorsi3_zero_extract"
3039 [(set (match_operand:SI 0 "register_operand" "=r")
3040 (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3041 (const_int 1)
3042 (match_operand:SI 2 "const_int_operand" "n"))
3043 (match_operand:SI 3 "register_operand" "0")))]
3044 "INTVAL (operands[2]) < 16"
3045 "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
3046 [(set_attr "length" "6")])
3047
3048 (define_insn "*iorsi3_and_lshiftrt_n_sb"
3049 [(set (match_operand:SI 0 "register_operand" "=r")
3050 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3051 (const_int 30))
3052 (const_int 2))
3053 (match_operand:SI 2 "register_operand" "0")))]
3054 ""
3055 "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
3056 [(set_attr "length" "8")])
3057
3058 (define_insn "*iorsi3_and_lshiftrt_9_sb"
3059 [(set (match_operand:SI 0 "register_operand" "=r")
3060 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3061 (const_int 9))
3062 (const_int 4194304))
3063 (match_operand:SI 2 "register_operand" "0")))
3064 (clobber (match_scratch:HI 3 "=&r"))]
3065 ""
3066 {
3067 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3068 return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3069 else
3070 return "rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
3071 }
3072 [(set_attr "length" "10")])
3073
3074 ;; Used to OR the exponent of a float.
3075
3076 (define_insn "*iorsi3_shift"
3077 [(set (match_operand:SI 0 "register_operand" "=r")
3078 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3079 (const_int 23))
3080 (match_operand:SI 2 "register_operand" "0")))
3081 (clobber (match_scratch:SI 3 "=&r"))]
3082 ""
3083 "#")
3084
3085 (define_split
3086 [(set (match_operand:SI 0 "register_operand" "")
3087 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3088 (const_int 23))
3089 (match_dup 0)))
3090 (clobber (match_operand:SI 2 "register_operand" ""))]
3091 "epilogue_completed
3092 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3093 && REGNO (operands[0]) != REGNO (operands[1])"
3094 [(parallel [(set (match_dup 3)
3095 (ashift:HI (match_dup 3)
3096 (const_int 7)))
3097 (clobber (scratch:QI))])
3098 (set (match_dup 0)
3099 (ior:SI (ashift:SI (match_dup 1)
3100 (const_int 16))
3101 (match_dup 0)))]
3102 {
3103 operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
3104 })
3105
3106 (define_split
3107 [(set (match_operand:SI 0 "register_operand" "")
3108 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3109 (const_int 23))
3110 (match_dup 0)))
3111 (clobber (match_operand:SI 2 "register_operand" ""))]
3112 "epilogue_completed
3113 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3114 && REGNO (operands[0]) != REGNO (operands[1]))"
3115 [(set (match_dup 2)
3116 (match_dup 1))
3117 (parallel [(set (match_dup 3)
3118 (ashift:HI (match_dup 3)
3119 (const_int 7)))
3120 (clobber (scratch:QI))])
3121 (set (match_dup 0)
3122 (ior:SI (ashift:SI (match_dup 2)
3123 (const_int 16))
3124 (match_dup 0)))]
3125 {
3126 operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
3127 })
3128
3129 (define_insn "*iorsi2_and_1_lshiftrt_1"
3130 [(set (match_operand:SI 0 "register_operand" "=r")
3131 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
3132 (const_int 1))
3133 (lshiftrt:SI (match_dup 1)
3134 (const_int 1))))]
3135 ""
3136 "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
3137 [(set_attr "length" "6")])
3138
3139 (define_insn_and_split "*iorsi3_ashift_16_ashift_24"
3140 [(set (match_operand:SI 0 "register_operand" "=r")
3141 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3142 (const_int 16))
3143 (ashift:SI (match_operand:SI 2 "register_operand" "r")
3144 (const_int 24))))]
3145 ""
3146 "#"
3147 "&& reload_completed"
3148 [(set (match_dup 3)
3149 (ior:HI (ashift:HI (match_dup 4)
3150 (const_int 8))
3151 (match_dup 3)))
3152 (parallel [(set (match_dup 0)
3153 (ashift:SI (match_dup 0)
3154 (const_int 16)))
3155 (clobber (scratch:QI))])]
3156 {
3157 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3158 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
3159 })
3160
3161 (define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
3162 [(set (match_operand:SI 0 "register_operand" "=&r")
3163 (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
3164 (const_int 16))
3165 (const_int 16711680))
3166 (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
3167 (const_int 24))))]
3168 ""
3169 "#"
3170 "&& reload_completed"
3171 [(set (match_dup 3)
3172 (ior:HI (zero_extend:HI (match_dup 1))
3173 (ashift:HI (subreg:HI (match_dup 2) 0)
3174 (const_int 8))))
3175 (parallel [(set (match_dup 0)
3176 (ashift:SI (match_dup 0)
3177 (const_int 16)))
3178 (clobber (scratch:QI))])]
3179 {
3180 operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
3181 })
3182
3183 ;; Used to add the exponent of a float.
3184
3185 (define_insn "*addsi3_shift"
3186 [(set (match_operand:SI 0 "register_operand" "=r")
3187 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3188 (const_int 8388608))
3189 (match_operand:SI 2 "register_operand" "0")))
3190 (clobber (match_scratch:SI 3 "=&r"))]
3191 ""
3192 "#")
3193
3194 (define_split
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3197 (const_int 8388608))
3198 (match_dup 0)))
3199 (clobber (match_operand:SI 2 "register_operand" ""))]
3200 "epilogue_completed
3201 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3202 && REGNO (operands[0]) != REGNO (operands[1])"
3203 [(parallel [(set (match_dup 3)
3204 (ashift:HI (match_dup 3)
3205 (const_int 7)))
3206 (clobber (scratch:QI))])
3207 (set (match_dup 0)
3208 (plus:SI (mult:SI (match_dup 1)
3209 (const_int 65536))
3210 (match_dup 0)))]
3211 {
3212 operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
3213 })
3214
3215 (define_split
3216 [(set (match_operand:SI 0 "register_operand" "")
3217 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3218 (const_int 8388608))
3219 (match_dup 0)))
3220 (clobber (match_operand:SI 2 "register_operand" ""))]
3221 "epilogue_completed
3222 && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3223 && REGNO (operands[0]) != REGNO (operands[1]))"
3224 [(set (match_dup 2)
3225 (match_dup 1))
3226 (parallel [(set (match_dup 3)
3227 (ashift:HI (match_dup 3)
3228 (const_int 7)))
3229 (clobber (scratch:QI))])
3230 (set (match_dup 0)
3231 (plus:SI (mult:SI (match_dup 2)
3232 (const_int 65536))
3233 (match_dup 0)))]
3234 {
3235 operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
3236 })
3237
3238 ;; ashift:SI
3239
3240 (define_insn_and_split "*ashiftsi_sextqi_7"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
3243 (const_int 7)))]
3244 ""
3245 "#"
3246 "&& reload_completed"
3247 [(parallel [(set (match_dup 2)
3248 (ashift:HI (match_dup 2)
3249 (const_int 8)))
3250 (clobber (scratch:QI))])
3251 (set (match_dup 0)
3252 (sign_extend:SI (match_dup 2)))
3253 (parallel [(set (match_dup 0)
3254 (ashiftrt:SI (match_dup 0)
3255 (const_int 1)))
3256 (clobber (scratch:QI))])]
3257 {
3258 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
3259 })
3260
3261 ;; Storing a part of HImode to QImode.
3262
3263 (define_insn ""
3264 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3265 (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
3266 (const_int 8)) 1))]
3267 ""
3268 "mov.b\\t%t1,%R0"
3269 [(set_attr "cc" "set_znv")
3270 (set_attr "length" "8")])
3271
3272 ;; Storing a part of SImode to QImode.
3273
3274 (define_insn ""
3275 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3276 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3277 (const_int 8)) 3))]
3278 ""
3279 "mov.b\\t%x1,%R0"
3280 [(set_attr "cc" "set_znv")
3281 (set_attr "length" "8")])
3282
3283 (define_insn ""
3284 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3285 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3286 (const_int 16)) 3))
3287 (clobber (match_scratch:SI 2 "=&r"))]
3288 ""
3289 "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
3290 [(set_attr "cc" "set_znv")
3291 (set_attr "length" "10")])
3292
3293 (define_insn ""
3294 [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
3295 (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3296 (const_int 24)) 3))
3297 (clobber (match_scratch:SI 2 "=&r"))]
3298 ""
3299 "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
3300 [(set_attr "cc" "set_znv")
3301 (set_attr "length" "10")])
3302
3303 (define_insn_and_split ""
3304 [(set (pc)
3305 (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3306 (const_int 1)
3307 (const_int 7))
3308 (const_int 0))
3309 (label_ref (match_operand 1 "" ""))
3310 (pc)))]
3311 ""
3312 "#"
3313 ""
3314 [(set (cc0) (compare (match_dup 0)
3315 (const_int 0)))
3316 (set (pc)
3317 (if_then_else (ge (cc0)
3318 (const_int 0))
3319 (label_ref (match_dup 1))
3320 (pc)))]
3321 "")
3322
3323 (define_insn_and_split ""
3324 [(set (pc)
3325 (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
3326 (const_int 1)
3327 (const_int 7))
3328 (const_int 0))
3329 (label_ref (match_operand 1 "" ""))
3330 (pc)))]
3331 ""
3332 "#"
3333 ""
3334 [(set (cc0) (compare (match_dup 0)
3335 (const_int 0)))
3336 (set (pc)
3337 (if_then_else (lt (cc0)
3338 (const_int 0))
3339 (label_ref (match_dup 1))
3340 (pc)))]
3341 "")
3342 \f
3343 (include "peepholes.md")