2003-09-04 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / ip2k / ip2k.md
blobddd6fd20a7b8168f98207a7918cac1c8557598af
1 ;; -*- Mode: Scheme -*-
2 ;; GCC machine description for Ubicom IP2022 Communications Controller.
3 ;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 ;; Contributed by Red Hat, Inc and Ubicom, Inc.
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.  */
23 ;; Default all instruction lengths to two bytes (one 16-bit instruction).
25 (define_attr "length" "" (const_int 2))
27 ;; Define if we can "skip" an insn or not
28 (define_attr "skip" "no,yes" (const_string "no"))
30 ;; Define an insn clobbers WREG or not
31 (define_attr "clobberw" "no,yes" (const_string "yes"))
33 ;; Performance Issues:
35 ;; With the IP2k only having one really useful pointer register we have to
36 ;; make most of our instruction patterns only match one offsettable address
37 ;; before addressing becomes strict whereas afterwards of course we can use
38 ;; any register details that have become fixed.  As we've already committed
39 ;; any reloads at this point of course we're a little late so we have to use
40 ;; a number of peephole2 optimizations to remerge viable patterns.  We can
41 ;; do a bit more tidying up in the machine-dependent reorg pass to try and
42 ;; make things better still.  None of this is ideal, but it's *much* better
43 ;; than nothing.
45 ;; Constraints:
47 ;; I - -255..-1 - all other literal values have to be loaded
48 ;; J - 0..7 - valid bit number in a register
49 ;; K - 0..127 - valid offset for addressing mode
50 ;; L - 1..127 - positive count suitable for shift.
51 ;; M - -1 as a literal value
52 ;; N - +1 as a literal value
53 ;; O - zero
54 ;; P - 0..255
56 ;; a - DP or IP registers (general address)
57 ;; f - IP register
58 ;; j - IPL register
59 ;; k - IPH register
60 ;; b - DP register
61 ;; y - DPH register
62 ;; z - DPL register
63 ;; q - SP register
64 ;; c - DP or SP registers (offsettable address)
65 ;; d - non-pointer registers (not SP, DP, IP)
66 ;; u - non-SP registers (everything except SP)
68 ;; R - Indirect thru IP - Avoid this except for QI mode, since we
69 ;;     can't access extra bytes.
70 ;; S - Short (stack/dp address). Pointer with 0..127 displacement
71 ;;     Note that 0(SP) has undefined contents due to post-decrement push
72 ;; T - data-section immediate value.  A CONST_INT or SYMBOL_REF into .data
74 ;; Special assembly-language format effectors:
76 ;; ABCD -
77 ;;     Reference up to 4 big-endian registers - %A0 is Rn+0, while %D0 is Rn+3
78 ;; STUVWXYZ -
79 ;;     Reference up to 8 big-endian registers - %S0 is Rn+0, while %Z0 is Rn+7
81 ;; H - High part of 16 bit address or literal %hi8data(v) or %hi8insn(v)
82 ;; L - Low part of 16 bit address or literal  %lo8data(v) or %lo8insn(v)
83 ;; b - print a literal value with no punctuation (typically bit selector)
84 ;; e - print 1 << v ('exponent')
85 ;; n - print negative number
86 ;; x - print 16 bit hex number
87 ;; < - interior stack push; adjust any stack-relative operands accordingly
88 ;; > - interior stack pop; clear adjustment.
91 ;; Basic operations to move data in and out of fr's.  Also extended to
92 ;; cover the loading of w with immediates
95 (define_insn "*movqi_w_gen"
96   [(set (reg:QI 10)
97         (match_operand:QI 0 "general_operand" "rSi"))]
98   "(ip2k_reorg_split_qimode)"
99   "mov\\tw,%0"
100   [(set_attr "skip" "yes")])
102 (define_insn "*movqi_fr_w"
103   [(set (match_operand:QI 0 "nonimmediate_operand" "=rS")
104         (reg:QI 10))]
105   "(ip2k_reorg_split_qimode)"
106   "mov\\t%0,w"
107   [(set_attr "skip" "yes")
108    (set_attr "clobberw" "no")])
111 ;; Handle the cases where we get back to back redundant mov patterns issued.  
112 ;; This of course sounds somewhat absurd but is actually reasonably common
113 ;; because we aren't able to match certain patterns before registers are
114 ;; chosen.  This is particularly true of memory to memory operations where
115 ;; we can't provide patterns that will guarantee to match every time because
116 ;; this would require reloads in the middle of instructions.  If we
117 ;; discover a case that doesn't need a reload of course then this combiner
118 ;; operation will tidy up for us.
120 ;; Warning!  Whilst it would be nice to match operand 0 as a general operand
121 ;; we mustn't do so because this doesn't work with the REG_DEAD check.
123 (define_peephole2
124   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
125         (match_operand 1 "ip2k_gen_operand" ""))
126    (set (match_operand 2 "ip2k_split_dest_operand" "")
127         (match_dup 0))]
128   "(peep2_reg_dead_p (2, operands[0])
129     && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP)
130     && (REG_P (operands[2])
131         || ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
132                                      GET_MODE_SIZE (GET_MODE (operands[0])))))"
133   [(set (match_dup 2)
134         (match_dup 1))]
135   "")
137 (define_peephole2
138   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
139         (match_operand 1 "immediate_operand" ""))
140    (set (match_operand 2 "ip2k_gen_operand" "")
141         (match_dup 0))]
142   "(peep2_reg_dead_p (2, operands[0])
143     && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP)
144     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
145                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
146   [(set (match_dup 2)
147         (match_dup 1))]
148   "")
151 ;; Move 8-bit integers.
154 (define_expand "movqi"
155   [(set (match_operand:QI 0 "" "")
156         (match_operand:QI 1 "" ""))]
157   ""
158   "")
160 (define_insn "*pushqi"
161   [(set (match_operand:QI 0 "push_operand"   "=<")
162         (match_operand:QI 1 "general_operand" "g"))]
163   ""
164   "push\\t%1"
165   [(set_attr "skip" "yes")
166    (set_attr "clobberw" "no")])
168 ;; IP isn't offsettable but we can fake this behavior here and win if we would
169 ;; otherwise use DP and require a reload from IP.  This instruction is only
170 ;; matched by peephole2 operations.
172 (define_insn "*movqi_to_ip_plus_offs"
173   [(set (mem:QI (plus:HI (reg:HI 4)
174                          (match_operand 0 "const_int_operand" "P,P")))
175         (match_operand:QI 1 "general_operand"                 "O,g"))]
176   "reload_completed && (INTVAL (operands[0]) < 0x100)"
177   "*{
178     if (INTVAL (operands[0]) == 1)
179       OUT_AS1 (inc, ipl);
180     else
181       {
182         OUT_AS2 (mov, w, %0);
183         OUT_AS2 (add, ipl, w);
184       }
186     switch (which_alternative)
187       {
188       case 0:
189         OUT_AS1 (clr, (IP));
190         break;
192       case 1:
193         OUT_AS1 (push, %1%<);
194         OUT_AS1 (pop, (IP)%>);
195         break;
196       }
198     if (!find_regno_note (insn, REG_DEAD, REG_IP))
199       {
200         if (INTVAL (operands[0]) == 1)
201           OUT_AS1 (dec, ipl);
202         else
203           OUT_AS2 (sub, ipl, w);
204       }
205     return \"\";
206   }")
208 ;; IP isn't offsettable but we can fake this behavior here and win if we would
209 ;; otherwise use DP and require a reload from IP.  This instruction is only
210 ;; matched by peephole2 operations.
212 (define_insn "*movqi_from_ip_plus_offs"
213   [(set (match_operand:QI 0 "nonimmediate_operand"           "=g")
214         (mem:QI (plus:HI (reg:HI 4)
215                          (match_operand 1 "const_int_operand" "P"))))]
216   "reload_completed && (INTVAL (operands[1]) < 0x100)"
217   "*{
218     if (INTVAL (operands[1]) == 1)
219       OUT_AS1 (inc, ipl);
220     else
221       {
222         OUT_AS2 (mov, w, %1);
223         OUT_AS2 (add, ipl, w);
224       }
225     OUT_AS1 (push, (IP)%<);
226     OUT_AS1 (pop, %0%>);
227     if (!find_regno_note (insn, REG_DEAD, REG_IP)
228         && ip2k_xexp_not_uses_reg_p (operands[0], REG_IP, 2))
229       {
230         if (INTVAL (operands[1]) == 1)
231           OUT_AS1 (dec, ipl);
232         else
233           OUT_AS2 (sub, ipl, w);
234       }
235     return \"\";
236   }")
238 (define_insn_and_split "*movqi"
239   [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,roR,r,  rS,roR")
240         (match_operand:QI 1 "general_operand"       "  O, ri,o,rioR,rSi"))]
241   ""
242   "@
243    clr\\t%0
244    #
245    #
246    #
247    #"
248   "(ip2k_reorg_split_qimode
249     && (GET_CODE (operands[1]) != CONST_INT
250         || INTVAL (operands[1]) != 0))"
251   [(set (reg:QI 10) (match_dup 1))
252    (set (match_dup 0) (reg:QI 10))]
253   ""
254   [(set_attr "skip" "yes,no,no,no,no")
255    (set_attr "clobberw" "no,yes,yes,yes,yes")])
257 (define_peephole2
258   [(set (reg:HI 12)
259         (reg:HI 4))
260    (set (match_operand:QI 0 "nonimmediate_operand" "")
261         (mem:QI (plus:HI (reg:HI 12)
262                          (match_operand 1 "const_int_operand" ""))))]
263   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
264     && peep2_regno_dead_p (2, REG_DP)
265     && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)
266     && (INTVAL (operands[1]) < 0x100))"
267   [(set (match_dup 0)
268         (mem:QI (plus:HI (reg:HI 4)
269                          (match_dup 1))))]
270   "")
272 (define_peephole2
273   [(set (reg:HI 12)
274         (reg:HI 4))
275    (set (mem:QI (plus:HI (reg:HI 12)
276                          (match_operand 0 "const_int_operand" "")))
277         (match_operand:QI 1 "general_operand" ""))]
278   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
279     && peep2_regno_dead_p (2, REG_DP)
280     && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)
281     && (INTVAL (operands[0]) < 0x100))"
282   [(set (mem:QI (plus:HI (reg:HI 4)
283                          (match_dup 0)))
284         (match_dup 1))]
285   "")
287 (define_peephole2
288   [(set (match_operand:QI 0 "register_operand" "")
289         (mem:QI (plus:HI (reg:HI 4)
290                          (match_operand 1 "const_int_operand" ""))))
291    (set (match_operand:QI 2 "nonimmediate_operand" "")
292         (match_dup 0))]
293   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
294     && peep2_reg_dead_p (2, operands[0]))"
295   [(set (match_dup 2)
296         (mem:QI (plus:HI (reg:HI 4)
297                          (match_dup 1))))]
298   "")
300 ;; We sometimes want to copy a value twice, usually when we copy a value into
301 ;; both a structure slot and into a temporary register.  We can win here
302 ;; because gcc doesn't know about ways of reusing w while we're copying.
304 (define_insn_and_split "*movqi_twice"
305   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
306         (match_operand:QI 1 "general_operand"       "g"))
307    (set (match_operand:QI 2 "nonimmediate_operand" "=g")
308         (match_dup 1))]
309   "ip2k_reorg_merge_qimode"
310   "mov\\tw,%1\;mov\\t%0,w\;mov\\t%2,w"
311   "(ip2k_reorg_split_qimode)"
312   [(set (reg:QI 10) (match_dup 1))
313    (set (match_dup 0) (reg:QI 10))
314    (set (match_dup 2) (reg:QI 10))]
315   "")
317 ;; Don't try to match until we've removed redundant reloads.  Often this
318 ;; simplification will remove the need to do two moves!
320 (define_peephole2
321   [(set (match_operand:QI 0 "nonimmediate_operand" "")
322         (match_operand:QI 1 "general_operand" ""))
323    (set (match_operand:QI 2 "nonimmediate_operand" "")
324         (match_dup 0))]
325   "(ip2k_reorg_merge_qimode
326     && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))"
327   [(parallel [(set (match_dup 0)
328                    (match_dup 1))
329               (set (match_dup 2)
330                    (match_dup 1))])]
331   "")
333 ;; Don't try to match until we've removed redundant reloads.  Often this
334 ;; simplification will remove the need to do two moves!
336 (define_peephole2
337   [(set (match_operand:QI 0 "nonimmediate_operand" "")
338         (match_operand:QI 1 "general_operand" ""))
339    (set (match_operand:QI 2 "nonimmediate_operand" "")
340         (match_dup 1))]
341   "(ip2k_reorg_merge_qimode
342     && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))"
343   [(parallel [(set (match_dup 0)
344                    (match_dup 1))
345               (set (match_dup 2)
346                    (match_dup 1))])]
347   "")
350 ;; Move 16-bit integers.
353 (define_expand "movhi"
354   [(set (match_operand:HI 0 "" "")
355         (match_operand:HI 1 "" ""))]
356   ""
357   "")
359 (define_insn "*pushhi_ip"
360   [(set (match_operand:HI 0 "push_operand"      "=<")
361         (mem:HI (reg:HI 4)))]
362   "reload_completed"
363   "inc\\tipl\;push\\t(IP)\;dec\\tipl\;push\\t(IP)"
364   [(set_attr "clobberw" "no")])
366 (define_insn "*movhi_to_ip"
367   [(set (mem:HI (reg:HI 4))
368         (match_operand:HI 0 "general_operand" "O,roi"))]
369   "reload_completed"
370   "*{
371     switch (which_alternative)
372       {
373       case 0:
374         OUT_AS1 (clr, (IP));
375         OUT_AS1 (inc, ipl);
376         OUT_AS1 (clr, (IP));
377         if (!find_regno_note (insn, REG_DEAD, REG_IP))
378           OUT_AS1 (dec, ipl);
379         return \"\";
381       case 1:
382         OUT_AS2 (mov, w, %H0);
383         OUT_AS2 (mov, (IP), w);
384         OUT_AS2 (mov, w, %L0);
385         OUT_AS1 (inc, ipl);
386         OUT_AS2 (mov, (IP), w);
387         if (!find_regno_note (insn, REG_DEAD, REG_IP))
388           OUT_AS1 (dec, ipl);
389         return \"\";
390       default:
391         abort ();
392       }
393   }")
395 (define_insn "*movhi_from_ip"
396   [(set (match_operand:HI 0 "nonimmediate_operand" "=f,bqdo")
397         (mem:HI (reg:HI 4)))]
398   "reload_completed"
399   "*{
400     switch (which_alternative)
401       {
402       case 0:
403         OUT_AS1 (push, (IP));
404         OUT_AS1 (inc, ipl);
405         OUT_AS2 (mov, w, (IP));
406         OUT_AS2 (mov, ipl, w);
407         OUT_AS1 (pop, iph);
408         return \"\";
410       case 1:
411         OUT_AS2 (mov, w, (IP));
412         OUT_AS2 (mov, %H0, w);
413         OUT_AS1 (inc, ipl);
414         OUT_AS2 (mov, w, (IP));
415         OUT_AS2 (mov, %L0, w);
416         if (!find_regno_note (insn, REG_DEAD, REG_IP))
417           OUT_AS1 (dec, ipl);
418         return \"\";
419       default:
420         abort ();
421       }
422   }")
424 (define_insn "*movhi_from_ip_plus_offs"
425   [(set (match_operand:HI 0 "nonimmediate_operand"           "=f,bqdo")
426         (mem:HI (plus:HI (reg:HI 4)
427                          (match_operand 1 "const_int_operand" "P,   P"))))]
428   "reload_completed && (INTVAL (operands[1]) < 0x100)"
429   "*{
430     switch (which_alternative)
431       {
432       case 0:
433         OUT_AS2 (mov, w, %1);
434         OUT_AS2 (add, ipl, w);
435         OUT_AS1 (push, (IP));
436         OUT_AS1 (inc, ipl);
437         OUT_AS2 (mov, w, (IP));
438         OUT_AS2 (mov, ipl, w);
439         OUT_AS1 (pop, iph);
440         return \"\";
442       case 1:
443         if (INTVAL (operands[1]) == 1)
444           OUT_AS1 (inc, ipl);
445         else
446           {
447             OUT_AS2 (mov, w, %1);
448             OUT_AS2 (add, ipl, w);
449           }
450         OUT_AS1 (push, (IP)%<);
451         OUT_AS1 (pop, %H0%>);
452         OUT_AS1 (inc, ipl);
453         OUT_AS1 (push, (IP)%<);
454         OUT_AS1 (pop, %L0%>);
455         if (!find_regno_note (insn, REG_DEAD, REG_IP))
456           {
457             OUT_AS1 (dec, ipl);
458             if (INTVAL (operands[1]) == 1)
459               OUT_AS1 (dec, ipl);
460             else
461               OUT_AS2 (sub, ipl, w);
462           }
463         return \"\";
464       default:
465         abort ();
466       }
467   }")
469 (define_insn_and_split "*movhi"
470   [(set
471     (match_operand:HI 0 "ip2k_split_dest_operand" "=<,<,uo,b, uS,uo,uo, q,u")
472     (match_operand:HI 1 "general_operand"        "ron,i, n,T,uoi,uS,ui,ui,q"))]
473   ""
474   "@
475    push\\t%L1%<\;push\\t%H1%>
476    push\\t%L1%<\;push\\t%H1%>
477    mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w
478    loadl\\t%x1\;loadh\\t%x1
479    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w
480    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w
481    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w
482    mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w
483    mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w"
484   "(ip2k_reorg_split_himode
485     && (GET_CODE (operands[1]) == CONST_INT
486         || (push_operand (operands[0], HImode)
487             && GET_CODE (operands[1]) == REG)
488         || (register_operand (operands[0], HImode)
489             && REGNO (operands[0]) >= 0x80
490             && ip2k_gen_operand (operands[1], HImode))))"
491   [(set (match_dup 2) (match_dup 3))
492    (set (match_dup 4) (match_dup 5))]
493   "{
494      ip2k_split_words (QImode, HImode, operands);  /* Split into 2=3,4=5 */
495   }"
496   [(set_attr "clobberw" "no,no,yes,no,yes,yes,yes,yes,yes")])
498 ;; We don't generally use IP for HImode indirections because it's not
499 ;; offsettable, however if we're accessing something that's already pointed
500 ;; to by IP and would otherwise require a reload of DP then we can win by
501 ;; simulating HImode accesses via IP instead.
503 (define_peephole2
504   [(set (reg:HI 12)
505         (reg:HI 4))
506    (set (mem:HI (reg:HI 12))
507         (match_operand:HI 0 "general_operand" ""))]
508   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
509     && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)
510     && peep2_regno_dead_p (2, REG_DP))"
511   [(set (mem:HI (reg:HI 4))
512         (match_dup 0))]
513   "")
515 (define_peephole2
516   [(set (reg:HI 12)
517         (reg:HI 4))
518    (set (match_operand:HI 0 "nonimmediate_operand" "")
519         (mem:HI (reg:HI 12)))]
520   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
521     && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)
522     && peep2_regno_dead_p (2, REG_DP))"
523   [(set (match_dup 0)
524         (mem:HI (reg:HI 4)))]
525   "")
527 (define_peephole2
528   [(set (reg:HI 12)
529         (reg:HI 4))
530    (set (match_operand:HI 0 "nonimmediate_operand" "")
531         (mem:HI (plus:HI (reg:HI 12)
532                          (match_operand 1 "const_int_operand" ""))))]
533    ;
534    ; We only match here if IP and DP both go dead because emulating
535    ; offsets in conjunction with IP doesn't win unless IP goes
536    ; dead too.
537    ;
538    "((ip2k_reorg_in_progress || ip2k_reorg_completed)
539     && peep2_regno_dead_p (2, REG_DP)
540     && peep2_regno_dead_p (2, REG_IP)
541     && (INTVAL (operands[1]) < 0x100))"
542   [(set (match_dup 0)
543         (mem:HI (plus:HI (reg:HI 4)
544                          (match_dup 1))))]
545   "")
547 (define_peephole2
548   [(set (reg:HI 12)
549         (reg:HI 4))
550    (set (reg:HI 4)
551         (mem:HI (plus:HI (reg:HI 12)
552                          (match_operand 0 "const_int_operand" ""))))]
553   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
554     && peep2_regno_dead_p (2, REG_DP)
555     && (INTVAL (operands[0]) < 0x100))"
556   [(set (reg:HI 4)
557         (mem:HI (plus:HI (reg:HI 4)
558                          (match_dup 0))))]
559   "")
561 (define_peephole2
562   [(set (match_operand:HI 0 "register_operand" "")
563         (mem:HI (reg:HI 4)))
564    (set (match_operand:HI 2 "nonimmediate_operand" "")
565         (match_dup 0))]
566   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
567     && peep2_reg_dead_p (2, operands[0]))"
568   [(set (match_dup 2)
569         (mem:HI (reg:HI 4)))]
570   "")
572 (define_peephole2
573   [(set (match_operand:HI 0 "register_operand" "")
574         (mem:HI (plus:HI (reg:HI 4)
575                          (match_operand 1 "const_int_operand" ""))))
576    (set (match_operand:HI 2 "nonimmediate_operand" "")
577         (match_dup 0))]
578   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
579     && peep2_reg_dead_p (2, operands[0])
580     && (INTVAL (operands[1]) < 0x100))"
581   [(set (match_dup 2)
582         (mem:HI (plus:HI (reg:HI 4)
583                          (match_dup 1))))]
584   "")
586 (define_peephole2
587   [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "")
588         (match_operand:HI 1 "ip2k_short_operand" ""))
589    (set (reg:HI 12)
590         (reg:HI 4))
591    (set (mem:HI (reg:HI 12))
592         (match_dup 0))]
593   "(peep2_reg_dead_p (3, operands[0])
594     && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2)
595     && peep2_regno_dead_p (3, REG_DP))"
596   [(set (mem:HI (reg:HI 4))
597         (match_dup 1))]
598   "")
600 ;; We sometimes want to copy a value twice, usually when we copy a value into
601 ;; both a structure slot and into a temporary register.  We can win here
602 ;; because gcc doesn't know about ways of reusing w while we're copying.
604 (define_insn "*movhi_twice"
605   [(set (match_operand:HI 0 "ip2k_gen_operand" "=&uS,uS")
606         (match_operand:HI 1 "ip2k_gen_operand"   "uS,uS"))
607    (set (match_operand:HI 2 "ip2k_gen_operand" "=&uS,uS")
608         (match_dup 1))]
609   "ip2k_reorg_split_simode"
610   "*{
611     switch (which_alternative)
612       {
613       case 0:
614         return AS2 (mov, w, %L1) CR_TAB
615                AS2 (mov, %L0, w) CR_TAB
616                AS2 (mov, %L2, w) CR_TAB
617                AS2 (mov, w, %H1) CR_TAB
618                AS2 (mov, %H0, w) CR_TAB
619                AS2 (mov, %H2, w);
621       case 1:
622         return AS2 (mov, w, %L1) CR_TAB
623                AS1 (push, %H1%<) CR_TAB
624                AS1 (push, %H1%<) CR_TAB
625                AS1 (pop, %H0%>) CR_TAB
626                AS2 (mov, %L0, w) CR_TAB
627                AS1 (pop, %H2%>) CR_TAB
628                AS2 (mov, %L2, w);
629       default:
630         abort ();
631       }
632   }")
634 ;; We have to be *very* careful with this one to use predicates that do not
635 ;; allow this to match if there are any register dependencies between the
636 ;; operands.
637 ;; Don't try to match until we've removed redundant reloads.  Often this
638 ;; simplification will remove the need to do two moves!
640 (define_peephole2
641   [(set (match_operand:HI 0 "ip2k_gen_operand" "")
642         (match_operand:HI 1 "ip2k_gen_operand" ""))
643    (set (match_operand:HI 2 "ip2k_gen_operand" "")
644         (match_dup 0))]
645   "(ip2k_reorg_split_simode)"
646   [(parallel [(set (match_dup 0)
647                    (match_dup 1))
648               (set (match_dup 2)
649                    (match_dup 1))])]
650   "")
652 ;; We have to be *very* careful with this one to use predicates that do not
653 ;; allow this to match if there are any register dependencies between the
654 ;; operands.
655 ;; Don't try to match until we've removed redundant reloads.  Often this
656 ;; simplification will remove the need to do two moves!
658 (define_peephole2
659   [(set (match_operand:HI 0 "ip2k_gen_operand" "")
660         (match_operand:HI 1 "ip2k_gen_operand" ""))
661    (set (match_operand:HI 2 "ip2k_gen_operand" "")
662         (match_dup 1))]
663   "(ip2k_reorg_split_simode
664     && (!REG_P (operands[0])
665         || ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2)))"
666   [(parallel [(set (match_dup 0)
667                    (match_dup 1))
668               (set (match_dup 2)
669                    (match_dup 1))])]
670   "")
673 ;; Move 32-bit integers.
676 (define_expand "movsi"
677   [(set (match_operand:SI 0 "" "")
678         (match_operand:SI 1 "" ""))]
679   ""
680   "")
682 (define_insn_and_split "*movsi"
683   [(set (match_operand:SI 0 "ip2k_split_dest_operand" "=<, ro,  S")
684         (match_operand:SI 1 "general_operand"       "roSi,rSi,roi"))]
685   ""
686   "#"
687   "ip2k_reorg_split_simode"
688   [(set (match_dup 2) (match_dup 3))
689    (set (match_dup 4) (match_dup 5))]
690   "{
691      ip2k_split_words (HImode, SImode, operands);  /* Split into 2=3,4=5 */
692   }")
694 ;; We sometimes want to copy a value twice, usually when we copy a value into
695 ;; both a structure slot and into a temporary register.  We can win here
696 ;; because gcc doesn't know about ways of reusing w while we're copying.
698 (define_insn "*movsi_twice"
699   [(set (match_operand:SI 0 "ip2k_gen_operand" "=&uS,uS")
700         (match_operand:SI 1 "ip2k_gen_operand"   "uS,uS"))
701    (set (match_operand:SI 2 "ip2k_gen_operand" "=&uS,uS")
702         (match_dup 1))]
703   "ip2k_reorg_split_dimode"
704   "*{
705     switch (which_alternative)
706       {
707       case 0:
708         return AS2 (mov, w, %A1) CR_TAB
709                AS2 (mov, %A0, w) CR_TAB
710                AS2 (mov, %A2, w) CR_TAB
711                AS2 (mov, w, %B1) CR_TAB
712                AS2 (mov, %B0, w) CR_TAB
713                AS2 (mov, %B2, w) CR_TAB
714                AS2 (mov, w, %C1) CR_TAB
715                AS2 (mov, %C0, w) CR_TAB
716                AS2 (mov, %C2, w) CR_TAB
717                AS2 (mov, w, %D1) CR_TAB
718                AS2 (mov, %D0, w) CR_TAB
719                AS2 (mov, %D2, w);
721       case 1:
722         return AS2 (mov, w, %D1) CR_TAB
723                AS1 (push, %C1%<) CR_TAB
724                AS1 (push, %B1%<) CR_TAB
725                AS1 (push, %A1%<) CR_TAB
726                AS1 (push, %C1%<) CR_TAB
727                AS1 (push, %B1%<) CR_TAB
728                AS1 (push, %A1%<) CR_TAB
729                AS1 (pop, %A0%>) CR_TAB
730                AS1 (pop, %B0%>) CR_TAB
731                AS1 (pop, %C0%>) CR_TAB
732                AS2 (mov, %D0, w) CR_TAB
733                AS1 (pop, %A2%>) CR_TAB
734                AS1 (pop, %B2%>) CR_TAB
735                AS1 (pop, %C2%>) CR_TAB
736                AS2 (mov, %D2, w);
737       default:
738         abort ();
739      }
740   }")
742 ;; We have to be *very* careful with this one to use predicates that do not 
743 ;; allow this to match if there are any register dependencies between the
744 ;; operands.
745 ;; Don't try to match until we've removed redundant reloads.  Often this
746 ;; simplification will remove the need to do two moves!
748 (define_peephole2
749   [(set (match_operand:SI 0 "ip2k_gen_operand" "")
750         (match_operand:SI 1 "ip2k_gen_operand" ""))
751    (set (match_operand:SI 2 "ip2k_gen_operand" "")
752         (match_dup 0))]
753   "(ip2k_reorg_split_dimode
754     && (!REG_P (operands[0])
755         || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 4)
756             && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), 4)))
757     && (!REG_P (operands[1])
758         || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[1]), 4)
759             && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[1]), 4)))
760     && (!REG_P (operands[2])
761         || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 4)
762             && ip2k_xexp_not_uses_reg_p (operands[1],
763                                          REGNO (operands[2]), 4))))"
764   [(parallel [(set (match_dup 0)
765                    (match_dup 1))
766               (set (match_dup 2)
767                    (match_dup 1))])]
768   "")
770 ;; We have to be *very* careful with this one to use predicates that do not
771 ;; allow this to match if there are any register dependencies between the
772 ;; operands.
773 ;; Don't try to match until we've removed redundant reloads.  Often this
774 ;; simplification will remove the need to do two moves!
776 (define_peephole2
777   [(set (match_operand:SI 0 "ip2k_gen_operand" "")
778         (match_operand:SI 1 "ip2k_gen_operand" ""))
779    (set (match_operand:SI 2 "ip2k_gen_operand" "")
780         (match_dup 1))]
781   "(ip2k_reorg_split_dimode
782     && (!REG_P (operands[0])
783         || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 4)
784             && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), 4)))
785     && (!REG_P (operands[1])
786         || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[1]), 4)
787             && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[1]), 4)))
788     && (!REG_P (operands[2])
789         || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 4)
790             && ip2k_xexp_not_uses_reg_p (operands[1],
791                                          REGNO (operands[2]), 4))))"
792   [(parallel [(set (match_dup 0)
793                    (match_dup 1))
794               (set (match_dup 2)
795                    (match_dup 1))])]
796   "")
799 ;; Move 64-bit integers.
802 (define_expand "movdi"
803   [(set (match_operand:DI 0 "" "")
804         (match_operand:DI 1 "" ""))]
805   ""
806   "")
808 (define_insn_and_split "*movdi"
809   [(set (match_operand:DI 0 "ip2k_split_dest_operand" "=<, ro,  S")
810         (match_operand:DI 1 "general_operand"       "roSi,rSi,roi"))]
811   ""
812   "#"
813   "ip2k_reorg_split_dimode"
814   [(set (match_dup 2) (match_dup 3))
815    (set (match_dup 4) (match_dup 5))]
816   "{
817      ip2k_split_words (SImode, DImode, operands);  /* Split into 2=3,4=5 */
818   }")
821 ;; Move 32-bit floating point values.
824 (define_expand "movsf"
825   [(set (match_operand:SF 0 "" "")
826         (match_operand:SF 1 "" ""))]
827   ""
828   "if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
829      operands[1] = copy_to_mode_reg (SFmode, operands[1]);
830   ")
832 (define_insn_and_split "*movsf"
833   [(set (match_operand:SF 0 "ip2k_split_dest_operand" "=r<, o")
834         (match_operand:SF 1 "general_operand"         "roi,ri"))]
835   "(ip2k_short_operand (operands[0], SFmode)
836     && ip2k_short_operand (operands[1], SFmode))
837    || ! (memory_operand (operands[0], SFmode)
838          && memory_operand (operands[1], SFmode))"
839   "#"
840   "(reload_completed || reload_in_progress)"
841   [(set (match_dup 2) (match_dup 3))
842    (set (match_dup 4) (match_dup 5))
843    (set (match_dup 6) (match_dup 7))
844    (set (match_dup 8) (match_dup 9))]
845   "{
846      /* Split into 2=3,4=5 */
847      ip2k_split_words (HImode, SImode, operands);
848      /* Split 4=5 into 6=7,8=9 */               
849      ip2k_split_words (QImode, HImode, &operands[4]); 
850      operands[0] = operands[2];
851      operands[1] = operands[3];
852      ip2k_split_words (QImode, HImode, operands);
853   }")
856 ;; Move 64-bit floating point values.
860 ;; Block move operations.
863 ;; Copy a block of bytes (memcpy()).  We expand the definition to convert
864 ;; our memory operand into a register pointer operand instead.
866 (define_expand "movstrhi"
867   [(use (match_operand:BLK 0 "memory_operand" ""))
868    (use (match_operand:BLK 1 "memory_operand" ""))
869    (use (match_operand:HI 2 "general_operand" ""))
870    (use (match_operand 3 "const_int_operand" ""))]
871   ""
872   "{
873     rtx addr0, addr1, count;
875     addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
876     addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
878     if (GET_CODE (operands[2]) == CONST_INT)
879       count = gen_int_mode (INTVAL (operands[2]) & 0xffff, HImode);
880     else
881       count = operands[2];
883     emit_insn (gen_movstrhi_expanded (addr0, count, addr1));
884     DONE;
885   }")
887 ;; Block copy instruction.  We handle this by calling one of two functions in
888 ;; libgcc.  The first of these is a special case (faster) routine that handles
889 ;; constant block sizes under 256 bytes.  This one is particularly common
890 ;; because we use it when copying data structures.  The second routine handles
891 ;; the general case where we have either a variable block size or one that is
892 ;; greater than 255 bytes.
894 (define_insn "movstrhi_expanded"
895   [(set
896     (mem:BLK
897      (match_operand:HI 0 "nonimmediate_operand" "rS,ro,rS, rS, ro, rS"))
898     (mem:BLK
899      (match_operand:HI 2 "nonimmediate_operand" "ro,rS,rS, ro, rS, rS")))
900    (use
901     (match_operand:HI 1 "general_operand"        "P, P, P,rSi,rSi,roi"))]
902   ""
903   "@
904    push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi
905    push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi
906    push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi
907    push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi
908    push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi
909    push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi")
912 ;; Bit insert
914 (define_expand "insv"
915   [(set (zero_extract:QI (match_operand:QI 0 "nonimmediate_operand" "")
916                          (match_operand 1 "immediate_operand" "")  ;size
917                          (match_operand 2 "immediate_operand" "")) ;pos
918         (match_operand:QI 3 "general_operand" ""))]
919   ""
920   "{
921     if (! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')
922         || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
923       FAIL;
924   }")
926 (define_insn "*insv"
927   [(set (zero_extract:QI
928          (match_operand:QI
929           0 "nonimmediate_operand" "+roR,roR,roR,roR,&roR,&roR,&r")
930          (match_operand
931           1 "immediate_operand"       "N,  N,  J,  J,   N,   J, J") ;sz
932          (match_operand
933           2 "immediate_operand"       "J,  J,  J,  J,   J,   J, J"));pos
934         (match_operand:QI
935          3 "general_operand"         "MN,  O,  M,  O, roR,  rn,oR"))]
936   ""
937   "*{
938     unsigned int pos = INTVAL (operands[2]),
939                  siz = INTVAL (operands[1]),
940                  mask = (1 << (pos + siz)) - (1 << pos);
942     switch (which_alternative)
943       {
944       case 0:
945         return \"setb\\t%0,%b1\";
947       case 1:
948         return \"clrb\\t%0,%b1\";
950       case 2:
951         operands[3] = gen_int_mode (mask & 0xff, QImode);
952         return AS2 (mov, w, %3) CR_TAB
953                AS2 (or, %0, w);
955       case 3:
956         operands[3] = gen_int_mode (0xff & ~mask, QImode);
957         return AS2 (mov, w, %3) CR_TAB
958                AS2 (and, %0, w);
960       case 4:
961         return AS2 (clrb, %0,%b2) CR_TAB
962                AS2 (snb, %3, 0) CR_TAB
963                AS2 (setb, %0, %b2);
965       case 5:
966       case 6:
967         {
968           static char buff[256];
969           char *p = buff;
971           /* Clear the destination field */
973           p += sprintf (buff, \"mov\\tw,#$%2.2x\;and\\t%%0,w\;\",
974                         0xff & ~mask);
976           if (CONSTANT_P (operands[3]))
977           /* Constant can just be or-ed in. */
978             {
979               p += sprintf (p, \"mov\\tw,#$%2.2x\;or\\t%%0,w\",
980                             (int) (INTVAL (operands[3]) << pos) & mask & 0xff);
981               return buff;
982             }
984           p += sprintf (p, \"mov\\tw,%%3\;\"); /* Value to deposit */
986           /* Shift and mask the value before OR-ing into the destination. */
988           if (pos != 0)
989             p += sprintf (p, \"mulu\\tw,#%d\;\", 1<<pos);
991           p += sprintf (p, \"\;and\\tw,#$%2.2x\;or\\t%%0,w\", mask);
992           return buff;
993         }
994       default:
995         abort ();
996       }
997   }"
998   [(set_attr "skip" "yes,yes,no,no,no,no,no")
999    (set_attr "clobberw" "no,no,yes,yes,no,yes,yes")])
1002 ;; Add bytes
1005 (define_expand "addqi3"
1006   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1007         (plus:QI (match_operand:QI 1 "general_operand" "")
1008                  (match_operand:QI 2 "general_operand" "")))]
1009   ""
1010   "")
1012 (define_insn "*push_addqi3"
1013   [(set (match_operand:QI 0 "push_operand"                  "=<,<,<")
1014         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%g,g,g")
1015                  (match_operand:QI 2 "general_operand"       "N,M,g")))]
1016   ""
1017   "@
1018    push\\t%1\;inc\\t1(SP)
1019    push\\t%1\;dec\\t1(SP)
1020    mov\\tw,%2\;add\\tw,%1\;push\\twreg"
1021   [(set_attr "clobberw" "no,no,yes")])
1023 (define_insn "*addqi3_w"
1024   [(set
1025     (reg:QI 10)
1026     (plus:QI
1027      (match_operand:QI 0 "nonimmediate_operand" "%rS, g,rS, g, rS,  g,rS")
1028      (match_operand:QI 1 "general_operand"        "N, N, M, M,rSi,rSi, g")))]
1029   "(ip2k_reorg_split_qimode)"
1030   "@
1031    inc\\tw,%0
1032    inc\\tw,%0
1033    dec\\tw,%0
1034    dec\\tw,%0
1035    mov\\tw,%1\;add\\tw,%0
1036    mov\\tw,%1\;add\\tw,%0
1037    mov\\tw,%1\;add\\tw,%0"
1038   [(set_attr "skip" "no,no,no,no,no,no,no")])
1040 (define_insn_and_split "*addqi3"
1041   [(set (match_operand:QI 0 "nonimmediate_operand"          "=k,k,z,z,djyoR,djyoR,djyoR,djyS, g,rS, g,rS,  g, rS,rS")
1042         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,    0,    0,    0,   0,rS, g,rS, g, rS,  g,rS")
1043                  (match_operand:QI 2 "general_operand"       "N,g,N,g,    N,    M,  rSi,   g, N, N, M, M,rSi,rSi, g")))]
1044   ""
1045   "@
1046    incsnz\\t%0\;dec\\tiph
1047    mov\\tw,%2\;add\\t%0,w
1048    incsnz\\t%0\;dec\\tdph
1049    mov\\tw,%2\;add\\t%0,w
1050    inc\\t%0
1051    dec\\t%0
1052    mov\\tw,%2\;add\\t%0,w
1053    mov\\tw,%2\;add\\t%0,w
1054    #
1055    #
1056    #
1057    #
1058    #
1059    #
1060    #"
1061   "(ip2k_reorg_split_qimode
1062     && ! rtx_equal_p (operands[0], operands[1]))"
1063   [(set (reg:QI 10)
1064         (plus:QI (match_dup 1)
1065                  (match_dup 2)))
1066    (set (match_dup 0)
1067         (reg:QI 10))]
1068   ""
1069   [(set_attr "skip" "no,no,no,no,yes,yes,no,no,no,no,no,no,no,no,no")
1070    (set_attr
1071     "clobberw" "no,yes,no,yes,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes")])
1074 ;; Add 16-bit integers.
1077 (define_expand "addhi3"
1078   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1079         (plus:HI (match_operand:HI 1 "general_operand" "")
1080                  (match_operand:HI 2 "general_operand" "")))]
1081   ""
1082   "if (rtx_equal_p (operands[1], operands[2]))
1083      {
1084        /* It is not impossible to wind up with two constants here.
1085           If we simply emit the ashl, we'll generate unrecognizable
1086           instructions. */
1087        if (! nonimmediate_operand (operands[1], HImode))
1088          operands[1] = copy_to_mode_reg (HImode, operands[1]);
1089        emit_insn (gen_ashlhi3 (operands[0], operands[1], GEN_INT (1)));
1090        DONE;
1091      }
1092   ")
1094 (define_insn "*push_addhi3" ;                      0 1  2  3   4   5 6 7
1095   [(set
1096     (match_operand:HI 0 "push_operand"           "=<,<, <, <,  <,  <,<,<")
1097     (plus:HI
1098      (match_operand:HI 1 "nonimmediate_operand" "%uo,q,uo,bf, uo, uS,q,q")
1099      (match_operand:HI 2 "general_operand"        "N,N, M, P,uSi,uoi,u,n")))]
1100   ""
1101   "*{
1102     switch (which_alternative) {
1103     case 0:
1104       return AS1 (push, %L1%<) CR_TAB
1105              AS1 (push, %H1%>) CR_TAB
1106              AS1 (incsnz, 2(SP)) CR_TAB
1107              AS1 (inc, 1(SP));
1109     case 1:
1110       return AS2 (mov, w, %H1) CR_TAB
1111              AS1 (push, %L1) CR_TAB
1112              AS1 (push, wreg) CR_TAB
1113              AS1 (incsnz, 2(SP)) CR_TAB
1114              AS1 (inc, 1(SP));
1116     case 2:
1117       return AS1 (push, %L1%<) CR_TAB
1118              AS1 (push, %H1%>) CR_TAB
1119              AS2 (mov, w, #-1) CR_TAB
1120              AS2 (add, 2(SP), w) CR_TAB
1121              AS2 (addc, 1(SP), w);
1123     case 3:
1124       OUT_AS2 (mov, w, %L2);
1125       OUT_AS2 (add, %L1, w);
1126       OUT_AS1 (push, %L1);
1127       OUT_AS1 (push, %H1);
1128       if (!find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1129         OUT_AS2 (sub, %L1, w);
1130       return \"\";
1132     case 4:
1133     case 5:
1134       return AS2 (mov, w, %L2) CR_TAB
1135              AS2 (add, w, %L1) CR_TAB
1136              AS1 (push, wreg%<) CR_TAB
1137              AS2 (mov, w, %H2) CR_TAB
1138              AS2 (addc, w, %H1) CR_TAB
1139              AS1 (push, wreg%>);
1141     case 6:
1142       return AS2 (mov, w, %H1) CR_TAB
1143              AS1 (push, %L1) CR_TAB
1144              AS1 (push, wreg) CR_TAB
1145              AS2 (mov, w, %L2) CR_TAB
1146              AS2 (add, 2(SP), w) CR_TAB
1147              AS2 (mov, w, %H2) CR_TAB
1148              AS2 (addc, 1(SP), w);
1150     case 7:
1151       {
1152         operands[3] = GEN_INT (INTVAL (operands[2]) + 2);
1153         return AS1 (push, %L3) CR_TAB
1154                AS1 (push, %H3) CR_TAB
1155                AS2 (mov, w, %L1) CR_TAB
1156                AS2 (add, 2(SP), w) CR_TAB
1157                AS2 (mov, w, %H1) CR_TAB
1158                AS2 (addc, 1(SP), w);
1159       }
1160     default:
1161       abort ();
1162     }
1163   }"
1164   [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes,yes")])
1166 (define_insn "*push_addhi3_zero_ext" ;               0    1    2   3
1167   [(set (match_operand:HI 0 "push_operand"         "=<,   <,   <,  <")
1168         (plus:HI
1169          (zero_extend:HI
1170           (match_operand:QI 1 "general_operand" "%roRi,roRi,roRi,rSi"))
1171          (match_operand:HI 2 "general_operand"      "N,   P, rSi,roi")))]
1172   ""
1173   "@
1174    inc\\tw,%L2\;push\\twreg\;push\\t#0\;rl\\t1(SP)
1175    mov\\tw,%L2\;add\\tw,%1\;push\\twreg\;push\\t#0\;rl\\t1(SP)
1176    mov\\tw,%L2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,$ff\;push\\twreg%>
1177    mov\\tw,%L2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,$ff\;push\\twreg%>")
1179 (define_insn "*addhi3_imm_zero_ext_w"
1180   [(set
1181     (match_operand:HI 0 "nonimmediate_operand"  "=rS,o,a,b,a,a,rS,o,rS,o")
1182     (plus:HI (zero_extend:HI (reg:QI 10))
1183              (match_operand 1 "immediate_operand" "O,O,M,i,P,I, P,P, i,i")))]
1184   ""
1185   "@
1186    mov\\t%L0,w\;clr\\t%H0
1187    mov\\t%L0,w\;clr\\t%H0
1188    mov\\t%L0,w\;clr\\t%H0\;dec\\t%L0
1189    loadh\\t%x1\;loadl\\t%x1\;add\\t%L0,w
1190    mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%1\;add\\t%L0,w
1191    mov\\t%L0,w\;clr\\t%H0\;mov\\tw,#%n1\;sub\\t%L0,w
1192    add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;rl\\t%H0
1193    add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;rl\\t%H0
1194    add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%H1\;addc\\t%H0,w
1195    add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%H1\;addc\\t%H0,w")
1197 (define_insn_and_split "*addhi3_imm_zero_ext"
1198   [(set
1199     (match_operand:HI
1200      0 "nonimmediate_operand" "=rS, o, rS, o,  a,  b,  a,  a, rS, o, rS, o")
1201     (plus:HI
1202      (zero_extend:HI
1203       (match_operand:QI
1204        1 "general_operand"   "%roR,rS,roR,rS,roR,roR,roR,roR,roR,rS,roR,rS"))
1205      (match_operand
1206       2 "immediate_operand"    " O, O,  N, N,  M,  i,  P,  I,  P, P,  i, i")))]
1207   ""
1208   "@
1209    #
1210    #
1211    clr\\t%H0\;incsnz\\tw,%1\;inc\\t%H0\;mov\\t%L0,w
1212    clr\\t%H0\;incsnz\\tw,%1\;inc\\t%H0\;mov\\t%L0,w
1213    #
1214    #
1215    #
1216    #
1217    #
1218    #
1219    #
1220    #"
1221   "(ip2k_reorg_split_qimode
1222     && (GET_CODE (operands[1]) != CONST_INT
1223         || INTVAL (operands[1]) != 1))"
1224   [(set (reg:QI 10)
1225         (match_dup 1))
1226    (set (match_dup 0)
1227         (plus:HI (zero_extend:HI (reg:QI 10))
1228                  (match_dup 2)))])
1230 (define_insn "*addhi3_immediate" ;                       0  1 2  3 4 5 6  7   8   9  a  b  c   d   e  f
1231   [(set (match_operand:HI 0 "nonimmediate_operand"     "=a,do,a,do,a,a,a,do,&uo,&uS,bf,bf,bf,&uS,&uo, u")
1232         (plus:HI (match_operand:HI 1 "general_operand" "%0, 0,0, 0,0,0,0, 0, rS, ro,uo,uo,uo, ro, rS,uo")
1233                  (match_operand 2 "immediate_operand"   "N, N,M, M,P,I,i, i,  N,  N, M, P, I,  i,  i, i")))]
1234   ""
1235   "@
1236    inc\\t%L0
1237    incsnz\\t%L0\;inc\\t%H0
1238    dec\\t%L0
1239    mov\\tw,#-1\;add\\t%L0,w\;addc\\t%H0,w
1240    mov\\tw,%2\;add\\t%L0,w
1241    mov\\tw,#%n2\;sub\\t%L0,w
1242    mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;add\\t%H0,w
1243    mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w
1244    mov\\tw,%H1\;mov\\t%H0,w\;incsnz\\tw,%L1\;inc\\t%H0\;mov\\t%L0,w
1245    mov\\tw,%H1\;mov\\t%H0,w\;incsnz\\tw,%L1\;inc\\t%H0\;mov\\t%L0,w
1246    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;dec\\t%L0
1247    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;mov\\tw,%2\;add\\t%L0,w
1248    mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;mov\\tw,#%n2\;sub\\t%L0,w
1249    mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w
1250    mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w
1251    mov\\tw,%L2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;pop\\t%L0%>"
1252   [(set_attr "skip" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no,no,no")
1253    (set_attr "clobberw" "no,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes")])
1255 (define_insn "*addhi3_nonimmediate" ;                         0  1  2    3 4   5   6  7
1256   [(set (match_operand:HI 0 "nonimmediate_operand"        "=&bf,bf,&dS,&do,d,&rS,&rS, o")
1257         (plus:HI (match_operand:HI 1 "general_operand"      "%0, 0,  0,  0,0, ro, rS,rS")
1258                  (match_operand:HI 2 "nonimmediate_operand" "ro,uo, ro, rS,r, rS, ro,rS")))]
1259   ""
1260   "@
1261    mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;add\\t%H0,w
1262    mov\\tw,%L2\;push\\t%H2%<\;add\\t%L0,w\;pop\\twreg%>\;add\\t%H0,w
1263    mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w
1264    mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w
1265    mov\\tw,%L2\;push\\t%H2%<\;add\\t%L0,w\;pop\\twreg%>\;addc\\t%H0,w
1266    mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w
1267    mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w
1268    mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w")
1270 (define_insn "*addhi3_nonimm_zero_extend_w"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,ro,&ro,&rS,&rS, u")
1272         (plus:HI
1273          (zero_extend:HI (reg:QI 10))
1274          (match_operand:HI 1 "nonimmediate_operand" "0, 0, rS, rS, ro,uo")))]
1275   ""
1276   "@
1277    add\\t%L0,w
1278    add\\t%L0,w\;clr\\twreg\;addc\\t%H0,w
1279    add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w
1280    add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w
1281    add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w
1282    add\\tw,%L1\;push\\twreg%<\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w\;pop\\t%L0%>"
1283   [(set_attr "skip" "yes,no,no,no,no,no")
1284    (set_attr "clobberw" "no,yes,yes,yes,yes,yes")])
1286 (define_insn_and_split "*addhi3_nonimm_zero_extend"
1287   [(set (match_operand:HI 0 "nonimmediate_operand" "=a, ro,&ro,&rS,&rS, u")
1288         (plus:HI
1289          (zero_extend:HI
1290           (match_operand:QI 1 "general_operand"   "roR,roR, rS,roR, rS,rS"))
1291          (match_operand:HI 2 "nonimmediate_operand" "0,  0, rS, rS, ro,uo")))]
1292   ""
1293   "#"
1294   "(ip2k_reorg_split_qimode)"
1295   [(set (reg:QI 10)
1296         (match_dup 1))
1297    (set (match_dup 0)
1298         (plus:HI (zero_extend:HI (reg:QI 10))
1299                  (match_dup 2)))])
1300   
1303 ;; Add 32-bit integers.
1306 (define_expand "addsi3"
1307   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1308         (plus:SI (match_operand:SI 1 "general_operand" "")
1309                  (match_operand:SI 2 "general_operand" "")))]
1310   ""
1311   "")
1313 (define_insn "*push_addsi3"
1314   [(set (match_operand:SI 0 "push_operand"                  "=<,<,  <")
1315         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%g,g,  g")
1316                  (match_operand:SI 2 "general_operand"       "N,M,rSi")))]
1317   ""
1318   "*{
1319     switch (which_alternative) {
1320     case 0:
1321       OUT_AS1 (push, %D1%<);
1322       OUT_AS1 (push, %C1%<);
1323       OUT_AS1 (push, %B1%<);
1324       OUT_AS1 (push, %A1%>%>%>);
1325       OUT_AS1 (incsnz, 4(SP));
1326       OUT_AS1 (incsz, 3(SP));
1327       OUT_AS1 (page, 1f);
1328       OUT_AS1 (jmp, 1f);
1329       OUT_AS1 (incsnz, 2(SP));
1330       OUT_AS1 (inc, 1(SP));
1331       OUT_AS1 (1:,);
1332       return \"\";
1334     case 1:
1335       OUT_AS1 (push, %D1%<);
1336       OUT_AS1 (push, %C1%<);
1337       OUT_AS1 (push, %B1%<);
1338       OUT_AS1 (push, %A1%>%>%>);
1339       OUT_AS2 (mov, w, #-1);
1340       OUT_AS2 (add, 4(SP), w);
1341       OUT_AS2 (addc, 3(SP), w);
1342       OUT_AS2 (addc, 2(SP), w);
1343       OUT_AS2 (addc, 1(SP), w);
1344       return \"\";
1346     case 2:
1347       OUT_AS2 (mov, w, %D2);
1348       OUT_AS2 (add, w, %D1);
1349       OUT_AS1 (push, wreg%<);
1350       OUT_AS2 (mov, w, %C2);
1351       OUT_AS2 (addc, w, %C1);
1352       OUT_AS1 (push, wreg%<);
1353       OUT_AS2 (mov, w, %B2);
1354       OUT_AS2 (addc, w, %B1);
1355       OUT_AS1 (push, wreg%<);
1356       OUT_AS2 (mov, w, %A2);
1357       OUT_AS2 (addc, w, %A1);
1358       OUT_AS1 (push, wreg%>%>%>);
1359       return \"\";
1361     default:
1362       abort();
1363     }
1364   }"
1365   [(set_attr "clobberw" "no,yes,yes")])
1367 (define_insn "*addsi3" ;                                      0  1   2   3   4   5   6
1368   [(set
1369     (match_operand:SI 0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&rS")
1370     (plus:SI
1371      (match_operand:SI 1 "nonimmediate_operand" "%0, 0,  0,  0, rS, ro, rS")
1372      (match_operand:SI 2 "general_operand"       "N, M,rSi,roi,rSi,rSi,roi")))]
1373   ""
1374   "@
1375    incsnz\\t%D0\;incsz\\t%C0\;page\\t1f\;jmp\\t1f\;incsnz\\t%B0\;inc\\t%A0\;1:
1376    mov\\tw,#-1\;add\\t%D0,w\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w
1377    mov\\tw,%D2\;add\\t%D0,w\;mov\\tw,%C2\;addc\\t%C0,w\;mov\\tw,%B2\;addc\\t%B0,w\;mov\\tw,%A2\;addc\\t%A0,w
1378    mov\\tw,%D2\;add\\t%D0,w\;mov\\tw,%C2\;addc\\t%C0,w\;mov\\tw,%B2\;addc\\t%B0,w\;mov\\tw,%A2\;addc\\t%A0,w
1379    mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w
1380    mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w
1381    mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w"
1382   [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes")])
1384 (define_insn "*push_addsi3_zero_extendqi" ;                   0   1
1385   [(set (match_operand:SI 0 "push_operand"                  "=<,  <")
1386         (plus:SI (zero_extend:SI
1387                    (match_operand:QI 1 "general_operand" "%roRi,rSi"))
1388                  (match_operand:SI 2 "general_operand"     "rSi,roi")))]
1389   ""
1390   "@
1391    mov\\tw,%D2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>
1392    mov\\tw,%D2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>")
1394 (define_insn "*addsi3_zero_extendqi" ;
1395   [(set (match_operand:SI 0 "nonimmediate_operand"  "=ro, rS,&ro,&rS,&rS")
1396         (plus:SI
1397          (zero_extend:SI
1398           (match_operand:QI 1 "nonimmediate_operand" "rS,roR, rS,roR, rS"))
1399          (match_operand:SI 2 "general_operand"        "0,  0,rSi,rSi,roi")))]
1400   ""
1401   "@
1402    mov\\tw,%1\;add\\t%D0,w\;clr\\twreg\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w
1403    mov\\tw,%1\;add\\t%D0,w\;clr\\twreg\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w
1404    mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w
1405    mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w
1406    mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w")
1408 (define_insn "*push_addsi3_zero_extendhi" ;                       0   1
1409   [(set (match_operand:SI 0 "push_operand"                      "=<,  <")
1410         (plus:SI (zero_extend:SI
1411                    (match_operand:HI 1 "nonimmediate_operand" "%roR,rSR"))
1412                  (match_operand:SI 2 "general_operand"         "rSi,roi")))]
1413   ""
1414   "@
1415    mov\\tw,%D2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,%H1\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>
1416    mov\\tw,%D2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,%H1\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>")
1418 (define_insn "*addsi3_zero_extendhi" ;
1419   [(set (match_operand:SI 0 "nonimmediate_operand"  "=ro,rS,&ro,&rS,&rS")
1420         (plus:SI
1421          (zero_extend:SI
1422           (match_operand:HI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS"))
1423          (match_operand:SI 2 "general_operand"        "0, 0,rSi,rSi,roi")))]
1424   ""
1425   "@
1426    mov\\tw,%L1\;add\\t%D0,w\;mov\\tw,%H1\;addc\\t%C0,w\;clr\\twreg\;addc\\t%B0,w\;addc\\t%A0,w
1427    mov\\tw,%L1\;add\\t%D0,w\;mov\\tw,%H1\;addc\\t%C0,w\;clr\\twreg\;addc\\t%B0,w\;addc\\t%A0,w
1428    mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w
1429    mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w
1430    mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w")
1433 ;; Add 64-bit integers.
1436 (define_expand "adddi3"
1437   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1438         (plus:DI (match_operand:DI 1 "general_operand" "")
1439                  (match_operand:DI 2 "general_operand" "")))]
1440   ""
1441   "")
1443 (define_insn "*push_adddi3"
1444   [(set (match_operand:DI 0 "push_operand"                  "=<,<,  <")
1445         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%g,g,  g")
1446                  (match_operand:DI 2 "general_operand"       "N,M,rSi")))]
1447   ""
1448   "*{
1449     switch (which_alternative)
1450       {
1451         case 0:
1452           OUT_AS1 (push, %Z1%<);
1453           OUT_AS1 (push, %Y1%<);
1454           OUT_AS1 (push, %X1%<);
1455           OUT_AS1 (push, %W1%<);
1456           OUT_AS1 (push, %V1%<);
1457           OUT_AS1 (push, %U1%<);
1458           OUT_AS1 (push, %T1%<);
1459           OUT_AS1 (push, %S1%>%>%>%>%>%>%>);
1460           OUT_AS1 (incsnz, 8(SP));
1461           OUT_AS1 (incsz, 7(SP));
1462           OUT_AS1 (page, 1f);
1463           OUT_AS1 (jmp, 1f);
1464           OUT_AS1 (incsnz, 6(SP));
1465           OUT_AS1 (incsz, 5(SP));
1466           OUT_AS1 (page, 1f);
1467           OUT_AS1 (jmp, 1f);
1468           OUT_AS1 (incsnz, 4(SP));
1469           OUT_AS1 (incsz, 3(SP));
1470           OUT_AS1 (page, 1f);
1471           OUT_AS1 (jmp, 1f);
1472           OUT_AS1 (incsnz, 2(SP));
1473           OUT_AS1 (inc, 1(SP));
1474           OUT_AS1 (1:,);
1475           return \"\";
1477         case 1:
1478           OUT_AS1 (push, %Z1%<);
1479           OUT_AS1 (push, %Y1%<);
1480           OUT_AS1 (push, %X1%<);
1481           OUT_AS1 (push, %W1%<);
1482           OUT_AS1 (push, %V1%<);
1483           OUT_AS1 (push, %U1%<);
1484           OUT_AS1 (push, %T1%<);
1485           OUT_AS1 (push, %S1%>%>%>%>%>%>%>);
1486           OUT_AS2 (mov, w, #-1);
1487           OUT_AS2 (add, 8(SP), w);
1488           OUT_AS2 (addc, 7(SP), w);
1489           OUT_AS2 (addc, 6(SP), w);
1490           OUT_AS2 (addc, 5(SP), w);
1491           OUT_AS2 (addc, 4(SP), w);
1492           OUT_AS2 (addc, 3(SP), w);
1493           OUT_AS2 (addc, 2(SP), w);
1494           OUT_AS2 (addc, 1(SP), w);
1495           return \"\";
1497         case 2:
1498           OUT_AS2 (mov, w, %Z2);
1499           OUT_AS2 (add, w, %Z1);
1500           OUT_AS1 (push, wreg%<);
1501           OUT_AS2 (mov, w, %Y2);
1502           OUT_AS2 (addc, w, %Y1);
1503           OUT_AS1 (push, wreg%<);
1504           OUT_AS2 (mov, w, %X2);
1505           OUT_AS2 (addc, w, %X1);
1506           OUT_AS1 (push, wreg%<);
1507           OUT_AS2 (mov, w, %W2);
1508           OUT_AS2 (addc, w, %W1);
1509           OUT_AS1 (push, wreg%<);
1510           OUT_AS2 (mov, w, %V2);
1511           OUT_AS2 (addc, w, %V1);
1512           OUT_AS1 (push, wreg%<);
1513           OUT_AS2 (mov, w, %U2);
1514           OUT_AS2 (addc, w, %U1);
1515           OUT_AS1 (push, wreg%<);
1516           OUT_AS2 (mov, w, %T2);
1517           OUT_AS2 (addc, w, %T1);
1518           OUT_AS1 (push, wreg%<);
1519           OUT_AS2 (mov, w, %S2);
1520           OUT_AS2 (addc, w, %S1);
1521           OUT_AS1 (push, wreg%>%>%>%>%>%>%>);
1522           return \"\";
1524         default:
1525           abort();
1526       }
1527   }"
1528   [(set_attr "clobberw" "no,yes,yes")])
1530 (define_insn "*adddi3" ;                         0  1   2   3   4   5   6
1531   [(set
1532     (match_operand:DI 0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&rS")
1533     (plus:DI
1534      (match_operand:DI 1 "nonimmediate_operand" "%0, 0,  0,  0, rS, ro, rS")
1535      (match_operand:DI 2 "general_operand"       "N, M,rSi,roi,rSi,rSi,roi")))]
1536   ""
1537   "*{
1538     switch (which_alternative)
1539       {
1540         case 0:
1541           OUT_AS1 (incsnz, %Z0);
1542           OUT_AS1 (incsz, %Y0);
1543           OUT_AS1 (page, 1f);
1544           OUT_AS1 (jmp, 1f);
1545           OUT_AS1 (incsnz, %X0);
1546           OUT_AS1 (incsz, %W0);
1547           OUT_AS1 (page, 1f);
1548           OUT_AS1 (jmp, 1f);
1549           OUT_AS1 (incsnz, %V0);
1550           OUT_AS1 (incsz, %U0);
1551           OUT_AS1 (page, 1f);
1552           OUT_AS1 (jmp, 1f);
1553           OUT_AS1 (incsnz, %T0);
1554           OUT_AS1 (inc, %S0);
1555           OUT_AS1 (1:, );
1556           return \"\";
1558         case 1:
1559           OUT_AS2 (mov, w, #-1);
1560           OUT_AS2 (add, %Z0, w);
1561           OUT_AS2 (addc, %Y0, w);
1562           OUT_AS2 (addc, %X0, w);
1563           OUT_AS2 (addc, %W0, w);
1564           OUT_AS2 (addc, %V0, w);
1565           OUT_AS2 (addc, %U0, w);
1566           OUT_AS2 (addc, %T0, w);
1567           OUT_AS2 (addc, %S0, w);
1568           return \"\";
1570         case 2:
1571         case 3:
1572           OUT_AS2 (mov, w, %Z2);
1573           OUT_AS2 (add, %Z0, w);
1574           OUT_AS2 (mov, w, %Y2);
1575           OUT_AS2 (addc, %Y0, w);
1576           OUT_AS2 (mov, w, %X2);
1577           OUT_AS2 (addc, %X0, w);
1578           OUT_AS2 (mov, w, %W2);
1579           OUT_AS2 (addc, %W0, w);
1580           OUT_AS2 (mov, w, %V2);
1581           OUT_AS2 (addc, %V0, w);
1582           OUT_AS2 (mov, w, %U2);
1583           OUT_AS2 (addc, %U0, w);
1584           OUT_AS2 (mov, w, %T2);
1585           OUT_AS2 (addc, %T0, w);
1586           OUT_AS2 (mov, w, %S2);
1587           OUT_AS2 (addc, %S0, w);
1588           return \"\";
1590         case 4:
1591         case 5:
1592         case 6:
1593           OUT_AS2 (mov, w, %Z2);
1594           OUT_AS2 (add, w, %Z1);
1595           OUT_AS2 (mov, %Z0, w);
1596           OUT_AS2 (mov, w, %Y2);
1597           OUT_AS2 (addc, w, %Y1);
1598           OUT_AS2 (mov, %Y0, w);
1599           OUT_AS2 (mov, w, %X2);
1600           OUT_AS2 (addc, w, %X1);
1601           OUT_AS2 (mov, %X0, w);
1602           OUT_AS2 (mov, w, %W2);
1603           OUT_AS2 (addc, w, %W1);
1604           OUT_AS2 (mov, %W0, w);
1605           OUT_AS2 (mov, w, %V2);
1606           OUT_AS2 (addc, w, %V1);
1607           OUT_AS2 (mov, %V0, w);
1608           OUT_AS2 (mov, w, %U2);
1609           OUT_AS2 (addc, w, %U1);
1610           OUT_AS2 (mov, %U0, w);
1611           OUT_AS2 (mov, w, %T2);
1612           OUT_AS2 (addc, w, %T1);
1613           OUT_AS2 (mov, %T0, w);
1614           OUT_AS2 (mov, w, %S2);
1615           OUT_AS2 (addc, w, %S1);
1616           OUT_AS2 (mov, %S0, w);
1617           return \"\";
1619         default:
1620           abort();
1621       }
1622   }"
1623   [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes")])
1625 (define_insn "*adddi3_zero_extendqi" ;                 0   1   2   3   4
1626   [(set (match_operand:DI 0 "nonimmediate_operand"  "=ro, rS,&ro,&rS,&rS")
1627         (plus:DI
1628          (zero_extend:DI
1629           (match_operand:QI 1 "nonimmediate_operand" "rS,roR, rS,roR, rS"))
1630          (match_operand:DI 2 "general_operand"        "0,  0,rSi,rSi,roi")))]
1631   ""
1632   "*{
1633     switch (which_alternative)
1634       {
1635         case 0:
1636         case 1:
1637           OUT_AS2 (mov, w, %1);
1638           OUT_AS2 (add, %Z0, w);
1639           OUT_AS1 (clr, wreg);
1640           OUT_AS2 (addc, %Y0, w);
1641           OUT_AS2 (addc, %X0, w);
1642           OUT_AS2 (addc, %W0, w);
1643           OUT_AS2 (addc, %V0, w);
1644           OUT_AS2 (addc, %U0, w);
1645           OUT_AS2 (addc, %T0, w);
1646           OUT_AS2 (addc, %S0, w);
1647           return \"\";
1649         case 2:
1650         case 3:
1651         case 4:
1652           OUT_AS2 (mov, w, %1);
1653           OUT_AS2 (add, w, %Z2);
1654           OUT_AS2 (mov, %Z0, w);
1655           OUT_AS2 (mov, w, %Y2);
1656           OUT_AS2 (addc, w, $ff);
1657           OUT_AS2 (mov, %Y0, w);
1658           OUT_AS2 (mov, w, %X2);
1659           OUT_AS2 (addc, w, $ff);
1660           OUT_AS2 (mov, %X0, w);
1661           OUT_AS2 (mov, w, %W2);
1662           OUT_AS2 (addc, w, $ff);
1663           OUT_AS2 (mov, %W0, w);
1664           OUT_AS2 (mov, w, %V2);
1665           OUT_AS2 (addc, w, $ff);
1666           OUT_AS2 (mov, %V0, w);
1667           OUT_AS2 (mov, w, %U2);
1668           OUT_AS2 (addc, w, $ff);
1669           OUT_AS2 (mov, %U0, w);
1670           OUT_AS2 (mov, w, %T2);
1671           OUT_AS2 (addc, w, $ff);
1672           OUT_AS2 (mov, %T0, w);
1673           OUT_AS2 (mov, w, %S2);
1674           OUT_AS2 (addc, w, $ff);
1675           OUT_AS2 (mov, %S0, w);
1676           return \"\";
1678         default:
1679           abort();
1680       }
1681   }")
1683 (define_insn "*adddi3_zero_extendhi" ;                0  1   2   3   4
1684   [(set (match_operand:DI 0 "nonimmediate_operand"  "=ro,rS,&ro,&rS,&rS")
1685         (plus:DI
1686          (zero_extend:DI
1687           (match_operand:HI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS"))
1688          (match_operand:DI 2 "general_operand"        "0, 0,rSi,rSi,roi")))]
1689   ""
1690   "*{
1691     switch (which_alternative)
1692       {
1693         case 0:
1694         case 1:
1695           OUT_AS2 (mov, w, %L1);
1696           OUT_AS2 (add, %Z0, w);
1697           OUT_AS2 (mov, w, %H1);
1698           OUT_AS2 (addc, %Y0, w);
1699           OUT_AS1 (clr, wreg);
1700           OUT_AS2 (addc, %X0, w);
1701           OUT_AS2 (addc, %W0, w);
1702           OUT_AS2 (addc, %V0, w);
1703           OUT_AS2 (addc, %U0, w);
1704           OUT_AS2 (addc, %T0, w);
1705           OUT_AS2 (addc, %S0, w);
1706           return \"\";
1708         case 2:
1709         case 3:
1710         case 4:
1711           OUT_AS2 (mov, w, %L1);
1712           OUT_AS2 (add, w, %Z2);
1713           OUT_AS2 (mov, %Z0, w);
1714           OUT_AS2 (mov, w, %Y2);
1715           OUT_AS2 (addc, w, %H1);
1716           OUT_AS2 (mov, %Y0, w);
1717           OUT_AS2 (mov, w, %X2);
1718           OUT_AS2 (addc, w, $ff);
1719           OUT_AS2 (mov, %X0, w);
1720           OUT_AS2 (mov, w, %W2);
1721           OUT_AS2 (addc, w, $ff);
1722           OUT_AS2 (mov, %W0, w);
1723           OUT_AS2 (mov, w, %V2);
1724           OUT_AS2 (addc, w, $ff);
1725           OUT_AS2 (mov, %V0, w);
1726           OUT_AS2 (mov, w, %U2);
1727           OUT_AS2 (addc, w, $ff);
1728           OUT_AS2 (mov, %U0, w);
1729           OUT_AS2 (mov, w, %T2);
1730           OUT_AS2 (addc, w, $ff);
1731           OUT_AS2 (mov, %T0, w);
1732           OUT_AS2 (mov, w, %S2);
1733           OUT_AS2 (addc, w, $ff);
1734           OUT_AS2 (mov, %S0, w);
1735           return \"\";
1737         default:
1738           abort();
1739       }
1740   }")
1742 (define_insn "*adddi3_zero_extendsi" ;                 0  1   2   3   4
1743   [(set (match_operand:DI 0 "nonimmediate_operand"  "=ro,rS,&ro,&rS,&rS")
1744         (plus:DI
1745          (zero_extend:DI
1746           (match_operand:SI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS"))
1747          (match_operand:DI 2 "general_operand"        "0, 0,rSi,rSi,roi")))]
1748   ""
1749   "*{
1750     switch (which_alternative)
1751       {
1752         case 0:
1753         case 1:
1754           OUT_AS2 (mov, w, %D1);
1755           OUT_AS2 (add, %Z0, w);
1756           OUT_AS2 (mov, w, %C1);
1757           OUT_AS2 (addc, %Y0, w);
1758           OUT_AS2 (mov, w, %B1);
1759           OUT_AS2 (addc, %X0, w);
1760           OUT_AS2 (mov, w, %A1);
1761           OUT_AS2 (addc, %W0, w);
1762           OUT_AS1 (clr, wreg);
1763           OUT_AS2 (addc, %V0, w);
1764           OUT_AS2 (addc, %U0, w);
1765           OUT_AS2 (addc, %T0, w);
1766           OUT_AS2 (addc, %S0, w);
1767           return \"\";
1769         case 2:
1770         case 3:
1771         case 4:
1772           OUT_AS2 (mov, w, %D1);
1773           OUT_AS2 (add, w, %Z2);
1774           OUT_AS2 (mov, %Z0, w);
1775           OUT_AS2 (mov, w, %Y2);
1776           OUT_AS2 (addc, w, %C1);
1777           OUT_AS2 (mov, %Y0, w);
1778           OUT_AS2 (mov, w, %X2);
1779           OUT_AS2 (addc, w, %B1);
1780           OUT_AS2 (mov, %X0, w);
1781           OUT_AS2 (mov, w, %W2);
1782           OUT_AS2 (addc, w, %A1);
1783           OUT_AS2 (mov, %W0, w);
1784           OUT_AS2 (mov, w, %V2);
1785           OUT_AS2 (addc, w, $ff);
1786           OUT_AS2 (mov, %V0, w);
1787           OUT_AS2 (mov, w, %U2);
1788           OUT_AS2 (addc, w, $ff);
1789           OUT_AS2 (mov, %U0, w);
1790           OUT_AS2 (mov, w, %T2);
1791           OUT_AS2 (addc, w, $ff);
1792           OUT_AS2 (mov, %T0, w);
1793           OUT_AS2 (mov, w, %S2);
1794           OUT_AS2 (addc, w, $ff);
1795           OUT_AS2 (mov, %S0, w);
1796           return \"\";
1798         default:
1799           abort();
1800       }
1801   }")
1804 ;; Subtract bytes.
1807 (define_expand "subqi3"
1808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1809         (minus:QI (match_operand:QI 1 "general_operand" "")
1810                   (match_operand:QI 2 "general_operand" "")))]
1811   ""
1812   "if (GET_CODE (operands[2]) == CONST_INT)
1813      {
1814        emit_insn (gen_addqi3 (operands[0], operands[1],
1815                               gen_int_mode (-INTVAL (operands[2]), QImode)));
1816        DONE;
1817      }
1818   ")
1820 (define_insn "*push_subqi3"
1821   [(set (match_operand:QI 0 "push_operand"               "=<,  <")
1822         (minus:QI (match_operand:QI 1 "general_operand"   "g,rSn")
1823                   (match_operand:QI 2 "general_operand" "rSn,  g")))]
1824   ""
1825   "@
1826    push\\t%1%<\;mov\\tw,%2\;sub\\t1(SP),w%>
1827    push\\t%1%<\;mov\\tw,%2\;sub\\t1(SP),w%>")
1829 (define_insn "*subqi3_w"
1830   [(set (reg:QI 10)
1831         (minus:QI (match_operand:QI 0 "general_operand"  "rS,rSi,  g,rSi")
1832                   (match_operand:QI 1 "general_operand" "rSi, rS,rSi,  g")))]
1833   "(ip2k_reorg_split_qimode)"
1834   "@
1835    mov\\tw,%1\;sub\\tw,%0
1836    mov\\tw,%1\;sub\\tw,%0
1837    mov\\tw,%1\;sub\\tw,%0
1838    mov\\tw,%1\;sub\\tw,%0")
1840 (define_insn_and_split "*subqi3"
1841   [(set
1842     (match_operand:QI
1843      0 "nonimmediate_operand" "=k,k,z,z,djyoR,djyoR,djyS,djyoR,  g,  g, rS, rS")
1844     (minus:QI
1845      (match_operand:QI
1846       1 "general_operand"     "0,0,0,0,    0,    0,   0,    0, rS,rSi,  g,rSi")
1847      (match_operand:QI
1848       2 "general_operand"     "M,g,M,g,    M,    N,   g,  rSi,rSi, rS,rSi,  g")))]
1849   ""
1850   "@
1851    incsnz\\t%0\;dec\\tiph
1852    mov\\tw,%2\;sub\\t%0,w
1853    incsnz\\t%0\;dec\\tdph
1854    mov\\tw,%2\;sub\\t%0,w
1855    inc\\t%0
1856    dec\\t%0
1857    mov\\tw,%2\;sub\\t%0,w
1858    mov\\tw,%2\;sub\\t%0,w
1859    #
1860    #
1861    #
1862    #"
1863   "(ip2k_reorg_split_qimode
1864     && ! rtx_equal_p (operands[0], operands[1]))"
1865   [(set (reg:QI 10)
1866         (minus:QI (match_dup 1)
1867                   (match_dup 2)))
1868    (set (match_dup 0)
1869         (reg:QI 10))]
1870   ""
1871   [(set_attr "skip" "no,no,no,no,yes,yes,no,no,no,no,no,no")
1872    (set_attr "clobberw" "no,yes,no,yes,no,no,yes,yes,yes,yes,yes,yes")])
1875 ;; Subtract 16-bit integers.
1878 (define_expand "subhi3"
1879   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1880         (minus:HI (match_operand:HI 1 "general_operand" "")
1881                   (match_operand:HI 2 "general_operand" "")))]
1882   ""
1883   "if (GET_CODE (operands[2]) == CONST_INT)
1884      {
1885        emit_insn (gen_addhi3 (operands[0], operands[1],
1886                               gen_int_mode (-INTVAL (operands[2]), HImode)));
1887        DONE;
1888      }
1889   ")
1891 (define_insn "*push_subhi3"
1892   [(set (match_operand:HI 0 "push_operand"               "=<,  <")
1893         (minus:HI (match_operand:HI 1 "general_operand" "ron,rSn")
1894                   (match_operand:HI 2 "general_operand" "rSn,ron")))]
1895   ""
1896   "@
1897    push\\t%L1%<\;mov\\tw,%L2\;sub\\t1(SP),w\;push\\t%H1%<\;mov\\tw,%H2\;subc\\t1(SP),w%>%>
1898    push\\t%L1%<\;mov\\tw,%L2\;sub\\t1(SP),w\;push\\t%H1%<\;mov\\tw,%H2\;subc\\t1(SP),w%>%>")
1900 (define_insn "*subhi3_imm"
1901   [(set
1902     (match_operand:HI 0 "nonimmediate_operand"     "=a,a,a,a,do,&r,&ro,&rS")
1903     (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0, 0,ro, rS, ro")
1904               (match_operand 2 "immediate_operand"  "N,M,P,i, i, O,  i,  i")))]
1905   ""
1906   "@
1907    dec\\t%L0
1908    inc\\t%L0
1909    mov\\tw,%2\;sub\\t%L0,w
1910    mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;sub\\t%H0,w
1911    mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w
1912    mov\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w
1913    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w
1914    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w"
1915   [(set_attr "skip" "yes,yes,no,no,no,no,no,no")
1916    (set_attr "clobberw" "no,no,yes,yes,yes,yes,yes,yes")])
1918 (define_insn "*subhi3_ximm_zero_extend"
1919   [(set (match_operand:HI 0 "nonimmediate_operand"            "=ro, rS")
1920         (minus:HI (match_operand:HI 1 "immediate_operand"       "i,  i")
1921                   (zero_extend:HI
1922                     (match_operand:QI 2 "nonimmediate_operand" "rS,roR"))))]
1923   ""
1924   "@
1925    mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;clr\\twreg\;subc\\t%H0,w
1926    mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;clr\\twreg\;subc\\t%H0,w")
1928 (define_insn "*subhi3_ximm"
1929   [(set (match_operand:HI 0 "nonimmediate_operand"         "=&uo,&ro,&rS")
1930         (minus:HI (match_operand:HI 1 "immediate_operand"     "i,  i,  i")
1931                   (match_operand:HI 2 "nonimmediate_operand"  "0, rS, ro")))]
1932   ""
1933   "@
1934    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;push\\t%H2%<\;mov\\tw,%H1\;mov\\t%H0,w\;pop\\twreg%>\;subc\\t%H0,w
1935    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%H2\;subc\\t%H0,w
1936    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%H2\;subc\\t%H0,w")
1938 (define_insn "*subhi3_nonimm_zero_extend"
1939   [(set
1940     (match_operand:HI 0 "nonimmediate_operand" "=a,ro, rS,&ro,&rS,&rS")
1941     (minus:HI
1942      (match_operand:HI 1 "nonimmediate_operand" "0, 0,  0, rS, ro, rS")
1943      (zero_extend:HI
1944       (match_operand:QI 2 "general_operand"   "roR,rS,roR, rS, rS,roR"))))]
1945   ""
1946   "@
1947    mov\\tw,%2\;sub\\t%L0,w
1948    mov\\tw,%2\;sub\\t%L0,w\;clr\\twreg\;subc\\t%H0,w
1949    mov\\tw,%2\;sub\\t%L0,w\;clr\\twreg\;subc\\t%H0,w
1950    mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w
1951    mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w
1952    mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w")
1954 (define_insn "*subhi3_nonimm" ;                   0  1  2   3   4   5  6
1955   [(set
1956     (match_operand:HI 0 "nonimmediate_operand"  "=a,dS, o,&rS,&rS,&rS, o")
1957     (minus:HI
1958      (match_operand:HI 1 "nonimmediate_operand"  "0, 0, 0, ro, ro, rS,rS")
1959      (match_operand:HI 2 "nonimmediate_operand" "ro,ro,rS,  0, rS, ro,rS")))]
1960   ""
1961   "@
1962    mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;sub\\t%H0,w
1963    mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w
1964    mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w
1965    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w
1966    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w
1967    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w
1968    mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w")
1971 ;; Subtract 32-bit integers.
1974 (define_insn "subsi3" ;         0  1   2   3   4   5   6   7   8   9   a   b
1975   [(set
1976     (match_operand:SI
1977      0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&ro,&rS,&rS,&ro,&ro,&rS")
1978     (minus:SI
1979      (match_operand:SI
1980       1 "general_operand"    "0, 0,  0,  0,  i, ro, rS, rS, ro, rS,  i,  i")
1981      (match_operand:SI
1982       2 "general_operand"    "M, N,rSi,roi,  0,  0,  0,roi,rSi,rSi, rS, ro")))]
1983   ""
1984   "*{
1985     switch (which_alternative) {
1986     case 0:
1987       return AS2 (mov, w, #1) CR_TAB
1988              AS2 (add, %D0, w) CR_TAB
1989              AS1 (clr, wreg) CR_TAB
1990              AS2 (addc, %C0, w) CR_TAB
1991              AS2 (addc, %B0, w) CR_TAB
1992              AS2 (addc, %A0, w);
1993       
1994     case 1:
1995       return AS2 (mov, w, #-1) CR_TAB
1996              AS2 (sub, %D0, w) CR_TAB
1997              AS2 (subc, %C0, w) CR_TAB
1998              AS2 (subc, %B0, w) CR_TAB
1999              AS2 (subc, %A0, w);
2000       
2001     case 2:
2002     case 3:
2003       return AS2 (mov, w, %D2) CR_TAB
2004              AS2 (sub, %D0, w) CR_TAB
2005              AS2 (mov, w, %C2) CR_TAB
2006              AS2 (subc, %C0, w) CR_TAB
2007              AS2 (mov, w, %B2) CR_TAB
2008              AS2 (subc, %B0, w) CR_TAB
2009              AS2 (mov, w, %A2) CR_TAB
2010              AS2 (subc, %A0, w);
2012     case 4:
2013       return AS2 (mov, w, %D2) CR_TAB
2014              AS2 (sub, w, %D1) CR_TAB
2015              AS2 (mov, %D0, w) CR_TAB
2016              AS1 (push, %C2%<) CR_TAB
2017              AS2 (mov, w, %C1) CR_TAB
2018              AS2 (mov, %C0, w) CR_TAB
2019              AS1 (pop, wreg%>) CR_TAB
2020              AS2 (subc, %C0, w) CR_TAB
2021              AS1 (push, %B2%<) CR_TAB
2022              AS2 (mov, w, %B1) CR_TAB
2023              AS2 (mov, %B0, w) CR_TAB
2024              AS1 (pop, wreg%>) CR_TAB
2025              AS2 (subc, %B0, w) CR_TAB
2026              AS1 (push, %A2%<) CR_TAB
2027              AS2 (mov, w, %A1) CR_TAB
2028              AS2 (mov, %A0, w) CR_TAB
2029              AS1 (pop, wreg%>) CR_TAB
2030              AS2 (subc, %A0, w);
2032     case 5:
2033     case 6:
2034     case 7:
2035     case 8:
2036     case 9:
2037       return AS2 (mov, w, %D2) CR_TAB
2038              AS2 (sub, w, %D1) CR_TAB
2039              AS2 (mov, %D0, w) CR_TAB
2040              AS2 (mov, w, %C2) CR_TAB
2041              AS2 (subc, w, %C1) CR_TAB
2042              AS2 (mov, %C0, w) CR_TAB
2043              AS2 (mov, w, %B2) CR_TAB
2044              AS2 (subc, w, %B1) CR_TAB
2045              AS2 (mov, %B0, w) CR_TAB
2046              AS2 (mov, w, %A2) CR_TAB
2047              AS2 (subc, w, %A1) CR_TAB
2048              AS2 (mov, %A0, w);
2050     case 10:
2051     case 11:
2052       return AS2 (mov, w, %D2) CR_TAB
2053              AS2 (sub, w, %D1) CR_TAB
2054              AS2 (mov, %D0, w) CR_TAB
2055              AS2 (mov, w, %C1) CR_TAB
2056              AS2 (mov, %C0, w) CR_TAB
2057              AS2 (mov, w, %C2) CR_TAB
2058              AS2 (subc, %C0, w) CR_TAB
2059              AS2 (mov, w, %B1) CR_TAB
2060              AS2 (mov, %B0, w) CR_TAB
2061              AS2 (mov, w, %B2) CR_TAB
2062              AS2 (subc, %B0, w) CR_TAB
2063              AS2 (mov, w, %A1) CR_TAB
2064              AS2 (mov, %A0, w) CR_TAB
2065              AS2 (mov, w, %A2) CR_TAB
2066              AS2 (subc, %A0, w);
2067     default:
2068       abort ();
2069     }
2070   }")
2073 ;; Subtract 64-bit integers.
2076 (define_insn "subdi3" ;         0  1   2   3  4   5   6   7   8   9   a   b
2077   [(set
2078     (match_operand:DI
2079      0 "nonimmediate_operand" "=ro,ro, ro, rS,ro,&rS,&ro,&rS,&rS,&ro,&ro,&rS")
2080     (minus:DI
2081      (match_operand:DI
2082       1 "general_operand"      "0, 0,  0,  0, i, ro, rS, rS, ro, rS,  i,  i")
2083      (match_operand:DI
2084       2 "general_operand"     "M, N,rSi,roi, 0,  0,  0,roi,rSi,rSi, rS, ro")))]
2085   ""
2086   "*{
2087     switch (which_alternative) {
2088     case 0:
2089       return AS2 (mov, w, #1) CR_TAB
2090              AS2 (add, %Z0, w) CR_TAB
2091              AS1 (clr, wreg) CR_TAB
2092              AS2 (addc, %Y0, w) CR_TAB
2093              AS2 (addc, %X0, w) CR_TAB
2094              AS2 (addc, %W0, w) CR_TAB
2095              AS2 (addc, %V0, w) CR_TAB
2096              AS2 (addc, %U0, w) CR_TAB
2097              AS2 (addc, %T0, w) CR_TAB
2098              AS2 (addc, %S0, w);
2099       
2100     case 1:
2101       return AS2 (mov, w, #-1) CR_TAB
2102              AS2 (sub, %Z0, w) CR_TAB
2103              AS2 (subc, %Y0, w) CR_TAB
2104              AS2 (subc, %X0, w) CR_TAB
2105              AS2 (subc, %W0, w) CR_TAB
2106              AS2 (subc, %V0, w) CR_TAB
2107              AS2 (subc, %U0, w) CR_TAB
2108              AS2 (subc, %T0, w) CR_TAB
2109              AS2 (subc, %S0, w);
2110       
2111     case 2:
2112     case 3:
2113       return AS2 (mov, w, %Z2) CR_TAB
2114              AS2 (sub, %Z0, w) CR_TAB
2115              AS2 (mov, w, %Y2) CR_TAB
2116              AS2 (subc, %Y0, w) CR_TAB
2117              AS2 (mov, w, %X2) CR_TAB
2118              AS2 (subc, %X0, w) CR_TAB
2119              AS2 (mov, w, %W2) CR_TAB
2120              AS2 (subc, %W0, w) CR_TAB
2121              AS2 (mov, w, %V2) CR_TAB
2122              AS2 (subc, %V0, w) CR_TAB
2123              AS2 (mov, w, %U2) CR_TAB
2124              AS2 (subc, %U0, w) CR_TAB
2125              AS2 (mov, w, %T2) CR_TAB
2126              AS2 (subc, %T0, w) CR_TAB
2127              AS2 (mov, w, %S2) CR_TAB
2128              AS2 (subc, %S0, w);
2130     case 4:
2131       return AS2 (mov, w, %Z2) CR_TAB
2132              AS2 (sub, w, %Z1) CR_TAB
2133              AS2 (mov, %Z0, w) CR_TAB
2134              AS1 (push, %Y2%<) CR_TAB
2135              AS2 (mov, w, %Y1) CR_TAB
2136              AS2 (mov, %Y0, w) CR_TAB
2137              AS1 (pop, wreg%>) CR_TAB
2138              AS2 (subc, %Y0, w) CR_TAB
2139              AS1 (push, %X2%<) CR_TAB
2140              AS2 (mov, w, %X1) CR_TAB
2141              AS2 (mov, %X0, w) CR_TAB
2142              AS1 (pop, wreg%>) CR_TAB
2143              AS2 (subc, %X0, w) CR_TAB
2144              AS1 (push, %W2%<) CR_TAB
2145              AS2 (mov, w, %W1) CR_TAB
2146              AS2 (mov, %W0, w) CR_TAB
2147              AS1 (pop, wreg%>) CR_TAB
2148              AS2 (subc, %W0, w) CR_TAB
2149              AS1 (push, %V2%<) CR_TAB
2150              AS2 (mov, w, %V1) CR_TAB
2151              AS2 (mov, %V0, w) CR_TAB
2152              AS1 (pop, wreg%>) CR_TAB
2153              AS2 (subc, %V0, w) CR_TAB
2154              AS1 (push, %U2%<) CR_TAB
2155              AS2 (mov, w, %U1) CR_TAB
2156              AS2 (mov, %U0, w) CR_TAB
2157              AS1 (pop, wreg%>) CR_TAB
2158              AS2 (subc, %U0, w) CR_TAB
2159              AS1 (push, %T2%<) CR_TAB
2160              AS2 (mov, w, %T1) CR_TAB
2161              AS2 (mov, %T0, w) CR_TAB
2162              AS1 (pop, wreg%>) CR_TAB
2163              AS2 (subc, %T0, w) CR_TAB
2164              AS1 (push, %S2%<) CR_TAB
2165              AS2 (mov, w, %S1) CR_TAB
2166              AS2 (mov, %S0, w) CR_TAB
2167              AS1 (pop, wreg%>) CR_TAB
2168              AS2 (subc, %S0, w);
2170     case 5:
2171     case 6:
2172     case 7:
2173     case 8:
2174     case 9:
2175       return AS2 (mov, w, %Z2) CR_TAB
2176              AS2 (sub, w, %Z1) CR_TAB
2177              AS2 (mov, %Z0, w) CR_TAB
2178              AS2 (mov, w, %Y2) CR_TAB
2179              AS2 (subc, w, %Y1) CR_TAB
2180              AS2 (mov, %Y0, w) CR_TAB
2181              AS2 (mov, w, %X2) CR_TAB
2182              AS2 (subc, w, %X1) CR_TAB
2183              AS2 (mov, %X0, w) CR_TAB
2184              AS2 (mov, w, %W2) CR_TAB
2185              AS2 (subc, w, %W1) CR_TAB
2186              AS2 (mov, %W0, w) CR_TAB
2187              AS2 (mov, w, %V2) CR_TAB
2188              AS2 (subc, w, %V1) CR_TAB
2189              AS2 (mov, %V0, w) CR_TAB
2190              AS2 (mov, w, %U2) CR_TAB
2191              AS2 (subc, w, %U1) CR_TAB
2192              AS2 (mov, %U0, w) CR_TAB
2193              AS2 (mov, w, %T2) CR_TAB
2194              AS2 (subc, w, %T1) CR_TAB
2195              AS2 (mov, %T0, w) CR_TAB
2196              AS2 (mov, w, %S2) CR_TAB
2197              AS2 (subc, w, %S1) CR_TAB
2198              AS2 (mov, %S0, w);
2200     case 10:
2201     case 11:
2202       return AS2 (mov, w, %Z2) CR_TAB
2203              AS2 (sub, w, %Z1) CR_TAB
2204              AS2 (mov, %Z0, w) CR_TAB
2205              AS2 (mov, w, %Y1) CR_TAB
2206              AS2 (mov, %Y0, w) CR_TAB
2207              AS2 (mov, w, %Y2) CR_TAB
2208              AS2 (subc, %Y0, w) CR_TAB
2209              AS2 (mov, w, %X1) CR_TAB
2210              AS2 (mov, %X0, w) CR_TAB
2211              AS2 (mov, w, %X2) CR_TAB
2212              AS2 (subc, %X0, w) CR_TAB
2213              AS2 (mov, w, %W1) CR_TAB
2214              AS2 (mov, %W0, w) CR_TAB
2215              AS2 (mov, w, %W2) CR_TAB
2216              AS2 (subc, %W0, w) CR_TAB
2217              AS2 (mov, w, %V1) CR_TAB
2218              AS2 (mov, %V0, w) CR_TAB
2219              AS2 (mov, w, %V2) CR_TAB
2220              AS2 (subc, %V0, w) CR_TAB
2221              AS2 (mov, w, %U1) CR_TAB
2222              AS2 (mov, %U0, w) CR_TAB
2223              AS2 (mov, w, %U2) CR_TAB
2224              AS2 (subc, %U0, w) CR_TAB
2225              AS2 (mov, w, %T1) CR_TAB
2226              AS2 (mov, %T0, w) CR_TAB
2227              AS2 (mov, w, %T2) CR_TAB
2228              AS2 (subc, %T0, w) CR_TAB
2229              AS2 (mov, w, %S1) CR_TAB
2230              AS2 (mov, %S0, w) CR_TAB
2231              AS2 (mov, w, %S2) CR_TAB
2232              AS2 (subc, %S0, w);
2233     default:
2234       abort ();
2235     }
2236   }")
2239 ;; Bitwise and instructions.
2242 (define_expand "andqi3"
2243   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2244         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
2245                 (match_operand:QI 2 "general_operand" "")))]
2246   ""
2247   "")
2249 (define_insn "*andqi3_bit"
2250   [(set (match_operand:QI 0 "nonimmediate_operand"       "=roR")
2251         (and:QI (match_dup 0)
2252                 (match_operand:QI 1 "const_int_operand"     "n")))]
2253   "(find_one_clear_bit_p (INTVAL (operands[1]) | 0xffffff00UL) != -1)"
2254   "*{
2255     operands[2] = GEN_INT (find_one_clear_bit_p (INTVAL (operands[1])
2256                                                  | 0xffffff00UL));
2257     return AS2 (clrb, %0, %b2);
2258   }"
2259   [(set_attr "skip" "yes")
2260    (set_attr "clobberw" "no")])
2262 (define_insn "*andqi3_w_fr"
2263   [(set (reg:QI 10)
2264         (and:QI (match_operand:QI 0 "general_operand" "roRn")
2265                 (reg:QI 10)))]
2266   "(ip2k_reorg_split_qimode)"
2267   "and\\tw,%0"
2268   [(set_attr "skip" "yes")])
2270 (define_insn_and_split "*andqi3_fr_w"
2271   [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,rS,roR, rS,rS")
2272         (and:QI
2273          (match_operand:QI 1 "nonimmediate_operand"  "%0, 0, rS,roR,rS")
2274          (reg:QI 10)))]
2275   "(ip2k_reorg_split_qimode)"
2276   "@
2277    and\\t%0,w
2278    and\\t%0,w
2279    # 
2280    #
2281    #"
2282   "(ip2k_reorg_split_qimode
2283     && ! rtx_equal_p (operands[0], operands[1]))"
2284   [(set (reg:QI 10)
2285         (and:QI (match_dup 1)
2286                 (reg:QI 10)))
2287    (set (match_dup 0)
2288         (reg:QI 10))]
2289   ""
2290   [(set_attr "skip" "yes,yes,no,no,no")
2291    (set_attr "clobberw" "no,no,yes,yes,yes")])
2293 (define_insn_and_split "*andqi3" ;                    0    1   2   3    4
2294   [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,  rS,roR, rS,  rS")
2295         (and:QI
2296          (match_operand:QI 1 "nonimmediate_operand"  "%0,   0, rS,roR,  rS")
2297          (match_operand:QI 2 "general_operand"      "rSn,roRn,rSn,rSn,roRn")))]
2298   ""
2299   "@
2300    mov\\tw,%2\;and\\t%0,w
2301    #
2302    #
2303    #
2304    #"
2305   "(ip2k_reorg_split_qimode
2306     && (! rtx_equal_p (operands[0], operands[1])
2307         || GET_CODE (operands[2]) != CONST_INT
2308         || find_one_clear_bit_p (INTVAL (operands[2]) | 0xffffff00UL) == -1))"
2309   [(set (reg:QI 10)
2310         (match_dup 2))
2311    (set (match_dup 0)
2312         (and:QI (match_dup 1)
2313                 (reg:QI 10)))])
2315 (define_insn_and_split "andhi3" ;                      0   1   2   3   4
2316   [(set (match_operand:HI 0 "nonimmediate_operand"  "=uo, uS,&dS,&do,&dS")
2317         (and:HI
2318          (match_operand:HI 1 "nonimmediate_operand"  "%0,  0, ro, rS, rS")
2319          (match_operand:HI 2 "general_operand"      "rSn,ron,rSn,rSn,ron")))]
2320   ""
2321   "#"
2322   "(ip2k_reorg_split_himode)"
2323   [(set (match_dup 3)
2324         (and:QI (match_dup 4)
2325                 (match_dup 5)))
2326    (set (match_dup 6)
2327         (and:QI (match_dup 7)
2328                 (match_dup 8)))]
2329   "{
2330     operands[3] = ip2k_get_high_half (operands[0], QImode);
2331     operands[4] = ip2k_get_high_half (operands[1], QImode);
2332     operands[5] = ip2k_get_high_half (operands[2], QImode);
2333     operands[6] = ip2k_get_low_half (operands[0], QImode);
2334     operands[7] = ip2k_get_low_half (operands[1], QImode);
2335     operands[8] = ip2k_get_low_half (operands[2], QImode);
2336   }")
2338 (define_insn_and_split "andsi3" ;                    0   1   2   3   4
2339   [(set (match_operand:SI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS")
2340         (and:SI
2341          (match_operand:SI 1 "nonimmediate_operand" "%0,  0, ro, rS, rS")
2342          (match_operand:SI 2 "general_operand"      "rSn,ron,rSn,rSn,ron")))]
2343   ""
2344   "#"
2345   "(ip2k_reorg_split_simode)"
2346   [(set (match_dup 3)
2347         (and:HI (match_dup 4)
2348                 (match_dup 5)))
2349    (set (match_dup 6)
2350         (and:HI (match_dup 7)
2351                 (match_dup 8)))]
2352   "{
2353     operands[3] = ip2k_get_high_half (operands[0], HImode);
2354     operands[4] = ip2k_get_high_half (operands[1], HImode);
2355     operands[5] = ip2k_get_high_half (operands[2], HImode);
2356     operands[6] = ip2k_get_low_half (operands[0], HImode);
2357     operands[7] = ip2k_get_low_half (operands[1], HImode);
2358     operands[8] = ip2k_get_low_half (operands[2], HImode);
2359   }")
2361 (define_insn_and_split "anddi3" ;                     0   1   2   3   4
2362   [(set (match_operand:DI 0 "nonimmediate_operand"  "=uo, uS,&dS,&do,&dS")
2363         (and:DI
2364          (match_operand:DI 1 "nonimmediate_operand"  "%0,  0, ro, rS, rS")
2365          (match_operand:DI 2 "general_operand"      "rSn,ron,rSn,rSn,ron")))]
2366   ""
2367   "#"
2368   "(ip2k_reorg_split_dimode)"
2369   [(set (match_dup 3)
2370         (and:SI (match_dup 4)
2371                 (match_dup 5)))
2372    (set (match_dup 6)
2373         (and:SI (match_dup 7)
2374                 (match_dup 8)))]
2375   "{
2376     operands[3] = ip2k_get_high_half (operands[0], SImode);
2377     operands[4] = ip2k_get_high_half (operands[1], SImode);
2378     operands[5] = ip2k_get_high_half (operands[2], SImode);
2379     operands[6] = ip2k_get_low_half (operands[0], SImode);
2380     operands[7] = ip2k_get_low_half (operands[1], SImode);
2381     operands[8] = ip2k_get_low_half (operands[2], SImode);
2382   }")
2385 ;; Bitwise or instructions.
2388 (define_expand "iorqi3"
2389   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2390         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
2391                 (match_operand:QI 2 "general_operand" "")))]
2392   ""
2393   "")
2395 (define_insn "*iorqi3_bit"
2396   [(set (match_operand:QI 0 "nonimmediate_operand"       "=roR")
2397         (ior:QI (match_dup 0)
2398                 (match_operand:QI 1 "const_int_operand"     "n")))]
2399   "(find_one_set_bit_p (INTVAL (operands[1]) & 0xff) != -1)"
2400   "*{
2401     operands[2] = GEN_INT (find_one_set_bit_p (INTVAL (operands[1]) & 0xff));
2402     return AS2 (setb, %0, %b2);
2403   }"
2404   [(set_attr "skip" "yes")
2405    (set_attr "clobberw" "no")])
2407 (define_insn "*iorqi3" ;                              0    1   2   3    4
2408   [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,  rS,roR, rS,  rS")
2409         (ior:QI
2410          (match_operand:QI 1 "nonimmediate_operand"  "%0,   0, rS,roR,  rS")
2411          (match_operand:QI 2 "general_operand"      "rSi,roRi,rSi,rSi,roRi")))]
2412   ""
2413   "@
2414    mov\\tw,%2\;or\\t%0,w
2415    mov\\tw,%2\;or\\t%0,w
2416    mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w
2417    mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w
2418    mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w")
2420 (define_insn_and_split "iorhi3" ;                    0   1   2   3   4
2421   [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS")
2422         (ior:HI
2423          (match_operand:HI 1 "nonimmediate_operand" "%0,  0, ro, rS, rS")
2424          (match_operand:HI 2 "general_operand"     "rSn,ron,rSn,rSn,ron")))]
2425   ""
2426   "#"
2427   "(ip2k_reorg_split_himode)"
2428   [(set (match_dup 3)
2429         (ior:QI (match_dup 4)
2430                 (match_dup 5)))
2431    (set (match_dup 6)
2432         (ior:QI (match_dup 7)
2433                 (match_dup 8)))]
2434   "{
2435     operands[3] = ip2k_get_high_half (operands[0], QImode);
2436     operands[4] = ip2k_get_high_half (operands[1], QImode);
2437     operands[5] = ip2k_get_high_half (operands[2], QImode);
2438     operands[6] = ip2k_get_low_half (operands[0], QImode);
2439     operands[7] = ip2k_get_low_half (operands[1], QImode);
2440     operands[8] = ip2k_get_low_half (operands[2], QImode);
2441   }")
2443 (define_insn_and_split "iorsi3" ;                     0   1   2   3   4
2444   [(set (match_operand:SI 0 "nonimmediate_operand"  "=uo, uS,&dS,&do,&dS")
2445         (ior:SI
2446          (match_operand:SI 1 "nonimmediate_operand"  "%0,  0, ro, rS, rS")
2447          (match_operand:SI 2 "general_operand"      "rSn,ron,rSn,rSn,ron")))]
2448   ""
2449   "#"
2450   "(ip2k_reorg_split_simode)"
2451   [(set (match_dup 3)
2452         (ior:HI (match_dup 4)
2453                 (match_dup 5)))
2454    (set (match_dup 6)
2455         (ior:HI (match_dup 7)
2456                 (match_dup 8)))]
2457   "{
2458     operands[3] = ip2k_get_high_half (operands[0], HImode);
2459     operands[4] = ip2k_get_high_half (operands[1], HImode);
2460     operands[5] = ip2k_get_high_half (operands[2], HImode);
2461     operands[6] = ip2k_get_low_half (operands[0], HImode);
2462     operands[7] = ip2k_get_low_half (operands[1], HImode);
2463     operands[8] = ip2k_get_low_half (operands[2], HImode);
2464   }")
2466 (define_insn_and_split "iordi3" ;                     0   1   2   3   4
2467   [(set (match_operand:DI 0 "nonimmediate_operand"  "=uo, uS,&dS,&do,&dS")
2468         (ior:DI
2469          (match_operand:DI 1 "nonimmediate_operand"  "%0,  0, ro, rS, rS")
2470          (match_operand:DI 2 "general_operand"      "rSn,ron,rSn,rSn,ron")))]
2471   ""
2472   "#"
2473   "(ip2k_reorg_split_dimode)"
2474   [(set (match_dup 3)
2475         (ior:SI (match_dup 4)
2476                 (match_dup 5)))
2477    (set (match_dup 6)
2478         (ior:SI (match_dup 7)
2479                 (match_dup 8)))]
2480   "{
2481     operands[3] = ip2k_get_high_half (operands[0], SImode);
2482     operands[4] = ip2k_get_high_half (operands[1], SImode);
2483     operands[5] = ip2k_get_high_half (operands[2], SImode);
2484     operands[6] = ip2k_get_low_half (operands[0], SImode);
2485     operands[7] = ip2k_get_low_half (operands[1], SImode);
2486     operands[8] = ip2k_get_low_half (operands[2], SImode);
2487   }")
2490 ;; Bitwise xor instructions
2492 ;; TODO: xor ops can also use "not w, fr"!
2495 (define_insn "xorqi3"
2496   [(set
2497     (match_operand:QI 0 "nonimmediate_operand"  "=roR,roR,  rS,roR, rS,  rS")
2498     (xor:QI (match_operand:QI 1 "general_operand" "%0,  0,   0, rS,roR,  rS")
2499             (match_operand:QI 2 "general_operand" "M,rSi,roRi,rSi,rSi,roRi")))]
2500   ""
2501   "@
2502    not\\t%0
2503    mov\\tw,%2\;xor\\t%0,w
2504    mov\\tw,%2\;xor\\t%0,w
2505    mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w
2506    mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w
2507    mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w"
2508   [(set_attr "clobberw" "no,yes,yes,yes,yes,yes")])
2510 (define_insn_and_split "xorhi3" ;                    0   1   2   3   4
2511   [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS")
2512         (xor:HI
2513          (match_operand:HI 1 "nonimmediate_operand" "%0,  0, ro, rS, rS")
2514          (match_operand:HI 2 "general_operand"     "rSn,ron,rSn,rSn,ron")))]
2515   ""
2516   "#"
2517   "(ip2k_reorg_split_himode)"
2518   [(set (match_dup 3)
2519         (xor:QI (match_dup 4)
2520                 (match_dup 5)))
2521    (set (match_dup 6)
2522         (xor:QI (match_dup 7)
2523                 (match_dup 8)))]
2524   "{
2525     operands[3] = ip2k_get_high_half (operands[0], QImode);
2526     operands[4] = ip2k_get_high_half (operands[1], QImode);
2527     operands[5] = ip2k_get_high_half (operands[2], QImode);
2528     operands[6] = ip2k_get_low_half (operands[0], QImode);
2529     operands[7] = ip2k_get_low_half (operands[1], QImode);
2530     operands[8] = ip2k_get_low_half (operands[2], QImode);
2531   }")
2533 (define_insn_and_split "xorsi3" ;                    0   1   2   3   4
2534   [(set (match_operand:SI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS")
2535         (xor:SI
2536          (match_operand:SI 1 "nonimmediate_operand" "%0,  0, ro, rS, rS")
2537          (match_operand:SI 2 "general_operand"     "rSn,ron,rSn,rSn,ron")))]
2538   ""
2539   "#"
2540   "(ip2k_reorg_split_simode)"
2541   [(set (match_dup 3)
2542         (xor:HI (match_dup 4)
2543                 (match_dup 5)))
2544    (set (match_dup 6)
2545         (xor:HI (match_dup 7)
2546                 (match_dup 8)))]
2547   "{
2548     operands[3] = ip2k_get_high_half (operands[0], HImode);
2549     operands[4] = ip2k_get_high_half (operands[1], HImode);
2550     operands[5] = ip2k_get_high_half (operands[2], HImode);
2551     operands[6] = ip2k_get_low_half (operands[0], HImode);
2552     operands[7] = ip2k_get_low_half (operands[1], HImode);
2553     operands[8] = ip2k_get_low_half (operands[2], HImode);
2554   }")
2556 (define_insn_and_split "xordi3" ;                    0   1   2   3   4
2557   [(set (match_operand:DI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS")
2558         (xor:DI
2559          (match_operand:DI 1 "nonimmediate_operand" "%0,  0, ro, rS, rS")
2560          (match_operand:DI 2 "general_operand"     "rSn,ron,rSn,rSn,ron")))]
2561   ""
2562   "#"
2563   "(ip2k_reorg_split_dimode)"
2564   [(set (match_dup 3)
2565         (xor:SI (match_dup 4)
2566                 (match_dup 5)))
2567    (set (match_dup 6)
2568         (xor:SI (match_dup 7)
2569                 (match_dup 8)))]
2570   "{
2571     operands[3] = ip2k_get_high_half (operands[0], SImode);
2572     operands[4] = ip2k_get_high_half (operands[1], SImode);
2573     operands[5] = ip2k_get_high_half (operands[2], SImode);
2574     operands[6] = ip2k_get_low_half (operands[0], SImode);
2575     operands[7] = ip2k_get_low_half (operands[1], SImode);
2576     operands[8] = ip2k_get_low_half (operands[2], SImode);
2577   }")
2580 ;; Multiply instructions.
2583 (define_insn "umulqi3"
2584   [(set (match_operand:QI 0 "nonimmediate_operand"          "=ro, rS,  rS")
2585         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%rS,roR,  rS")
2586                  (match_operand:QI 2 "general_operand"      "rSi,rSi,roRi")))]
2587   ""
2588   "mov\\tw,%1\;mulu\\tw,%2\;mov\\t%0,w")
2590 (define_insn "mulqihi3"
2591   [(set (match_operand:HI 0 "nonimmediate_operand"   "=ro, rS,  rS")
2592         (mult:HI
2593          (sign_extend:HI
2594           (match_operand:QI 1 "nonimmediate_operand" "%rS,roR,  rS"))
2595          (sign_extend:HI
2596           (match_operand:QI 2 "general_operand"      "rSi,rSi,roRi"))))]
2597   ""
2598   "@
2599    mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w
2600    mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w
2601    mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w")
2603 (define_insn_and_split "umulqihi3"
2604   [(set (match_operand:HI 0 "nonimmediate_operand"          "=ro, rS,  rS")
2605         (mult:HI (zero_extend:HI
2606                   (match_operand:QI 1 "nonimmediate_operand" "%rS,roR,  rS"))
2607                  (zero_extend:HI
2608                   (match_operand:QI 2 "general_operand"     "rSi,rSi,roRi"))))]
2609   ""
2610   "#"
2611   "ip2k_reorg_split_qimode"
2612   [(set (match_dup 3)
2613         (mult:QI (match_dup 1)
2614                  (match_dup 2)))
2615    (set (reg:QI 10)
2616         (reg:QI 15))
2617    (set (match_dup 4)
2618         (reg:QI 10))]
2619   "{
2620     operands[3] = ip2k_get_low_half (operands[0], QImode);
2621     operands[4] = ip2k_get_high_half (operands[0], QImode);
2622   }")
2624 (define_insn "*mulhi3_by2"
2625   [(set (match_operand:HI 0 "nonimmediate_operand"         "=ro,&ro,&rS")
2626         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "0, rS, ro")
2627                  (zero_extend:HI (const_int 2))))]
2628   ""
2629   "@
2630    clrb\\tSTATUS,0\;rl\\t%L0\;rl\\t%H0
2631    clrb\\tSTATUS,0\;rl\\tw,%L1\;mov\\t%L0,w\;rl\\tw,%H1\;mov\\t%H0,w
2632    clrb\\tSTATUS,0\;rl\\tw,%L1\;mov\\t%L0,w\;rl\\tw,%H1\;mov\\t%H0,w"
2633   [(set_attr "clobberw" "no,yes,yes")])
2635 (define_insn "*mulhi3_byqi"
2636   [(set (match_operand:HI
2637          0 "nonimmediate_operand"                     "=ro,&ro,&rS, &rS")
2638         (mult:HI (match_operand:HI
2639                   1 "nonimmediate_operand"              "0, rS, ro,  rS")
2640                  (zero_extend:HI (match_operand:QI
2641                                   2 "general_operand" "rSi,rSi,rSi,roRi"))))]
2642   ""
2643   "@
2644    mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;push\\tmulh%<\;mov\\tw,%H1\;mulu\\tw,%2\;pop\\t%H0%>\;add\\t%H0,w
2645    mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w
2646    mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w
2647    mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w")
2649 (define_insn "smulqi_highpart"
2650   [(set (match_operand:QI 0 "nonimmediate_operand"      "=roR, rS,  rS")
2651         (truncate:QI
2652           (lshiftrt:HI
2653             (mult:HI
2654              (sign_extend:HI
2655               (match_operand:QI 1 "nonimmediate_operand" "%rS,roR,  rS"))
2656              (sign_extend:HI
2657               (match_operand:QI 2 "general_operand"      "rSi,rSi,roRi")))
2658             (const_int 8))))]
2659   ""
2660   "@
2661    mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w
2662    mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w
2663    mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w")
2665 (define_insn "umulqi_highpart"
2666   [(set (match_operand:QI 0 "nonimmediate_operand"      "=roR, rS,  rS")
2667         (truncate:QI
2668           (lshiftrt:HI
2669             (mult:HI
2670              (zero_extend:HI
2671               (match_operand:QI 1 "nonimmediate_operand" "%rS,roR,  rS"))
2672              (zero_extend:HI
2673               (match_operand:QI 2 "general_operand"      "rSi,rSi,roRi")))
2674             (const_int 8))))]
2675   ""
2676   "@
2677    mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w
2678    mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w
2679    mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w")
2681 (define_insn "mulhi3"
2682   [(set (match_operand:HI 0 "nonimmediate_operand"          "=uo, uS, uS")
2683         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rS, ro, rS")
2684                  (match_operand:HI 2 "general_operand"      "rSi,rSi,roi")))]
2685   ""
2686   "push\\t%L2%<\;push\\t%H2%<\;push\\t%L1%<\;push\\t%H1%>\;page\\t__mulhi3\;call\\t__mulhi3\;pop\\t%H0%>\;pop\\t%L0%>")
2688 ;; If we find that we're multiplying by a constant that's less than 256 we
2689 ;; can replace a full "mulhi3" with one of the lighter weight variants
2690 ;; that multiplies an HImode value by a QImode one.
2692 (define_split
2693   [(set (match_operand:HI 0 "nonimmediate_operand"         "=ro,rS")
2694         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro")
2695                  (match_operand:HI 2 "const_int_operand"     "P, P")))]
2696   "(INTVAL (operands[2]) < 0x100)"
2697   [(set (match_dup 0)
2698         (mult:HI (match_dup 1)
2699                  (zero_extend:HI (match_dup 3))))]
2700   "operands[3] = gen_int_mode (INTVAL (operands[2]), QImode);")
2703 ;; Divide/Modulus functions.
2706 (define_expand "udivmodhi4"
2707   [(parallel [(set (reg:HI 128)
2708                    (udiv:HI (match_operand:HI 1 "general_operand" "")
2709                             (match_operand:HI 2 "general_operand" "")))
2710               (set (reg:HI 130)
2711                    (umod:HI (match_dup 1) (match_dup 2)))
2712               (clobber (reg:QI 132))
2713               (clobber (reg:QI 133))])
2714    (set (match_operand:HI 0 "general_operand" "") (reg:HI 128))
2715    (set (match_operand:HI 3 "general_operand" "") (reg:HI 130))]
2716   ""
2717   "")
2719 (define_insn "*udivmodhi4_call"
2720   [(set (reg:HI 128)
2721         (udiv:HI (match_operand:HI 0 "general_operand" "uSi,uoi")
2722                  (match_operand:HI 1 "general_operand" "uoi,uSi")))
2723    (set (reg:HI 130)
2724         (umod:HI (match_dup 0) (match_dup 1)))
2725    (clobber (reg:QI 132))
2726    (clobber (reg:QI 133))]
2727   ""
2728   "push\\t%L1%<\;push\\t%H1%<\;push\\t%L0%<\;push\\t%H0%>%>%>\;page\\t__udivmodhi4\;call\\t__udivmodhi4")
2730 (define_expand "divmodhi4"
2731   [(parallel [(set (reg:HI 128)
2732                    (div:HI (match_operand:HI 1 "general_operand" "")
2733                            (match_operand:HI 2 "general_operand" "")))
2734               (set (reg:HI 130)
2735                    (mod:HI (match_dup 1)
2736                            (match_dup 2)))
2737               (clobber (reg:QI 132))
2738               (clobber (reg:QI 133))
2739               (clobber (reg:QI 134))
2740               (clobber (reg:QI 135))])
2741    (set (match_operand:HI 0 "general_operand" "") (reg:HI 128))
2742    (set (match_operand:HI 3 "general_operand" "") (reg:HI 130))]
2743   ""
2744   "")
2746 (define_insn "*divmodhi4_call"
2747   [(set (reg:HI 128)
2748         (div:HI (match_operand:HI 0 "general_operand" "uSi,uoi")
2749                 (match_operand:HI 1 "general_operand" "uoi,uSi")))
2750    (set (reg:HI 130)
2751         (mod:HI (match_dup 0) (match_dup 1)))
2752    (clobber (reg:QI 132))
2753    (clobber (reg:QI 133))
2754    (clobber (reg:QI 134))
2755    (clobber (reg:QI 135))]
2756   ""
2757   "push\\t%L1%<\;push\\t%H1%<\;push\\t%L0%<\;push\\t%H0%>%>%>\;page\\t__divmodhi4\;call\\t__divmodhi4")
2759 (define_expand "udivmodsi4"
2760   [(parallel [(set (reg:SI 128)
2761                    (udiv:SI (match_operand:SI 1 "general_operand" "")
2762                             (match_operand:SI 2 "general_operand" "")))
2763               (set (reg:SI 132)
2764                    (umod:SI (match_dup 1)
2765                             (match_dup 2)))
2766               (clobber (reg:QI 136))
2767               (clobber (reg:QI 137))
2768               (clobber (reg:QI 138))
2769               (clobber (reg:QI 139))])
2770    (set (match_operand:SI 0 "general_operand" "") (reg:SI 128))
2771    (set (match_operand:SI 3 "general_operand" "") (reg:SI 132))]
2772   ""
2773   "")
2775 (define_insn "*udivmodsi4_call"
2776   [(set (reg:SI 128)
2777         (udiv:SI (match_operand:SI 0 "general_operand" "rSi,roi")
2778                  (match_operand:SI 1 "general_operand" "roi,rSi")))
2779    (set (reg:SI 132)
2780         (umod:SI (match_dup 0)
2781                  (match_dup 1)))
2782    (clobber (reg:QI 136))
2783    (clobber (reg:QI 137))
2784    (clobber (reg:QI 138))
2785    (clobber (reg:QI 139))]
2786   ""
2787   "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;push\\t%D0%<\;push\\t%C0%<\;push\\t%B0%<\;push\\t%A0%>%>%>%>%>%>%>\;page\\t__udivmodsi4\;call\\t__udivmodsi4")
2789 (define_expand "divmodsi4"
2790   [(parallel [(set (reg:SI 128)
2791                    (div:SI (match_operand:SI 1 "general_operand" "")
2792                            (match_operand:SI 2 "general_operand" "")))
2793               (set (reg:SI 132)
2794                    (mod:SI (match_dup 1)
2795                            (match_dup 2)))
2796               (clobber (reg:QI 136))
2797               (clobber (reg:QI 137))
2798               (clobber (reg:QI 138))
2799               (clobber (reg:QI 139))
2800               (clobber (reg:QI 140))
2801               (clobber (reg:QI 141))])
2802    (set (match_operand:SI 0 "general_operand" "") (reg:SI 128))
2803    (set (match_operand:SI 3 "general_operand" "") (reg:SI 132))]
2804   ""
2805   "")
2807 (define_insn "*divmodsi4_call"
2808   [(set (reg:SI 128)
2809         (div:SI (match_operand:SI 0 "general_operand" "rSn,ron")
2810                 (match_operand:SI 1 "general_operand" "ron,rSn")))
2811    (set (reg:SI 132)
2812         (mod:SI (match_dup 0)
2813                 (match_dup 1)))
2814    (clobber (reg:QI 136))
2815    (clobber (reg:QI 137))
2816    (clobber (reg:QI 138))
2817    (clobber (reg:QI 139))
2818    (clobber (reg:QI 140))
2819    (clobber (reg:QI 141))]
2820   ""
2821   "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;push\\t%D0%<\;push\\t%C0%<\;push\\t%B0%<\;push\\t%A0%>%>%>%>%>%>%>\;page\\t__divmodsi4\;call\\t__divmodsi4")
2823 (define_expand "udivmoddi4"
2824   [(parallel [(set (reg:DI 128)
2825                    (udiv:DI (match_operand:DI 1 "general_operand" "")
2826                             (match_operand:DI 2 "general_operand" "")))
2827               (set (reg:DI 136)
2828                    (umod:DI (match_dup 1)
2829                             (match_dup 2)))
2830               (clobber (reg:QI 144))
2831               (clobber (reg:QI 145))
2832               (clobber (reg:QI 146))
2833               (clobber (reg:QI 147))
2834               (clobber (reg:QI 148))
2835               (clobber (reg:QI 149))
2836               (clobber (reg:QI 150))
2837               (clobber (reg:QI 151))])
2838    (set (match_operand:DI 0 "general_operand" "") (reg:DI 128))
2839    (set (match_operand:DI 3 "general_operand" "") (reg:DI 136))]
2840   ""
2841   "")
2843 (define_insn "*udivmoddi4_call"
2844   [(set (reg:DI 128)
2845         (udiv:DI (match_operand:DI 0 "general_operand" "rSi,roi")
2846                  (match_operand:DI 1 "general_operand" "roi,rSi")))
2847    (set (reg:DI 136)
2848         (umod:DI (match_dup 0)
2849                  (match_dup 1)))
2850    (clobber (reg:QI 144))
2851    (clobber (reg:QI 145))
2852    (clobber (reg:QI 146))
2853    (clobber (reg:QI 147))
2854    (clobber (reg:QI 148))
2855    (clobber (reg:QI 149))
2856    (clobber (reg:QI 150))
2857    (clobber (reg:QI 151))]
2858   ""
2859   "push\\t%Z1%<\;push\\t%Y1%<\;push\\t%X1%<\;push\\t%W1%<\;push\\t%V1%<\;push\\t%U1%<\;push\\t%T1%<\;push\\t%S1%<\;push\\t%Z0%<\;push\\t%Y0%<\;push\\t%X0%<\;push\\t%W0%<\;push\\t%V0%<\;push\\t%U0%<\;push\\t%T0%<\;push\\t%S00%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>\;page\\t__udivmoddi4\;call\\t__udivmoddi4")
2861 (define_expand "divmoddi4"
2862   [(parallel [(set (reg:DI 128)
2863                    (div:DI (match_operand:DI 1 "general_operand" "")
2864                            (match_operand:DI 2 "general_operand" "")))
2865               (set (reg:DI 136)
2866                    (mod:DI (match_dup 1)
2867                            (match_dup 2)))
2868               (clobber (reg:QI 144))
2869               (clobber (reg:QI 145))
2870               (clobber (reg:QI 146))
2871               (clobber (reg:QI 147))
2872               (clobber (reg:QI 148))
2873               (clobber (reg:QI 149))
2874               (clobber (reg:QI 150))
2875               (clobber (reg:QI 151))])
2876    (set (match_operand:DI 0 "general_operand" "") (reg:DI 128))
2877    (set (match_operand:DI 3 "general_operand" "") (reg:DI 136))]
2878   ""
2879   "")
2881 (define_insn "*divmoddi4_call"
2882   [(set (reg:DI 128)
2883         (div:DI (match_operand:DI 0 "general_operand" "rSn,ron")
2884                 (match_operand:DI 1 "general_operand" "ron,rSn")))
2885    (set (reg:DI 136)
2886         (mod:DI (match_dup 0)
2887                 (match_dup 1)))
2888    (clobber (reg:QI 144))
2889    (clobber (reg:QI 145))
2890    (clobber (reg:QI 146))
2891    (clobber (reg:QI 147))
2892    (clobber (reg:QI 148))
2893    (clobber (reg:QI 149))
2894    (clobber (reg:QI 150))
2895    (clobber (reg:QI 151))]
2896   ""
2897   "push\\t%Z1%<\;push\\t%Y1%<\;push\\t%X1%<\;push\\t%W1%<\;push\\t%V1%<\;push\\t%U1%<\;push\\t%T1%<\;push\\t%S1%<\;push\\t%Z0%<\;push\\t%Y0%<\;push\\t%X0%<\;push\\t%W0%<\;push\\t%V0%<\;push\\t%U0%<\;push\\t%T0%<\;push\\t%S00%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>\;page\\t__divmoddi4\;call\\t__divmoddi4")
2900 ;; Arithmetic shift left instructions.
2903 (define_insn "ashlqi3"
2904   [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,roR, rS,roR, rS")
2905         (ashift:QI
2906          (match_operand:QI 1 "nonimmediate_operand"   "0, rS,roR,  0,  0")
2907          (match_operand:QI 2 "general_operand"        "N,  L,  L, rS,roR")))]
2908   ""
2909   "@
2910    clrb status,0\;rl\\t%0
2911    mov\\tw,%e2\;mulu\\tw,%1\;mov\\t%0,w
2912    mov\\tw,%e2\;mulu\\tw,%1\;mov\\t%0,w
2913    mov\\tw,%2\;snz\;page\\t1f\;jmp\\t1f\;2:clrb\\tstatus,0\;rl\\t%0\;decsz\\twreg\;page\\t2b\;jmp\\t2b\;1:
2914    mov\\tw,%2\;snz\;page\\t1f\;jmp\\t1f\;2:clrb\\tstatus,0\;rl\\t%0\;decsz\\twreg\;page\\t2b\;jmp\\t2b\;1:"
2915   [(set_attr "clobberw" "no,yes,yes,yes,yes")])
2917 ;; Convert simple fixed-size shift of a zero-extended QImode value into a
2918 ;; multiply as our multiplier is much faster.  We also do this so that the
2919 ;;  multiply can possibly be merged into a much faster multiply-and-accumulate
2920 ;; operation.
2922 (define_split
2923   [(set (match_operand:HI 0 "nonimmediate_operand"              "=ro, rS")
2924         (ashift:HI (zero_extend:HI
2925                       (match_operand:QI 1 "nonimmediate_operand" "rS,roR"))
2926                    (match_operand:QI 2 "const_int_operand"        "J,  J")))]
2927   "(INTVAL (operands[2]) < 8)"
2928   [(set (match_dup 0)
2929         (mult:HI (zero_extend:HI (match_dup 1))
2930                  (zero_extend:HI (match_dup 3))))]
2931   "operands[3] = gen_int_mode (1 << INTVAL (operands[2]), QImode);")
2933 (define_insn_and_split "*ashlhi3_by8_zero_extend"
2934   [(set (match_operand:HI 0 "nonimmediate_operand"              "=ro, rS")
2935         (ashift:HI (zero_extend:HI
2936                       (match_operand:QI 1 "nonimmediate_operand" "rS,roR"))
2937                    (const_int 8)))]
2938   ""
2939   "#"
2940   "reload_completed"
2941   [(set (match_dup 2) (match_dup 1))
2942    (set (match_dup 3) (const_int 0))]
2943   "{
2944     operands[2] = ip2k_get_high_half (operands[0], QImode);
2945     operands[3] = ip2k_get_low_half (operands[0], QImode);
2946   }")
2948 (define_insn "*ashlhi3_zero_extend" ;                              0   1
2949   [(set (match_operand:HI 0 "nonimmediate_operand"              "=ro, rS")
2950         (ashift:HI (zero_extend:HI
2951                       (match_operand:QI 1 "nonimmediate_operand" "rS,roR"))
2952                    (match_operand:QI 2 "const_int_operand"        "n,  n")))]
2953   ""
2954   "*{
2955     if (INTVAL (operands[2]) < 8)
2956       return AS2 (mov, w, %1) CR_TAB
2957              AS2 (mulu, w, %e2) CR_TAB
2958              AS2 (mov, %L0, w) CR_TAB
2959              AS2 (mov, w, MULH) CR_TAB
2960              AS2 (mov, %H0, w);
2961     else
2962       {
2963         operands[3] = GEN_INT (INTVAL (operands[2]) - 8);
2964         return AS2 (mov, w, %1) CR_TAB
2965                AS2 (mulu, w, %e3) CR_TAB
2966                AS2 (mov, %H0, w) CR_TAB
2967                AS1 (clr, %L0);
2968       }
2969   }")
2971 ;; Convert simple fixed-size shift of a HImode value into a multiply as
2972 ;; our multiplier is much faster.  We also do this so that the multiply can
2973 ;; possibly be merged into a much faster multiply-and-accumulate operation.
2975 (define_split
2976   [(set (match_operand:HI 0 "nonimmediate_operand"           "=ro,rS")
2977         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro")
2978                    (match_operand:QI 2 "const_int_operand"     "J, J")))]
2979   "(INTVAL (operands[2]) < 8)"
2980   [(set (match_dup 0)
2981         (mult:HI (match_dup 1)
2982                  (zero_extend:HI (match_dup 3))))]
2983   "operands[3] = gen_int_mode (1 << INTVAL (operands[2]), QImode);")
2985 (define_insn_and_split "ashlhi3_split"
2986   [(set (match_operand:HI 0 "nonimmediate_operand"           "=ro,rS")
2987         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro")
2988                    (match_operand:QI 2 "const_int_operand"     "n, n")))]
2989   "(INTVAL (operands[2]) >= 8)"
2990   "#"
2991   "&& ip2k_reorg_split_himode"
2992   [(set (match_dup 4) (const_int 0))]
2993   "{
2994     operands[3] = ip2k_get_high_half (operands[0], QImode);
2995     operands[4] = ip2k_get_low_half (operands[0], QImode);
2996     operands[5] = ip2k_get_low_half (operands[1], QImode);
2998     if (INTVAL (operands[2]) == 8)
2999       emit_insn (gen_movqi (operands[3], operands[5]));
3000     else
3001       {
3002         operands[6] = gen_int_mode (INTVAL (operands[2]) - 8, QImode);
3003         emit_insn (gen_ashlqi3 (operands[3], operands[5], operands[6]));
3004       }
3005   }")
3007 (define_insn "ashlhi3" ;                              0   1   2  3   4
3008   [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS")
3009         (ashift:HI
3010          (match_operand:HI 1 "nonimmediate_operand"  "0, ro, rS, 0,  0")
3011          (match_operand:QI 2 "general_operand"       "L,  L,  L,rS,roR")))]
3012   ""
3013   "*{
3014     switch (which_alternative)
3015       {
3016       case 0:
3017         switch (INTVAL (operands[2]))
3018           {
3019           case 1:
3020             return AS2 (clrb, status, 0) CR_TAB
3021                    AS1 (rl, %L0) CR_TAB
3022                    AS1 (rl, %H0);
3024           case 2:
3025             return AS2 (clrb, status, 0) CR_TAB
3026                    AS1 (rl, %L0) CR_TAB
3027                    AS1 (rl, %H0) CR_TAB
3028                    AS2 (clrb, status, 0) CR_TAB
3029                    AS1 (rl, %L0) CR_TAB
3030                    AS1 (rl, %H0);
3032           case 3:
3033           case 4:
3034           case 5:
3035           case 6:
3036             return AS2 (mov, w, %L1) CR_TAB
3037                    AS2 (mulu, w, %e2) CR_TAB
3038                    AS2 (mov, %L0, w) CR_TAB
3039                    AS1 (push, MULH%<) CR_TAB
3040                    AS2 (mov, w, %H1) CR_TAB
3041                    AS2 (mulu, w, %e2) CR_TAB
3042                    AS2 (or, 1(SP), w) CR_TAB
3043                    AS1 (pop, %H0%>);
3045           case 7:
3046             return AS1 (rr, %H0) CR_TAB
3047                    AS2 (mov, w, %L0) CR_TAB
3048                    AS1 (clr, %L0) CR_TAB
3049                    AS2 (mov, %H0, w) CR_TAB
3050                    AS1 (rr, %H0) CR_TAB
3051                    AS1 (rr, %L0);
3053           default:
3054             /* Should be caught by a different insn pattern */
3055             abort ();
3056           }
3058       case 1:
3059       case 2:
3060         switch (INTVAL (operands[2]))
3061           {
3062           case 1:
3063             return AS2 (clrb, status, 0) CR_TAB
3064                    AS2 (rl, w, %L1) CR_TAB
3065                    AS2 (mov, %L0, w) CR_TAB
3066                    AS2 (rl, w, %H1) CR_TAB
3067                    AS2 (mov, %H0, w);
3069           case 2:
3070             return AS2 (clrb, status, 0) CR_TAB
3071                    AS2 (rl, w, %L1) CR_TAB
3072                    AS2 (mov, %L0, w) CR_TAB
3073                    AS2 (rl, w, %H1) CR_TAB
3074                    AS2 (mov, %H0, w) CR_TAB
3075                    AS2 (clrb, status, 0) CR_TAB
3076                    AS1 (rl, %L0) CR_TAB
3077                    AS1 (rl, %H0);
3079           case 3:
3080           case 4:
3081           case 5:
3082           case 6:
3083             return AS2 (mov, w, %L1) CR_TAB
3084                    AS2 (mulu, w, %e2) CR_TAB
3085                    AS2 (mov, %L0, w) CR_TAB
3086                    AS1 (push, MULH%<) CR_TAB
3087                    AS2 (mov, w, %H1) CR_TAB
3088                    AS2 (mulu, w, %e2) CR_TAB
3089                    AS2 (or, 1(SP), w) CR_TAB
3090                    AS1 (pop, %H0%>);
3092           case 7:
3093             return AS2 (rr, w, %H1) CR_TAB
3094                    AS2 (mov, w, %L1) CR_TAB
3095                    AS1 (clr, %L0) CR_TAB
3096                    AS2 (mov, %H0, w) CR_TAB
3097                    AS1 (rr, %H0) CR_TAB
3098                    AS1 (rr, %L0);
3100           default:
3101             /* Should be caught by a different insn pattern */
3102             abort ();
3103           }
3105       case 3:
3106       case 4:
3107         return AS2 (mov, w, %2) CR_TAB
3108                AS1 (snz,) CR_TAB
3109                AS1 (page, 2f) CR_TAB
3110                AS1 (jmp, 2f) CR_TAB
3111                AS1 (1:,) CR_TAB
3112                AS2 (clrb, status, 0) CR_TAB
3113                AS1 (rl, %L0) CR_TAB
3114                AS1 (rl, %H0) CR_TAB
3115                AS1 (decsz, wreg) CR_TAB
3116                AS1 (page, 1b) CR_TAB
3117                AS1 (jmp, 1b) CR_TAB
3118                AS1 (2:,);
3120       default:
3121         abort();
3122       }
3123   }")
3125 (define_insn_and_split "*ashlsi3_by16_zero_extend"
3126   [(set (match_operand:SI 0 "nonimmediate_operand"              "=ro,rS")
3127         (ashift:SI (zero_extend:SI
3128                       (match_operand:HI 1 "nonimmediate_operand" "rS,ro"))
3129                    (const_int 16)))]
3130   ""
3131   "#"
3132   "reload_completed"
3133   [(set (match_dup 2) (match_dup 1))
3134    (set (match_dup 3) (const_int 0))]
3135   "{
3136     operands[2] = ip2k_get_high_half (operands[0], HImode);
3137     operands[3] = ip2k_get_low_half (operands[0], HImode);
3138   }")
3140 (define_insn_and_split "ashlsi3_split"
3141   [(set (match_operand:SI 0 "nonimmediate_operand"          "=ro,&ro,&rS")
3142         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro")
3143                    (match_operand:QI 2 "const_int_operand"    "n,  n,  n")))]
3144   "(INTVAL (operands[2]) >= 16)"
3145   "#"
3146   "&& ip2k_reorg_split_simode"
3147   [(const_int 0)]
3148   "{
3149     operands[3] = ip2k_get_high_half (operands[0], HImode);
3150     operands[4] = ip2k_get_low_half (operands[0], HImode);
3151     operands[5] = ip2k_get_low_half (operands[1], HImode);
3153     if (INTVAL (operands[2]) == 16)
3154       {
3155         emit_insn (gen_movhi (operands[3], operands[5]));
3156         emit_insn (gen_movhi (operands[4], GEN_INT (0)));
3157       }
3158     else
3159       {
3160         operands[6] = GEN_INT (INTVAL (operands[2]) - 16);
3161         emit_insn (gen_ashlhi3 (operands[3], operands[5], operands[6]));
3162         emit_insn (gen_movhi (operands[4], GEN_INT (0)));
3163       }
3164   }")
3166 (define_insn "ashlsi3"
3167   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS")
3168         (ashift:SI
3169          (match_operand:SI 1 "nonimmediate_operand"  "0,  0, 0, rS, ro")
3170          (match_operand:QI 2 "general_operand"       "L,roR,rS,  L,  L")))]
3171   ""
3172   "*{
3173     switch (which_alternative) {
3174     case 0:
3175       switch (INTVAL (operands[2])) {
3176       case 1:
3177         return AS2 (clrb, status, 0) CR_TAB
3178                AS1 (rl, %D0) CR_TAB
3179                AS1 (rl, %C0) CR_TAB
3180                AS1 (rl, %B0) CR_TAB
3181                AS1 (rl, %A0);
3183       case 2:
3184         return AS2 (clrb, status, 0) CR_TAB
3185                AS1 (rl, %D0) CR_TAB
3186                AS1 (rl, %C0) CR_TAB
3187                AS1 (rl, %B0) CR_TAB
3188                AS1 (rl, %A0) CR_TAB
3189                AS2 (clrb, status, 0) CR_TAB
3190                AS1 (rl, %D0) CR_TAB
3191                AS1 (rl, %C0) CR_TAB
3192                AS1 (rl, %B0) CR_TAB
3193                AS1 (rl, %A0);
3195       case 8:
3196         return AS2 (mov, w, %B0) CR_TAB
3197                AS2 (mov, %A0, w) CR_TAB
3198                AS2 (mov, w, %C0) CR_TAB
3199                AS2 (mov, %B0, w) CR_TAB
3200                AS2 (mov, w, %D0) CR_TAB
3201                AS2 (mov, %C0, w) CR_TAB
3202                AS1 (clr, %D0);
3204       case 16:
3205         return AS2 (mov, w, %C0) CR_TAB
3206                AS2 (mov, %A0, w) CR_TAB
3207                AS2 (mov, w, %D0) CR_TAB
3208                AS2 (mov, %B0, w) CR_TAB
3209                AS1 (clr, %C0) CR_TAB
3210                AS1 (clr, %D0);
3212       case 23:
3213         return AS2 (rr, w, %C0) CR_TAB
3214                AS2 (mov, w, %D0) CR_TAB
3215                AS2 (mov, %A0, w) CR_TAB
3216                AS1 (clr, %B0) CR_TAB
3217                AS1 (clr, %C0) CR_TAB
3218                AS1 (clr, %D0) CR_TAB
3219                AS1 (rr, %A0) CR_TAB
3220                AS1 (rr, %B0);
3222       case 24:
3223         return AS2 (mov, w, %D0) CR_TAB
3224                AS2 (mov, %A0, w) CR_TAB
3225                AS1 (clr, %B0) CR_TAB
3226                AS1 (clr, %C0) CR_TAB
3227                AS1 (clr, %D0);
3229       case 31:
3230         return AS2 (rr, w, %D0) CR_TAB
3231                AS1 (clr, %A0) CR_TAB
3232                AS1 (clr, %B0) CR_TAB
3233                AS1 (clr, %C0) CR_TAB
3234                AS1 (clr, %D0) CR_TAB
3235                AS1 (rr, %A0);
3237       default:
3238         return AS2 (mov, w, %2) CR_TAB
3239                AS1 (1:,) CR_TAB
3240                AS2 (clrb, status, 0) CR_TAB
3241                AS1 (rl, %D0) CR_TAB
3242                AS1 (rl, %C0) CR_TAB
3243                AS1 (rl, %B0) CR_TAB
3244                AS1 (rl, %A0) CR_TAB
3245                AS1 (decsz, wreg) CR_TAB
3246                AS1 (page, 1b) CR_TAB
3247                AS1 (jmp, 1b);
3248       }
3250     case 1:
3251     case 2:
3252       return AS2 (mov, w, %2) CR_TAB
3253              AS1 (snz,) CR_TAB
3254              AS1 (page, 2f) CR_TAB
3255              AS1 (jmp, 2f) CR_TAB
3256              AS1 (1:,) CR_TAB
3257              AS2 (clrb, status, 0) CR_TAB
3258              AS1 (rl, %D0) CR_TAB
3259              AS1 (rl, %C0) CR_TAB
3260              AS1 (rl, %B0) CR_TAB
3261              AS1 (rl, %A0) CR_TAB
3262              AS1 (decsz, wreg) CR_TAB
3263              AS1 (page, 1b) CR_TAB
3264              AS1 (jmp, 1b) CR_TAB
3265              AS1 (2:,);
3267     case 3:
3268     case 4:
3269       switch (INTVAL (operands[2])) {
3270       case 1:
3271         return AS2 (clrb, status, 0) CR_TAB
3272                AS2 (rl, w, %D1) CR_TAB
3273                AS2 (mov, %D0, w) CR_TAB
3274                AS2 (rl, w, %C1) CR_TAB
3275                AS2 (mov, %C0, w) CR_TAB
3276                AS2 (rl, w, %B1) CR_TAB
3277                AS2 (mov, %B0, w) CR_TAB
3278                AS2 (rl, w, %A1) CR_TAB
3279                AS2 (mov, %A0, w);
3281       case 2:
3282         return AS2 (clrb, status, 0) CR_TAB
3283                AS2 (rl, w, %D1) CR_TAB
3284                AS2 (mov, %D0, w) CR_TAB
3285                AS2 (rl, w, %C1) CR_TAB
3286                AS2 (mov, %C0, w) CR_TAB
3287                AS2 (rl, w, %B1) CR_TAB
3288                AS2 (mov, %B0, w) CR_TAB
3289                AS2 (rl, w, %A1) CR_TAB
3290                AS2 (mov, %A0, w) CR_TAB
3291                AS2 (clrb, status, 0) CR_TAB
3292                AS1 (rl, %D0) CR_TAB
3293                AS1 (rl, %C0) CR_TAB
3294                AS1 (rl, %B0) CR_TAB
3295                AS1 (rl, %A0);
3297       case 8:
3298         return AS2 (mov, w, %B1) CR_TAB
3299                AS2 (mov, %A0, w) CR_TAB
3300                AS2 (mov, w, %C1) CR_TAB
3301                AS2 (mov, %B0, w) CR_TAB
3302                AS2 (mov, w, %D1) CR_TAB
3303                AS2 (mov, %C0, w) CR_TAB
3304                AS1 (clr, %D0);
3306       case 16:
3307         return AS2 (mov, w, %C1) CR_TAB
3308                AS2 (mov, %A0, w) CR_TAB
3309                AS2 (mov, w, %D1) CR_TAB
3310                AS2 (mov, %B0, w) CR_TAB
3311                AS1 (clr, %C0) CR_TAB
3312                AS1 (clr, %D0);
3314       case 23:
3315         return AS2 (rr, w, %C1) CR_TAB
3316                AS2 (mov, w, %D1) CR_TAB
3317                AS2 (mov, %A0, w) CR_TAB
3318                AS1 (clr, %B0) CR_TAB
3319                AS1 (clr, %C0) CR_TAB
3320                AS1 (clr, %D0) CR_TAB
3321                AS1 (rr, %A0) CR_TAB
3322                AS1 (rr, %B0);
3324       case 24:
3325         return AS2 (mov, w, %D1) CR_TAB
3326                AS2 (mov, %A0, w) CR_TAB
3327                AS1 (clr, %B0) CR_TAB
3328                AS1 (clr, %C0) CR_TAB
3329                AS1 (clr, %D0);
3331       case 31:
3332         return AS2 (rr, w, %D1) CR_TAB
3333                AS1 (clr, %A0) CR_TAB
3334                AS1 (clr, %B0) CR_TAB
3335                AS1 (clr, %C0) CR_TAB
3336                AS1 (clr, %D0) CR_TAB
3337                AS1 (rr, %A0);
3339       default:
3340         return AS2 (mov, w, %A1) CR_TAB
3341                AS2 (mov, %A0, w) CR_TAB
3342                AS2 (mov, w, %B1) CR_TAB
3343                AS2 (mov, %B0, w) CR_TAB
3344                AS2 (mov, w, %C1) CR_TAB
3345                AS2 (mov, %C0, w) CR_TAB
3346                AS2 (mov, w, %D1) CR_TAB
3347                AS2 (mov, %D0, w) CR_TAB
3348                AS2 (mov, w, %2) CR_TAB
3349                AS1 (1:,) CR_TAB
3350                AS2 (clrb, status, 0) CR_TAB
3351                AS1 (rl, %D0) CR_TAB
3352                AS1 (rl, %C0) CR_TAB
3353                AS1 (rl, %B0) CR_TAB
3354                AS1 (rl, %A0) CR_TAB
3355                AS1 (decsz, wreg) CR_TAB
3356                AS1 (page, 1b) CR_TAB
3357                AS1 (jmp, 1b);
3358       }
3359     default:
3360       abort ();
3361     }
3362   }")
3364 (define_insn_and_split "ashldi3_split"
3365   [(set (match_operand:DI 0 "nonimmediate_operand"          "=ro,&ro,&rS")
3366         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro")
3367                    (match_operand:QI 2 "const_int_operand"    "n,  n,  n")))]
3368   "((INTVAL (operands[2]) >= 32) || (INTVAL (operands[2]) == 16))"
3369   "#"
3370   "&& ip2k_reorg_split_dimode"
3371   [(const_int 0)]
3372   "{
3373     operands[3] = ip2k_get_high_half (operands[0], SImode);
3374     operands[4] = ip2k_get_low_half (operands[0], SImode);
3375     operands[5] = ip2k_get_low_half (operands[1], SImode);
3377     if (INTVAL (operands[2]) == 16)
3378       {
3379         operands[6] = ip2k_get_high_half (operands[1], SImode);
3380         operands[7] = ip2k_get_high_half (operands[3], HImode);
3381         operands[8] = ip2k_get_low_half (operands[3], HImode);
3382         operands[9] = ip2k_get_high_half (operands[4], HImode);
3383         operands[10] = ip2k_get_low_half (operands[4], HImode);
3384         operands[11] = ip2k_get_low_half (operands[6], HImode);
3385         operands[12] = ip2k_get_high_half (operands[5], HImode);
3386         operands[13] = ip2k_get_low_half (operands[5], HImode);
3387         emit_insn (gen_movhi (operands[7], operands[11]));
3388         emit_insn (gen_movhi (operands[8], operands[12]));
3389         emit_insn (gen_movhi (operands[9], operands[13]));
3390         emit_insn (gen_movhi (operands[10], GEN_INT (0)));
3391       }
3392     else if (INTVAL (operands[2]) == 32)
3393       {
3394         emit_insn (gen_movsi (operands[3], operands[5]));
3395         emit_insn (gen_movsi (operands[4], GEN_INT (0)));
3396       }
3397     else
3398       {
3399         operands[6] = GEN_INT (INTVAL (operands[2]) - 32);
3400         emit_insn (gen_ashlsi3 (operands[3], operands[5], operands[6]));
3401         emit_insn (gen_movsi (operands[4], GEN_INT (0)));
3402       }
3403   }")
3406 ;; Arithmetic shift right instructions.
3409 (define_expand "ashrqi3"
3410   [(set (match_operand:QI 0 "nonimmediate_operand" "")
3411         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
3412                      (match_operand:QI 2 "general_operand" "")))]
3413   ""
3414   "if (operands[2] == const0_rtx)
3415      {
3416        emit_move_insn (operands[0], operands[1]);
3417        DONE;
3418      }
3419   ")
3421 (define_insn "*ashrqi3"
3422   [(set
3423     (match_operand:QI 0 "nonimmediate_operand" "=roR,roR, rS,roR, rS,roR, rS")
3424     (ashiftrt:QI
3425      (match_operand:QI 1 "nonimmediate_operand" "0,  0,  0, rS,roR, rS,roR")
3426      (match_operand:QI 2 "general_operand"      "N, rS,roR,  N,  N,  L,  L")))]
3427   ""
3428   "*{
3429     switch (which_alternative)
3430       {
3431       case 0:
3432         return AS2 (rl, w, %0) CR_TAB
3433                AS1 (rr, %0);
3435       case 3:
3436       case 4:
3437         return AS2 (rl, w, %1) CR_TAB /* dup the sign bit */
3438                AS2 (rr, w, %1) CR_TAB
3439                AS2 (mov, %0, w);
3441       case 5:
3442       case 6:
3443         /* Do >> by left-shifting partially into MULH. */
3444         operands[2] = GEN_INT (8 - INTVAL (operands[2]));
3445         return AS2 (mov, w, %1) CR_TAB
3446                AS2 (muls, w, %e2) CR_TAB
3447                AS2 (mov, w, mulh) CR_TAB
3448                AS2 (mov, %0, w);
3450       case 1:
3451       case 2:
3452       default:
3453         return AS2 (mov, w, %2) CR_TAB
3454                AS1 (snz,) CR_TAB
3455                AS1 (page, 2f) CR_TAB
3456                AS1 (jmp, 2f) CR_TAB
3457                AS1 (1:,) CR_TAB
3458                AS2 (setb, status, 0) CR_TAB
3459                AS2 (sb, %0, 7) CR_TAB
3460                AS2 (clrb, status, 0) CR_TAB
3461                AS1 (rr, %0) CR_TAB
3462                AS1 (decsz, wreg) CR_TAB
3463                AS1 (page, 1b) CR_TAB
3464                AS1 (jmp, 1b) CR_TAB
3465                AS1 (2:,);
3466       }
3467   }")
3469 (define_insn "ashrhi3" ;                             0   1   2  3   4
3470   [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS")
3471         (ashiftrt:HI
3472          (match_operand:HI 1 "nonimmediate_operand"  "0, ro, rS, 0,  0")
3473          (match_operand:QI 2 "general_operand"       "L,  L,  L,rS,roR")))]
3474   ""
3475   "*{
3476     switch (which_alternative) {
3477     case 0:
3478       switch (INTVAL (operands[2])) {
3479       case 1:
3480         return AS2 (rl, w, %H0) CR_TAB
3481                AS1 (rr, %H0) CR_TAB
3482                AS1 (rr, %L0);
3484       case 2:
3485         return AS2 (rl, w, %H0) CR_TAB
3486                AS1 (rr, %H0) CR_TAB
3487                AS1 (rr, %L0) CR_TAB
3488                AS2 (rl, w, %H0) CR_TAB
3489                AS1 (rr, %H0) CR_TAB
3490                AS1 (rr, %L0);
3492       case 8:
3493         return AS2 (mov, w, %H0) CR_TAB
3494                AS2 (mov, %L0, w) CR_TAB
3495                AS1 (clr, %H0) CR_TAB
3496                AS2 (snb, %L0, 7) CR_TAB
3497                AS1 (not, %H0);
3499       default:
3500         return AS2 (mov, w, %2) CR_TAB
3501                AS1 (1:,) CR_TAB
3502                AS2 (setb, status, 0) CR_TAB
3503                AS2 (sb, %H0, 7) CR_TAB
3504                AS2 (clrb, status, 0) CR_TAB
3505                AS1 (rr, %H0) CR_TAB
3506                AS1 (rr, %L0) CR_TAB
3507                AS1 (decsz, wreg) CR_TAB
3508                AS1 (page, 1b) CR_TAB
3509                AS1 (jmp, 1b);
3510       }
3512     case 1:
3513     case 2:
3514       switch (INTVAL (operands[2])) {
3515       case 1:
3516         return AS2 (rl, w, %H1) CR_TAB
3517                AS2 (rr, w, %H1) CR_TAB
3518                AS2 (mov, %H0, w) CR_TAB
3519                AS2 (rr, w, %L1) CR_TAB
3520                AS2 (mov, %L0, w);
3522       case 2:
3523         return AS2 (rl, w, %H1) CR_TAB
3524                AS2 (rr, w, %H1) CR_TAB
3525                AS2 (mov, %H0, w) CR_TAB
3526                AS2 (rr, w, %L1) CR_TAB
3527                AS2 (mov, %L0, w) CR_TAB
3528                AS2 (rl, w, %H0) CR_TAB
3529                AS1 (rr, %H0) CR_TAB
3530                AS1 (rr, %L0);
3532       case 8:
3533         return AS2 (mov, w, %H1) CR_TAB
3534                AS2 (mov, %L0, w) CR_TAB
3535                AS1 (clr, %H0) CR_TAB
3536                AS2 (snb, %L0, 7) CR_TAB
3537                AS1 (not, %H0);
3539       default:
3540         return AS2 (mov, w, %L1) CR_TAB
3541                AS2 (mov, %L0, w) CR_TAB
3542                AS2 (mov, w, %H1) CR_TAB
3543                AS2 (mov, %H0, w) CR_TAB
3544                AS2 (mov, w, %2) CR_TAB
3545                AS1 (1:,) CR_TAB
3546                AS2 (setb, status, 0) CR_TAB
3547                AS2 (sb, %H0, 7) CR_TAB
3548                AS2 (clrb, status, 0) CR_TAB
3549                AS1 (rr, %H0) CR_TAB
3550                AS1 (rr, %L0) CR_TAB
3551                AS1 (decsz, wreg) CR_TAB
3552                AS1 (page, 1b) CR_TAB
3553                AS1 (jmp, 1b);
3554       }
3556     case 3:
3557     case 4:
3558       return AS2 (mov, w, %2) CR_TAB
3559              AS1 (snz,) CR_TAB
3560              AS1 (page, 2f) CR_TAB
3561              AS1 (jmp, 2f) CR_TAB
3562              AS1 (1:,) CR_TAB
3563              AS2 (setb, status, 0) CR_TAB
3564              AS2 (sb, %H0, 7) CR_TAB
3565              AS2 (clrb, status, 0) CR_TAB
3566              AS1 (rr, %H0) CR_TAB
3567              AS1 (rr, %L0) CR_TAB
3568              AS1 (decsz, wreg) CR_TAB
3569              AS1 (page, 1b) CR_TAB
3570              AS1 (jmp, 1b) CR_TAB
3571              AS1 (2:,);
3573     default:
3574       abort();
3575     }
3576   }")
3578 (define_insn "ashrsi3"
3579   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS")
3580         (ashiftrt:SI
3581          (match_operand:SI 1 "nonimmediate_operand"  "0,  0, 0, rS, ro")
3582          (match_operand:QI 2 "general_operand"       "L,roR,rS,  L,  L")))]
3583   ""
3584   "*{
3585     switch (which_alternative) {
3586     case 0:
3587       switch (INTVAL (operands[2])) {
3588       case 1:
3589         return AS2 (rl, w, %A0) CR_TAB /* dup the sign bit */
3590                AS1 (rr, %A0) CR_TAB
3591                AS1 (rr, %B0) CR_TAB
3592                AS1 (rr, %C0) CR_TAB
3593                AS1 (rr, %D0);
3595       case 2:
3596         return AS2 (rl, w, %A0) CR_TAB /* dup the sign bit */
3597                AS1 (rr, %A0) CR_TAB
3598                AS1 (rr, %B0) CR_TAB
3599                AS1 (rr, %C0) CR_TAB
3600                AS1 (rr, %D0) CR_TAB
3601                AS2 (rl, w, %A0) CR_TAB
3602                AS1 (rr, %A0) CR_TAB
3603                AS1 (rr, %B0) CR_TAB
3604                AS1 (rr, %C0) CR_TAB
3605                AS1 (rr, %D0);
3607       case 8:
3608         return AS2 (mov, w, %C0) CR_TAB
3609                AS2 (mov, %D0, w) CR_TAB
3610                AS2 (mov, w, %B0) CR_TAB
3611                AS2 (mov, %C0, w) CR_TAB
3612                AS2 (mov, w, %A0) CR_TAB
3613                AS2 (mov, %B0, w) CR_TAB
3614                AS1 (clr, %A0) CR_TAB
3615                AS2 (snb, %B0, 7) CR_TAB
3616                AS1 (not, %A0);
3618       case 16:
3619         return AS2 (mov, w, %B0) CR_TAB
3620                AS2 (mov, %D0, w) CR_TAB
3621                AS2 (mov, w, %A0) CR_TAB
3622                AS2 (mov, %C0, w) CR_TAB
3623                AS1 (clr, WREG) CR_TAB
3624                AS2 (snb, %C0, 7) CR_TAB
3625                AS1 (not, WREG) CR_TAB
3626                AS2 (mov, %B0, w) CR_TAB
3627                AS2 (mov, %A0, w);
3629       case 23:
3630         return AS2 (rl, w, %B0) CR_TAB
3631                AS2 (mov, w, %A0) CR_TAB
3632                AS2 (mov, %D0, w) CR_TAB
3633                AS1 (clr, WREG) CR_TAB
3634                AS2 (snb, %D0, 7) CR_TAB
3635                AS1 (not, WREG) CR_TAB
3636                AS2 (mov, %C0, w) CR_TAB
3637                AS2 (mov, %B0, w) CR_TAB
3638                AS2 (mov, %A0, w) CR_TAB
3639                AS1 (rl, %D0) CR_TAB
3640                AS1 (rl, %C0);
3642       case 24:
3643         return AS2 (mov, w, %A0) CR_TAB
3644                AS2 (mov, %D0, w) CR_TAB
3645                AS1 (clr, WREG) CR_TAB
3646                AS2 (snb, %D0, 7) CR_TAB
3647                AS1 (not, WREG) CR_TAB
3648                AS2 (mov, %C0, w) CR_TAB
3649                AS2 (mov, %B0, w) CR_TAB
3650                AS2 (mov, %A0, w);
3652       case 31:
3653         return AS2 (rl, w, %A0) CR_TAB
3654                AS1 (clr, WREG) CR_TAB
3655                AS2 (snb, %A0, 7) CR_TAB
3656                AS1 (not, WREG) CR_TAB
3657                AS2 (mov, %D0, w) CR_TAB
3658                AS2 (mov, %C0, w) CR_TAB
3659                AS2 (mov, %B0, w) CR_TAB
3660                AS2 (mov, %A0, w) CR_TAB
3661                AS1 (rl, %D0);
3663       default:
3664         return AS2 (mov, w, %2) CR_TAB
3665                AS1 (1:,) CR_TAB
3666                AS2 (setb, status, 0) CR_TAB
3667                AS2 (sb, %A0, 7) CR_TAB
3668                AS2 (clrb, status, 0) CR_TAB
3669                AS1 (rr, %A0) CR_TAB
3670                AS1 (rr, %B0) CR_TAB
3671                AS1 (rr, %C0) CR_TAB
3672                AS1 (rr, %D0) CR_TAB
3673                AS1 (decsz, WREG) CR_TAB
3674                AS1 (page, 1b) CR_TAB
3675                AS1 (jmp, 1b);
3676       }
3678     case 1:
3679     case 2:
3680       return AS2 (mov, w, %2) CR_TAB
3681              AS1 (snz,) CR_TAB
3682              AS1 (page, 2f) CR_TAB
3683              AS1 (jmp, 2f) CR_TAB
3684              AS1 (1:,) CR_TAB
3685              AS2 (setb, status, 0) CR_TAB
3686              AS2 (sb, %A0, 7) CR_TAB
3687              AS2 (clrb, status, 0) CR_TAB
3688              AS1 (rr, %A0) CR_TAB
3689              AS1 (rr, %B0) CR_TAB
3690              AS1 (rr, %C0) CR_TAB
3691              AS1 (rr, %D0) CR_TAB
3692              AS1 (decsz, WREG) CR_TAB
3693              AS1 (page, 1b) CR_TAB
3694              AS1 (jmp, 1b) CR_TAB
3695              AS1 (2:,);
3697     case 3:
3698     case 4:
3699       switch (INTVAL (operands[2])) {
3700       case 1:
3701         return AS2 (rl, w, %A1) CR_TAB /* dup the sign bit */
3702                AS2 (rr, w, %A1) CR_TAB
3703                AS2 (mov, %A0, w) CR_TAB
3704                AS2 (rr, w, %B1) CR_TAB
3705                AS2 (mov, %B0, w) CR_TAB
3706                AS2 (rr, w, %C1) CR_TAB
3707                AS2 (mov, %C0, w) CR_TAB
3708                AS2 (rr, w, %D1) CR_TAB
3709                AS2 (mov, %D0, w);
3711       case 2:
3712         return AS2 (rl, w, %A1) CR_TAB /* dup the sign bit */
3713                AS2 (rr, w, %A1) CR_TAB
3714                AS2 (mov, %A0, w) CR_TAB
3715                AS2 (rr, w, %B1) CR_TAB
3716                AS2 (mov, %B0, w) CR_TAB
3717                AS2 (rr, w, %C1) CR_TAB
3718                AS2 (mov, %C0, w) CR_TAB
3719                AS2 (rr, w, %D1) CR_TAB
3720                AS2 (mov, %D0, w) CR_TAB
3721                AS2 (rl, w, %A0) CR_TAB
3722                AS1 (rr, %A0) CR_TAB
3723                AS1 (rr, %B0) CR_TAB
3724                AS1 (rr, %C0) CR_TAB
3725                AS1 (rr, %D0);
3727       case 8:
3728         return AS2 (mov, w, %C1) CR_TAB
3729                AS2 (mov, %D0, w) CR_TAB
3730                AS2 (mov, w, %B1) CR_TAB
3731                AS2 (mov, %C0, w) CR_TAB
3732                AS2 (mov, w, %A1) CR_TAB
3733                AS2 (mov, %B0, w) CR_TAB
3734                AS1 (clr, %A0) CR_TAB
3735                AS2 (snb, %B0, 7) CR_TAB
3736                AS1 (not, %A0);
3738       case 16:
3739         return AS2 (mov, w, %B1) CR_TAB
3740                AS2 (mov, %D0, w) CR_TAB
3741                AS2 (mov, w, %A1) CR_TAB
3742                AS2 (mov, %C0, w) CR_TAB
3743                AS1 (clr, WREG) CR_TAB
3744                AS2 (snb, %C0, 7) CR_TAB
3745                AS1 (not, WREG) CR_TAB
3746                AS2 (mov, %B0, w) CR_TAB
3747                AS2 (mov, %A0, w);
3749       case 23:
3750         return AS2 (rl, w, %B1) CR_TAB
3751                AS2 (mov, w, %A1) CR_TAB
3752                AS2 (mov, %D0, w) CR_TAB
3753                AS1 (clr, WREG) CR_TAB
3754                AS2 (snb, %D0, 7) CR_TAB
3755                AS1 (not, WREG) CR_TAB
3756                AS2 (mov, %C0, w) CR_TAB
3757                AS2 (mov, %B0, w) CR_TAB
3758                AS2 (mov, %A0, w) CR_TAB
3759                AS1 (rl, %D0) CR_TAB
3760                AS1 (rl, %C0);
3762       case 24:
3763         return AS2 (mov, w, %A1) CR_TAB
3764                AS2 (mov, %D0, w) CR_TAB
3765                AS1 (clr, WREG) CR_TAB
3766                AS2 (snb, %D0, 7) CR_TAB
3767                AS1 (not, WREG) CR_TAB
3768                AS2 (mov, %C0, w) CR_TAB
3769                AS2 (mov, %B0, w) CR_TAB
3770                AS2 (mov, %A0, w);
3772       case 31:
3773         return AS2 (rl, w, %A1) CR_TAB
3774                AS1 (clr, WREG) CR_TAB
3775                AS2 (snb, %A1, 7) CR_TAB
3776                AS1 (not, WREG) CR_TAB
3777                AS2 (mov, %D0, w) CR_TAB
3778                AS2 (mov, %C0, w) CR_TAB
3779                AS2 (mov, %B0, w) CR_TAB
3780                AS2 (mov, %A0, w) CR_TAB
3781                AS1 (rl, %D0);
3783       default:
3784         return AS2 (mov, w, %A1) CR_TAB
3785                AS2 (mov, %A0, w) CR_TAB
3786                AS2 (mov, w, %B1) CR_TAB
3787                AS2 (mov, %B0, w) CR_TAB
3788                AS2 (mov, w, %C1) CR_TAB
3789                AS2 (mov, %C0, w) CR_TAB
3790                AS2 (mov, w, %D1) CR_TAB
3791                AS2 (mov, %D0, w) CR_TAB
3792                AS2 (mov, w, %2) CR_TAB
3793                AS1 (1:,) CR_TAB
3794                AS2 (setb, status, 0) CR_TAB
3795                AS2 (sb, %A0, 7) CR_TAB
3796                AS2 (clrb, status, 0) CR_TAB
3797                AS1 (rr, %A0) CR_TAB
3798                AS1 (rr, %B0) CR_TAB
3799                AS1 (rr, %C0) CR_TAB
3800                AS1 (rr, %D0) CR_TAB
3801                AS1 (decsz, wreg) CR_TAB
3802                AS1 (page, 1b) CR_TAB
3803                AS1 (jmp, 1b);
3804       }
3805     default:
3806       abort ();
3807     }
3808   }")
3811 ;; Logical shift right instructions.
3814 (define_insn "lshrqi3"
3815   [(set (match_operand:QI
3816          0 "nonimmediate_operand" "=roR, rS,roR,roR, rS,&roR,roR, rS")
3817         (lshiftrt:QI
3818          (match_operand:QI
3819           1 "nonimmediate_operand"   "0,  0,  0, rS,roR,  rS, rS,roR")
3820          (match_operand:QI
3821           2 "general_operand"        "N,roR, rS,  N,  N,  rS,  L,  L")))]
3822   ""
3823   "*{
3824     switch (which_alternative)
3825       {
3826       case 0:
3827         return AS2 (clrb, status, 0) CR_TAB
3828                AS1 (rr, %0);
3830       case 1:
3831       case 2:
3832         return AS2 (mov, w, %2) CR_TAB
3833                AS1 (snz,) CR_TAB
3834                AS1 (page, 2f) CR_TAB
3835                AS1 (jmp, 2f) CR_TAB
3836                AS1 (1:,) CR_TAB
3837                AS2 (clrb, status, 0) CR_TAB
3838                AS1 (rr, %0) CR_TAB
3839                AS1 (decsz, wreg) CR_TAB
3840                AS1 (page, 1b) CR_TAB
3841                AS1 (jmp, 1b) CR_TAB
3842                AS1 (2:,);
3844       case 3:
3845       case 4:
3846         return AS2 (clrb, status, 0) CR_TAB
3847                AS2 (rr, w, %1) CR_TAB
3848                AS2 (mov, %0, w);
3850       case 5:
3851         return AS2 (mov, w, %1) CR_TAB
3852                AS2 (mov, %0, w) CR_TAB
3853                AS2 (mov, w, %2) CR_TAB
3854                AS1 (snz,) CR_TAB
3855                AS1 (page, 2f) CR_TAB
3856                AS1 (jmp, 2f) CR_TAB
3857                AS1 (1:,)
3858                AS2 (clrb, status, 0) CR_TAB
3859                AS1 (rr, %0) CR_TAB
3860                AS1 (decsz, wreg) CR_TAB
3861                AS1 (page, 1b) CR_TAB
3862                AS1 (jmp, 1b) CR_TAB
3863                AS1 (2:,);
3865       case 6:
3866       case 7:
3867         /* Do >> by left-shifting partially into MULH. */
3868         operands[2] = GEN_INT (8 - INTVAL (operands[2]));
3869         return AS2 (mov, w, %1) CR_TAB
3870                AS2 (mulu, w, %e2) CR_TAB
3871                AS2 (mov, w, mulh) CR_TAB
3872                AS2 (mov, %0, w);
3873       default:
3874         abort ();
3875       }
3876   }")
3878 (define_insn_and_split "lshrhi3_split"
3879   [(set (match_operand:HI 0 "nonimmediate_operand"             "=ro,rS")
3880         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro")
3881                    (match_operand:QI 2 "const_int_operand"       "n, n")))]
3882   "(INTVAL (operands[2]) >= 8)"
3883   "#"
3884   "&& ip2k_reorg_split_himode"
3885   [(const_int 0)]
3886   "{
3887     operands[3] = ip2k_get_high_half (operands[0], QImode);
3888     operands[4] = ip2k_get_low_half (operands[0], QImode);
3889     operands[5] = ip2k_get_high_half (operands[1], QImode);
3891     if (INTVAL (operands[2]) == 8)
3892       emit_insn (gen_movqi (operands[4], operands[5]));
3893     else
3894       {
3895         operands[6] = GEN_INT (INTVAL (operands[2]) - 8);
3896         emit_insn (gen_lshrqi3 (operands[4], operands[5], operands[6]));
3897       }
3898     emit_insn (gen_movqi (operands[3], GEN_INT (0)));
3899   }")
3901 (define_insn "lshrhi3" ;                              0   1   2  3   4
3902   [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS")
3903         (lshiftrt:HI
3904          (match_operand:HI 1 "nonimmediate_operand" " 0, ro, rS, 0,  0")
3905          (match_operand:QI 2 "general_operand"       "L,  L,  L,rS,roR")))]
3906   ""
3907   "*{
3908     switch (which_alternative)
3909       {
3910       case 0:
3911         switch (INTVAL (operands[2]))
3912           {
3913           case 1:
3914             return AS2 (clrb, status, 0) CR_TAB
3915                    AS1 (rr, %H0) CR_TAB
3916                    AS1 (rr, %L0);
3918           case 2:
3919             return AS2 (clrb, status, 0) CR_TAB
3920                    AS1 (rr, %H0) CR_TAB
3921                    AS1 (rr, %L0) CR_TAB
3922                    AS2 (clrb, status, 0) CR_TAB
3923                    AS1 (rr, %H0) CR_TAB
3924                    AS1 (rr, %L0);
3926           case 3:
3927           case 4:
3928           case 5:
3929           case 6:
3930           case 7:
3931             operands[2] = GEN_INT (8 - INTVAL (operands[2]));
3932             return AS2 (mov, w, %L0) CR_TAB
3933                    AS2 (mulu, w, %e2) CR_TAB
3934                    AS2 (mov, w, MULH) CR_TAB
3935                    AS2 (mov, %L0, w) CR_TAB
3936                    AS2 (mov, w, %H0) CR_TAB
3937                    AS2 (mulu, w, %e2) CR_TAB
3938                    AS2 (or, %L0, w) CR_TAB
3939                    AS2 (mov, w, MULH) CR_TAB
3940                    AS2 (mov, %H0, w);
3942           default:
3943             /* Should be caught by a different insn pattern */
3944             abort ();
3945           }
3947       case 1:
3948       case 2:
3949         switch (INTVAL (operands[2]))
3950           {
3951           case 1:
3952             return AS2 (clrb, status, 0) CR_TAB
3953                    AS2 (rr, w, %H1) CR_TAB
3954                    AS2 (mov, %H0, w) CR_TAB
3955                    AS2 (rr, w, %L1) CR_TAB
3956                    AS2 (mov, %L0, w);
3958           case 2:
3959             return AS2 (clrb, status, 0) CR_TAB
3960                    AS2 (rr, w, %H1) CR_TAB
3961                    AS2 (mov, %H0, w) CR_TAB
3962                    AS2 (rr, w, %L1) CR_TAB
3963                    AS2 (mov, %L0, w) CR_TAB
3964                    AS2 (clrb, status, 0) CR_TAB
3965                    AS1 (rr, %H0) CR_TAB
3966                    AS1 (rr, %L0);
3968           case 3:
3969           case 4:
3970           case 5:
3971           case 6:
3972           case 7:
3973             operands[2] = GEN_INT (8 - INTVAL (operands[2]));
3974             return AS2 (mov, w, %L1) CR_TAB
3975                    AS2 (mulu, w, %e2) CR_TAB
3976                    AS2 (mov, w, MULH) CR_TAB
3977                    AS2 (mov, %L0, w) CR_TAB
3978                    AS2 (mov, w, %H1) CR_TAB
3979                    AS2 (mulu, w, %e2) CR_TAB
3980                    AS2 (or, %L0, w) CR_TAB
3981                    AS2 (mov, w, MULH) CR_TAB
3982                    AS2 (mov, %H0, w);
3984           default:
3985             /* Should be caught by a different insn pattern */
3986             abort ();
3987           }
3989       case 3:
3990       case 4:
3991         return AS2 (mov, w, %2) CR_TAB
3992                AS1 (snz,) CR_TAB
3993                AS1 (page, 2f) CR_TAB
3994                AS1 (jmp, 2f) CR_TAB
3995                AS1 (1:,) CR_TAB
3996                AS2 (clrb, status, 0) CR_TAB
3997                AS1 (rr, %H0) CR_TAB
3998                AS1 (rr, %L0) CR_TAB
3999                AS1 (decsz, wreg) CR_TAB
4000                AS1 (page, 1b) CR_TAB
4001                AS1 (jmp, 1b) CR_TAB
4002                AS1 (2:,);
4004       default:
4005         abort();
4006       }
4007   }")
4009 (define_insn_and_split "lshrsi3_split"
4010   [(set (match_operand:SI 0 "nonimmediate_operand"            "=ro,&ro,&rS")
4011         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro")
4012                    (match_operand:QI 2 "const_int_operand"      "n,  n,  n")))]
4013   "(INTVAL (operands[2]) >= 16)"
4014   "#"
4015   "&& ip2k_reorg_split_simode"
4016   [(const_int 0)]
4017   "{
4018     operands[3] = ip2k_get_high_half (operands[0], HImode);
4019     operands[4] = ip2k_get_low_half (operands[0], HImode);
4020     operands[5] = ip2k_get_high_half (operands[1], HImode);
4022     if (INTVAL (operands[2]) == 16)
4023       emit_insn (gen_movhi (operands[4], operands[5]));
4024     else
4025       {
4026         operands[6] = GEN_INT (INTVAL (operands[2]) - 16);
4027         emit_insn (gen_lshrhi3 (operands[4], operands[5], operands[6]));
4028       }
4029     emit_insn (gen_movhi (operands[3], GEN_INT (0)));
4030   }")
4032 ;; This occurs frequently in supporting FP among other things,
4033 ;; and out-of-line is almost as big as inline, so....
4035 (define_insn "lshrsi3"
4036   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS")
4037         (lshiftrt:SI
4038          (match_operand:SI 1 "nonimmediate_operand"  "0,  0, 0, rS, ro")
4039          (match_operand:QI 2 "general_operand"       "L,roR,rS,  L,  L")))]
4041   ""
4042   "*{
4043     switch (which_alternative) {
4044     case 0:
4045       switch (INTVAL (operands[2])) {
4046       case 1:
4047         return AS2 (clrb, status, 0) CR_TAB
4048                AS1 (rr, %A0) CR_TAB
4049                AS1 (rr, %B0) CR_TAB
4050                AS1 (rr, %C0) CR_TAB
4051                AS1 (rr, %D0);
4053       case 2:
4054         return AS2 (clrb, status, 0) CR_TAB
4055                AS1 (rr, %A0) CR_TAB
4056                AS1 (rr, %B0) CR_TAB
4057                AS1 (rr, %C0) CR_TAB
4058                AS1 (rr, %D0) CR_TAB
4059                AS2 (clrb, status, 0) CR_TAB
4060                AS1 (rr, %A0) CR_TAB
4061                AS1 (rr, %B0) CR_TAB
4062                AS1 (rr, %C0) CR_TAB
4063                AS1 (rr, %D0);
4065       case 8:
4066         return AS2 (mov, w, %C0) CR_TAB
4067                AS2 (mov, %D0, w) CR_TAB
4068                AS2 (mov, w, %B0) CR_TAB
4069                AS2 (mov, %C0, w) CR_TAB
4070                AS2 (mov, w, %A0) CR_TAB
4071                AS2 (mov, %B0, w) CR_TAB
4072                AS1 (clr, %A0);
4074       case 16:
4075         return AS2 (mov, w, %B0) CR_TAB
4076                AS2 (mov, %D0, w) CR_TAB
4077                AS2 (mov, w, %A0) CR_TAB
4078                AS2 (mov, %C0, w) CR_TAB
4079                AS1 (clr, %B0) CR_TAB
4080                AS1 (clr, %A0);
4082       case 23:
4083         return AS2 (rl, w, %B0) CR_TAB
4084                AS2 (mov, w, %A0) CR_TAB
4085                AS2 (mov, %D0, w) CR_TAB
4086                AS1 (clr, %C0) CR_TAB
4087                AS1 (clr, %B0) CR_TAB
4088                AS1 (clr, %A0) CR_TAB
4089                AS1 (rl, %D0) CR_TAB
4090                AS1 (rl, %C0);
4092       case 24:
4093         return AS2 (mov, w, %A0) CR_TAB
4094                AS2 (mov, %D0, w) CR_TAB
4095                AS1 (clr, %C0) CR_TAB
4096                AS1 (clr, %B0) CR_TAB
4097                AS1 (clr, %A0);
4099       case 31:
4100         return AS2 (rl, w, %A0) CR_TAB
4101                AS1 (clr, %D0) CR_TAB
4102                AS1 (clr, %C0) CR_TAB
4103                AS1 (clr, %B0) CR_TAB
4104                AS1 (clr, %A0) CR_TAB
4105                AS1 (rl, %D0);
4107       default:
4108         return AS2 (mov, w, %2) CR_TAB
4109                AS1 (1:,) CR_TAB
4110                AS2 (clrb, status, 0) CR_TAB
4111                AS1 (rr, %A0) CR_TAB
4112                AS1 (rr, %B0) CR_TAB
4113                AS1 (rr, %C0) CR_TAB
4114                AS1 (rr, %D0) CR_TAB
4115                AS1 (decsz, wreg) CR_TAB
4116                AS1 (page, 1b) CR_TAB
4117                AS1 (jmp, 1b);
4118       }
4120     case 1:
4121     case 2:
4122       return AS2 (mov, w, %2) CR_TAB
4123              AS1 (snz,) CR_TAB
4124              AS1 (page, 2f) CR_TAB
4125              AS1 (jmp, 2f) CR_TAB
4126              AS1 (1:,) CR_TAB
4127              AS2 (clrb, status, 0) CR_TAB
4128              AS1 (rr, %A0) CR_TAB
4129              AS1 (rr, %B0) CR_TAB
4130              AS1 (rr, %C0) CR_TAB
4131              AS1 (rr, %D0) CR_TAB
4132              AS1 (decsz, wreg) CR_TAB
4133              AS1 (page, 1b) CR_TAB
4134              AS1 (jmp, 1b) CR_TAB
4135              AS1 (2:,);
4137     case 3:
4138     case 4:
4139       switch (INTVAL (operands[2])) {
4140       case 1:
4141         return AS2 (clrb, status, 0) CR_TAB
4142                AS2 (rr, w, %A1) CR_TAB
4143                AS2 (mov, %A0, w) CR_TAB
4144                AS2 (rr, w, %B1) CR_TAB
4145                AS2 (mov, %B0, w) CR_TAB
4146                AS2 (rr, w, %C1) CR_TAB
4147                AS2 (mov, %C0, w) CR_TAB
4148                AS2 (rr, w, %D1) CR_TAB
4149                AS2 (mov, %D0, w);
4151       case 2:
4152         return AS2 (clrb, status, 0) CR_TAB
4153                AS2 (rr, w, %A1) CR_TAB
4154                AS2 (mov, %A0, w) CR_TAB
4155                AS2 (rr, w, %B1) CR_TAB
4156                AS2 (mov, %B0, w) CR_TAB
4157                AS2 (rr, w, %C1) CR_TAB
4158                AS2 (mov, %C0, w) CR_TAB
4159                AS2 (rr, w, %D1) CR_TAB
4160                AS2 (mov, %D0, w) CR_TAB
4161                AS2 (clrb, status, 0) CR_TAB
4162                AS1 (rr, %A0) CR_TAB
4163                AS1 (rr, %B0) CR_TAB
4164                AS1 (rr, %C0) CR_TAB
4165                AS1 (rr, %D0);
4167       case 8:
4168         return AS2 (mov, w, %C1) CR_TAB
4169                AS2 (mov, %D0, w) CR_TAB
4170                AS2 (mov, w, %B1) CR_TAB
4171                AS2 (mov, %C0, w) CR_TAB
4172                AS2 (mov, w, %A1) CR_TAB
4173                AS2 (mov, %B0, w) CR_TAB
4174                AS1 (clr, %A0);
4176       case 16:
4177         return AS2 (mov, w, %B1) CR_TAB
4178                AS2 (mov, %D0, w) CR_TAB
4179                AS2 (mov, w, %A1) CR_TAB
4180                AS2 (mov, %C0, w) CR_TAB
4181                AS1 (clr, %B0) CR_TAB
4182                AS1 (clr, %A0);
4184       case 23:
4185         return AS2 (rl, w, %B1) CR_TAB
4186                AS2 (mov, w, %A1) CR_TAB
4187                AS2 (mov, %D0, w) CR_TAB
4188                AS1 (clr, %C0) CR_TAB
4189                AS1 (clr, %B0) CR_TAB
4190                AS1 (clr, %A0) CR_TAB
4191                AS1 (rl, %D0) CR_TAB
4192                AS1 (rl, %C0);
4194       case 24:
4195         return AS2 (mov, w, %A1) CR_TAB
4196                AS2 (mov, %D0, w) CR_TAB
4197                AS1 (clr, %C0) CR_TAB
4198                AS1 (clr, %B0) CR_TAB
4199                AS1 (clr, %A0);
4201       case 31:
4202         return AS2 (rl, w, %A1) CR_TAB
4203                AS1 (clr, %D0) CR_TAB
4204                AS1 (clr, %C0) CR_TAB
4205                AS1 (clr, %B0) CR_TAB
4206                AS1 (clr, %A0) CR_TAB
4207                AS1 (rl, %D0);
4209       default:
4210         return AS2 (mov, w, %A1) CR_TAB
4211                AS2 (mov, %A0, w) CR_TAB
4212                AS2 (mov, w, %B1) CR_TAB
4213                AS2 (mov, %B0, w) CR_TAB
4214                AS2 (mov, w, %C1) CR_TAB
4215                AS2 (mov, %C0, w) CR_TAB
4216                AS2 (mov, w, %D1) CR_TAB
4217                AS2 (mov, %D0, w) CR_TAB
4218                AS2 (mov, w, %2) CR_TAB
4219                AS1 (1:,) CR_TAB
4220                AS2 (clrb, status, 0) CR_TAB
4221                AS1 (rr, %A0) CR_TAB
4222                AS1 (rr, %B0) CR_TAB
4223                AS1 (rr, %C0) CR_TAB
4224                AS1 (rr, %D0) CR_TAB
4225                AS1 (decsz, wreg) CR_TAB
4226                AS1 (page, 1b) CR_TAB
4227                AS1 (jmp, 1b);
4228       }
4229     default:
4230       abort ();
4231     }
4232   }")
4234 (define_insn_and_split "lshrdi3_split"
4235   [(set (match_operand:DI 0 "nonimmediate_operand"            "=ro,&ro,&rS")
4236         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro")
4237                    (match_operand:QI 2 "const_int_operand"      "n,  n,  n")))]
4238   "((INTVAL (operands[2]) >= 32) || (INTVAL (operands[2]) == 16))"
4239   "#"
4240   "&& ip2k_reorg_split_dimode"
4241   [(const_int 0)]
4242   "{
4243     operands[3] = ip2k_get_high_half (operands[0], SImode);
4244     operands[4] = ip2k_get_low_half (operands[0], SImode);
4245     operands[5] = ip2k_get_high_half (operands[1], SImode);
4247     if (INTVAL (operands[2]) == 16)
4248       {
4249         operands[6] = ip2k_get_low_half (operands[1], SImode);
4250         operands[7] = ip2k_get_high_half (operands[3], HImode);
4251         operands[8] = ip2k_get_low_half (operands[3], HImode);
4252         operands[9] = ip2k_get_high_half (operands[4], HImode);
4253         operands[10] = ip2k_get_low_half (operands[4], HImode);
4254         operands[11] = ip2k_get_high_half (operands[6], HImode);
4255         operands[12] = ip2k_get_low_half (operands[5], HImode);
4256         operands[13] = ip2k_get_high_half (operands[5], HImode);
4257         emit_insn (gen_movhi (operands[10], operands[11]));
4258         emit_insn (gen_movhi (operands[9], operands[12]));
4259         emit_insn (gen_movhi (operands[8], operands[13]));
4260         emit_insn (gen_movhi (operands[7], GEN_INT(0)));
4261       }
4262     else if (INTVAL (operands[2]) == 32)
4263       {
4264         emit_insn (gen_movsi (operands[4], operands[5]));
4265         emit_insn (gen_movsi (operands[3], GEN_INT (0)));
4266       }
4267     else
4268       {
4269         operands[6] = GEN_INT (INTVAL (operands[2]) - 32);
4270         emit_insn (gen_lshrsi3 (operands[4], operands[5], operands[6]));
4271         emit_insn (gen_movsi (operands[3], GEN_INT (0)));
4272       }
4273   }")
4276 ;; Absolute value conversion instructions.
4279 (define_insn "absqi2"
4280   [(set (match_operand:QI 0 "nonimmediate_operand"        "=g")
4281         (abs:QI (match_operand:QI 1 "nonimmediate_operand" "g")))]
4282   ""
4283   "mov\\tw,%1\;snb\\twreg,7\;sub\\tw,#0\;mov\\t%0,w")
4285 (define_insn "abssf2"
4286   [(set (match_operand:SF 0 "nonimmediate_operand"       "=ro")
4287         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0")))]
4288   ""
4289   "clrb %A0,7"
4290   [(set_attr "clobberw" "no")])
4293 ;; Negate (X = 0 - Y) instructions.
4296 (define_insn_and_split "negqi2"
4297   [(set (match_operand:QI 0 "nonimmediate_operand"       "=ro,&ro,&rS")
4298         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0, rS, ro")))]
4299   ""
4300   "#"
4301   ""
4302   [(set (match_dup 0)
4303         (not:QI (match_dup 1)))
4304    (set (match_dup 0)
4305         (plus:QI (match_dup 0)
4306                  (const_int 1)))]
4307   "")
4309 (define_insn_and_split "neghi2"
4310   [(set (match_operand:HI 0 "nonimmediate_operand"       "=ro,&ro,&rS")
4311         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0, rS, ro")))]
4312   ""
4313   "#"
4314   ""
4315   [(set (match_dup 0)
4316         (not:HI (match_dup 1)))
4317    (set (match_dup 0)
4318         (plus:HI (match_dup 0)
4319                  (const_int 1)))]
4320   "")
4322 (define_insn_and_split "negsi2"
4323   [(set (match_operand:SI 0 "nonimmediate_operand"       "=ro,&ro,&rS")
4324         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro")))]
4325   ""
4326   "#"
4327   ""
4328   [(set (match_dup 0)
4329         (not:SI (match_dup 1)))
4330    (set (match_dup 0)
4331         (plus:SI (match_dup 0)
4332                  (const_int 1)))]
4333   "")
4335 (define_insn_and_split "negdi2"
4336   [(set (match_operand:DI 0 "nonimmediate_operand"       "=ro,&ro,&rS")
4337         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro")))]
4338   ""
4339   "#"
4340   ""
4341   [(set (match_dup 0)
4342         (not:DI (match_dup 1)))
4343    (set (match_dup 0)
4344         (plus:DI (match_dup 0)
4345                  (const_int 1)))]
4346   "")
4349 ;; Bitwise not (one's complement) instructions.
4352 (define_insn "one_cmplqi2"
4353   [(set (match_operand:QI 0 "nonimmediate_operand"   "=g,roR, rS")
4354         (not:QI (match_operand:QI 1 "general_operand" "0, rS,roR")))]
4355   ""
4356   "@
4357    not\\t%0
4358    not\\tw,%1\;mov\\t%0,w
4359    not\\tw,%1\;mov\\t%0,w"
4360   [(set_attr "skip" "yes,no,no")
4361    (set_attr "clobberw" "no,yes,yes")])
4363 (define_insn_and_split "one_cmplhi2"
4364   [(set (match_operand:HI 0 "nonimmediate_operand"   "=ro,&ro,&rS")
4365         (not:HI (match_operand:HI 1 "general_operand"  "0, rS, ro")))]
4366   ""
4367   "#"
4368   "(ip2k_reorg_split_himode)"
4369   [(set (match_dup 3)
4370         (not:QI (match_dup 4)))
4371    (set (match_dup 5)
4372         (not:QI (match_dup 6)))]
4373   "{
4374     operands[3] = ip2k_get_high_half (operands[0], QImode);
4375     operands[4] = ip2k_get_high_half (operands[1], QImode);
4376     operands[5] = ip2k_get_low_half (operands[0], QImode);
4377     operands[6] = ip2k_get_low_half (operands[1], QImode);
4378   }")
4380 (define_insn_and_split "one_cmplsi2"
4381   [(set (match_operand:SI 0 "nonimmediate_operand"   "=ro,&ro,&rS")
4382         (not:SI (match_operand:SI 1 "general_operand"  "0, rS, ro")))]
4383   ""
4384   "#"
4385   "(ip2k_reorg_split_simode)"
4386   [(set (match_dup 3)
4387         (not:HI (match_dup 4)))
4388    (set (match_dup 5)
4389         (not:HI (match_dup 6)))]
4390   "{
4391     operands[3] = ip2k_get_high_half (operands[0], HImode);
4392     operands[4] = ip2k_get_high_half (operands[1], HImode);
4393     operands[5] = ip2k_get_low_half (operands[0], HImode);
4394     operands[6] = ip2k_get_low_half (operands[1], HImode);
4395   }")
4397 (define_insn_and_split "one_cmpldi2"
4398   [(set (match_operand:DI 0 "nonimmediate_operand"   "=ro,&ro,&rS")
4399         (not:DI (match_operand:DI 1 "general_operand"  "0, rS, ro")))]
4400   ""
4401   "#"
4402   "(ip2k_reorg_split_dimode)"
4403   [(set (match_dup 3)
4404         (not:SI (match_dup 4)))
4405    (set (match_dup 5)
4406         (not:SI (match_dup 6)))]
4407   "{
4408     operands[3] = ip2k_get_high_half (operands[0], SImode);
4409     operands[4] = ip2k_get_high_half (operands[1], SImode);
4410     operands[5] = ip2k_get_low_half (operands[0], SImode);
4411     operands[6] = ip2k_get_low_half (operands[1], SImode);
4412   }")
4415 ;; Sign extension instructions.
4418 (define_insn "*push_extendqihi2"
4419   [(set (match_operand:HI 0 "push_operand"                     "=<,<")
4420         (sign_extend:HI (match_operand:QI 1 "general_operand" "roR,n")))]
4421   ""
4422   "@
4423    push\\t%1%<\;push\\t#0%<\;snb\\t%1,7\;not\\t1(SP)%>%>
4424    push\\t%L1\;push\\t%H1"
4425   [(set_attr "clobberw" "no,no")])
4427 (define_insn "extendqihi2"
4428   [(set (match_operand:HI 0 "nonimmediate_operand"            "=rS,ro,ro")
4429         (sign_extend:HI (match_operand:QI 1 "general_operand" "roR,rS, n")))]
4430   ""
4431   "*{
4432     switch (which_alternative)
4433       {
4434       case 0:
4435       case 1:
4436         if (register_operand (operands[0], HImode)
4437             && register_operand (operands[1], QImode)
4438             && REGNO (operands[0]) == (REGNO (operands[1]) - 1))
4439           return AS1 (clr, %H0) CR_TAB
4440                  AS2 (snb, %1, 7) CR_TAB
4441                  AS1 (not, %H0);
4442         else
4443           return AS2 (mov, w, %1) CR_TAB
4444                  AS2 (mov, %L0, w) CR_TAB
4445                  AS1 (clr, %H0) CR_TAB
4446                  AS2 (snb, wreg, 7) CR_TAB
4447                  AS1 (not, %H0);
4449       case 2:
4450         return AS2 (mov, w, %L1) CR_TAB
4451                AS2 (mov, %L0, w) CR_TAB
4452                AS2 (mov, w, %H1) CR_TAB
4453                AS2 (mov, %H0, w);
4454       default:
4455         abort ();
4456       }
4457   }")
4459 (define_insn "*push_extendhisi2"
4460   [(set (match_operand:SI 0 "push_operand"                     "=<,<,<")
4461         (sign_extend:SI (match_operand:HI 1 "general_operand" "roS,n,s")))]
4462   ""
4463   "@
4464    push\\t%L1%<\;push\\t%H1%<\;clr\\twreg\;snb\\t%H1,7\;not\\twreg\;push\\twreg\;push\\twreg%>%>
4465    push\\t%D1\;push\\t%C1\;push\\t%B1\;push\\t%A1
4466    push\\t%L1\;push\\t%H1\;push\\t#0\;push\\t#0"
4467   [(set_attr "clobberw" "yes,no,no")])
4469 (define_insn "extendhisi2"
4470   [(set (match_operand:SI 0 "nonimmediate_operand"           "=ro,rS,ro,ro")
4471         (sign_extend:SI (match_operand:HI 1 "general_operand" "rS,ro, n, s")))]
4472   ""
4473   "@
4474    mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\twreg\;snb\\t%C0,7\;not\\twreg\;mov\\t%B0,w\;mov\\t%A0,w
4475    mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\twreg\;snb\\t%C0,7\;not\\twreg\;mov\\t%B0,w\;mov\\t%A0,w
4476    mov\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A1\;mov\\t%A0,w
4477    mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\t%B0\;clr\\t%A0")
4479 (define_insn "*push_extendqisi2"
4480   [(set (match_operand:SI 0 "push_operand"                     "=<,<")
4481         (sign_extend:SI (match_operand:QI 1 "general_operand" "roR,n")))]
4482   ""
4483   "@
4484    push\\t%1%<\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;push\\twreg\;push\\twreg\;push\\twreg%>
4485    push\\t%D1\;push\\t%C1\;push\\t%B1\;push\\t%A1"
4486   [(set_attr "clobberw" "yes,no")])
4488 (define_insn "extendqisi2"
4489   [(set (match_operand:SI 0 "nonimmediate_operand"           "=ro, rS,ro")
4490         (sign_extend:SI (match_operand:QI 1 "general_operand" "rS,roR, n")))]
4491   ""
4492   "@
4493    mov\\tw,%1\;mov\\t%D0,w\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;mov\\t%C0,w\;mov\\t%B0,w\;mov\\t%A0,w
4494    mov\\tw,%1\;mov\\t%D0,w\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;mov\\t%C0,w\;mov\\t%B0,w\;mov\\t%A0,w
4495    mov\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A1\;mov\\t%A0,w")
4498 ;; Zero extension instructions.
4501 (define_insn "*push_zero_extendqihi2"
4502   [(set (match_operand:HI 0 "push_operand"                      "=<")
4503         (zero_extend:HI (match_operand:QI 1 "general_operand" "roRi")))]
4504   ""
4505   "push\\t%1\;push\\t#0"
4506   [(set_attr "clobberw" "no")])
4508 (define_insn_and_split "zero_extendqihi2"
4509   [(set (match_operand:HI 0 "nonimmediate_operand"            "=ro,  rS")
4510         (zero_extend:HI (match_operand:QI 1 "general_operand" "rSi,roRi")))]
4511   ""
4512   "#"
4513   "ip2k_reorg_completed"
4514   [(set (match_dup 3) (match_dup 1))
4515    (set (match_dup 2) (const_int 0))]
4516   "{
4517     operands[2] = ip2k_get_high_half (operands[0], QImode);
4518     operands[3] = ip2k_get_low_half (operands[0], QImode);
4519   }")
4521 (define_insn "*push_zero_extendhisi2"
4522   [(set (match_operand:SI 0 "push_operand"                      "=<")
4523         (zero_extend:SI (match_operand:HI 1 "general_operand" "roSi")))]
4524   ""
4525   "push\\t%L1%<\;push\\t%H1%>\;push\\t#0\;push\\t#0")
4527 (define_insn_and_split "zero_extendhisi2"
4528   [(set (match_operand:SI 0 "nonimmediate_operand"            "=ro, rS")
4529         (zero_extend:SI (match_operand:HI 1 "general_operand" "rSi,roi")))]
4530   ""
4531   "#"
4532   "ip2k_reorg_completed"
4533   [(set (match_dup 3) (match_dup 1))
4534    (set (match_dup 2) (const_int 0))]
4535   "{
4536     operands[2] = ip2k_get_high_half (operands[0], HImode);
4537     operands[3] = ip2k_get_low_half (operands[0], HImode);
4538   }")
4540 (define_insn "*push_zero_extendqisi2"
4541   [(set (match_operand:SI 0 "push_operand"                      "=<")
4542         (zero_extend:SI (match_operand:QI 1 "general_operand" "roRi")))]
4543   ""
4544   "push\\t%1\;push\\t#0\;push\\t#0\;push\\t#0"
4545   [(set_attr "clobberw" "no")])
4547 (define_insn_and_split "zero_extendqisi2"
4548   [(set (match_operand:SI 0 "nonimmediate_operand"            "=ro,  rS")
4549         (zero_extend:SI (match_operand:QI 1 "general_operand" "rSi,roRi")))]
4550   ""
4551   "#"
4552   "ip2k_reorg_completed"
4553   [(set (match_dup 3) (zero_extend:HI (match_dup 1)))
4554    (set (match_dup 2) (const_int 0))]
4555   "{
4556     operands[2] = ip2k_get_high_half (operands[0], HImode);
4557     operands[3] = ip2k_get_low_half (operands[0], HImode);
4558   }")
4560 (define_insn "*push_zero_extendsidi2"
4561   [(set (match_operand:DI 0 "push_operand"                      "=<")
4562         (zero_extend:DI (match_operand:SI 1 "general_operand" "roSi")))]
4563   ""
4564   "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%>%>%>\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0")
4566 (define_insn_and_split "zero_extendsidi2"
4567   [(set (match_operand:DI 0 "nonimmediate_operand"            "=ro, rS")
4568         (zero_extend:DI (match_operand:SI 1 "general_operand" "rSi,roi")))]
4569   ""
4570   "#"
4571   "ip2k_reorg_completed"
4572   [(set (match_dup 3) (match_dup 1))
4573    (set (match_dup 2) (const_int 0))]
4574   "{
4575     operands[2] = ip2k_get_high_half (operands[0], SImode);
4576     operands[3] = ip2k_get_low_half (operands[0], SImode);
4577   }")
4579 (define_insn "*push_zero_extendhidi2"
4580   [(set (match_operand:DI 0 "push_operand"                      "=<")
4581         (zero_extend:DI (match_operand:HI 1 "general_operand" "roSi")))]
4582   ""
4583   "push\\t%L1%<\;push\\t%H1%>\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0"
4584   [(set_attr "clobberw" "no")])
4586 (define_insn_and_split "zero_extendhidi2"
4587   [(set (match_operand:DI 0 "nonimmediate_operand"            "=ro, rS")
4588         (zero_extend:DI (match_operand:HI 1 "general_operand" "rSi,roi")))]
4589   ""
4590   "#"
4591   "ip2k_reorg_completed"
4592   [(set (match_dup 3) (zero_extend:SI (match_dup 1)))
4593    (set (match_dup 2) (const_int 0))]
4594   "{
4595     operands[2] = ip2k_get_high_half (operands[0], SImode);
4596     operands[3] = ip2k_get_low_half (operands[0], SImode);
4597   }")
4599 (define_insn "*push_zero_extendqidi2"
4600   [(set (match_operand:DI 0 "push_operand"                      "=<")
4601         (zero_extend:DI (match_operand:QI 1 "general_operand" "roRi")))]
4602   ""
4603   "push\\t%1\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0"
4604   [(set_attr "clobberw" "no")])
4606 (define_insn_and_split "zero_extendqidi2"
4607   [(set (match_operand:DI 0 "nonimmediate_operand"            "=ro,  rS")
4608         (zero_extend:DI (match_operand:QI 1 "general_operand" "rSi,roRi")))]
4609   ""
4610   "#"
4611   "ip2k_reorg_completed"
4612   [(set (match_dup 3) (zero_extend:SI (match_dup 1)))
4613    (set (match_dup 2) (const_int 0))]
4614   "{
4615     operands[2] = ip2k_get_high_half (operands[0], SImode);
4616     operands[3] = ip2k_get_low_half (operands[0], SImode);
4617   }")
4620 ;; Truncation instructions.
4623 (define_insn "truncsihi2"
4624   [(set (match_operand:HI 0 "nonimmediate_operand"         "=rS, ro")
4625         (truncate:HI (match_operand:SI 1 "general_operand" "roi,rSi")))]
4626   ""
4627   "@
4628    mov\\tw,%D1\;push\\t%C1%<\;pop\\t%H0%>\;mov\\t%L0,w
4629    mov\\tw,%D1\;push\\t%C1%<\;pop\\t%H0%>\;mov\\t%L0,w")
4631 (define_insn "truncsiqi2"
4632   [(set (match_operand:QI 0 "nonimmediate_operand"         "=rS, ro")
4633         (truncate:QI (match_operand:SI 1 "general_operand" "roi,rSi")))]
4634   ""
4635   "@
4636    mov\\tw,%D1\;mov\\t%0,w
4637    mov\\tw,%D1\;mov\\t%0,w")
4639 (define_insn "trunchiqi2"
4640   [(set (match_operand:QI 0 "nonimmediate_operand"         "=rS, ro")
4641         (truncate:QI (match_operand:HI 1 "general_operand" "roi,rSi")))]
4642   ""
4643   "@
4644    mov\\tw,%L1\;mov\\t%0,w
4645    mov\\tw,%L1\;mov\\t%0,w")
4648 ;; Compare with zero (test) instructions.
4650 ;; As we don't have a particularly good set of condition codes we simply
4651 ;; tagging our comparison operands for use later within our "compare
4652 ;; and branch" instructions.
4655 (define_insn "tstqi"
4656   [(set (cc0)
4657         (match_operand:QI 0 "nonimmediate_operand" "roR"))]
4658   ""
4659   "* return ip2k_set_compare (operands[0], const0_rtx);")
4661 (define_insn "tsthi"
4662   [(set (cc0)
4663         (match_operand:HI 0 "nonimmediate_operand" "roS"))]
4664   ""
4665   "* return ip2k_set_compare (operands[0], const0_rtx);")
4667 (define_insn "tstsi"
4668   [(set (cc0)
4669         (match_operand:SI 0 "nonimmediate_operand" "roS"))]
4670   ""
4671   "* return ip2k_set_compare (operands[0], const0_rtx);")
4673 (define_insn "tstdi"
4674   [(set (cc0)
4675         (match_operand:DI 0 "nonimmediate_operand" "roS"))]
4676   ""
4677   "* return ip2k_set_compare (operands[0], const0_rtx);")
4680 ;; General value comparison instructions.
4682 ;; As we don't have a particularly good set of condition codes we simply
4683 ;; tagging our comparison operands for use later within our "compare
4684 ;; and branch" instructions.
4687 (define_insn "cmpqi"
4688   [(set (cc0)
4689         (compare (match_operand:QI 0 "nonimmediate_operand" "roR,  rS")
4690                  (match_operand:QI 1 "general_operand"      "rSn,roRn")))]
4691   ""
4692   "* return ip2k_set_compare (operands[0], operands[1]);")
4694 (define_insn "cmphi"
4695   [(set (cc0)
4696         (compare (match_operand:HI 0 "nonimmediate_operand" "ro, rS")
4697                  (match_operand:HI 1 "general_operand"     "rSn,ron")))]
4698   ""
4699   "* return ip2k_set_compare (operands[0], operands[1]);")
4701 (define_insn "cmpsi"
4702   [(set (cc0)
4703         (compare (match_operand:SI 0 "nonimmediate_operand" "ro, rS")
4704                  (match_operand:SI 1 "general_operand"     "rSn,ron")))]
4705   ""
4706   "* return ip2k_set_compare (operands[0], operands[1]);")
4708 (define_insn "cmpdi"
4709   [(set (cc0)
4710         (compare (match_operand:DI 0 "nonimmediate_operand" "ro, rS")
4711                  (match_operand:DI 1 "general_operand"     "rSn,ron")))]
4712   ""
4713   "* return ip2k_set_compare (operands[0], operands[1]);")
4716 ;; Conditional jump instructions.
4719 (define_expand "beq"
4720   [(set (pc)
4721         (if_then_else (eq (cc0) (const_int 0))
4722                       (label_ref (match_operand 0 "" ""))
4723                       (pc)))]
4724   ""
4725   "")
4727 (define_expand "bne"
4728   [(set (pc)
4729         (if_then_else (ne (cc0) (const_int 0))
4730                       (label_ref (match_operand 0 "" ""))
4731                       (pc)))]
4732   ""
4733   "")
4735 (define_expand "bge"
4736   [(set (pc)
4737         (if_then_else (ge (cc0) (const_int 0))
4738                       (label_ref (match_operand 0 "" ""))
4739                       (pc)))]
4740   ""
4741   "")
4743 (define_expand "bgeu"
4744   [(set (pc)
4745         (if_then_else (geu (cc0) (const_int 0))
4746                       (label_ref (match_operand 0 "" ""))
4747                       (pc)))]
4748   ""
4749   "")
4751 (define_expand "blt"
4752   [(set (pc)
4753         (if_then_else (lt (cc0) (const_int 0))
4754                       (label_ref (match_operand 0 "" ""))
4755                       (pc)))]
4756   ""
4757   "")
4759 (define_expand "bltu"
4760   [(set (pc)
4761         (if_then_else (ltu (cc0) (const_int 0))
4762                       (label_ref (match_operand 0 "" ""))
4763                       (pc)))]
4764   ""
4765   "")
4768 (define_expand "ble"
4769   [(set (pc)
4770         (if_then_else (le (cc0) (const_int 0))
4771                       (label_ref (match_operand 0 "" ""))
4772                       (pc)))]
4773   ""
4774   "")
4776 (define_expand "bleu"
4777   [(set (pc)
4778         (if_then_else (leu (cc0) (const_int 0))
4779                       (label_ref (match_operand 0 "" ""))
4780                       (pc)))]
4781   ""
4782   "")
4784 (define_expand "bgt"
4785   [(set (pc)
4786         (if_then_else (gt (cc0) (const_int 0))
4787                       (label_ref (match_operand 0 "" ""))
4788                       (pc)))]
4789   ""
4790   "")
4792 (define_expand "bgtu"
4793   [(set (pc)
4794         (if_then_else (gtu (cc0) (const_int 0))
4795                       (label_ref (match_operand 0 "" ""))
4796                       (pc)))]
4797   ""
4798   "")
4801 ;; Implementation of conditional jumps.
4803 ;; The assumption is that a previous test or compare instruction will have
4804 ;; provided the arguments to be compared to form cc0 and then we perform
4805 ;; a compare and branch operation here.
4807 (define_insn "*unsigned_cmp_branch"
4808   [(set (pc)
4809         (if_then_else (match_operator 1 "ip2k_unsigned_comparison_operator"
4810                         [(cc0)
4811                          (const_int 0)])
4812                       (label_ref (match_operand 0 "" ""))
4813                       (pc)))]
4814   ""
4815   "* return ip2k_gen_unsigned_comp_branch (insn, GET_CODE (operands[1]),
4816                                            operands[0]);")
4818 ;; Signed branches use Z, N or synthesized V.
4819 ;; result is generated as 0 (LT), 1 (EQ), 2 (GT)
4821 (define_insn "*signed_cmp_branch"
4822   [(set (pc)
4823         (if_then_else (match_operator 1 "ip2k_signed_comparison_operator"
4824                         [(cc0)
4825                          (const_int 0)])
4826                       (label_ref (match_operand 0 "" ""))
4827                       (pc)))]
4828   ""
4829   "* return ip2k_gen_signed_comp_branch (insn, GET_CODE (operands[1]),
4830                                          operands[0]);")
4832 ;; Reverse branch - reverse our comparison condition so that we can
4833 ;; branch in the opposite sense.
4835 (define_insn_and_split "*rvbranch"
4836   [(set (pc)
4837         (if_then_else (match_operator 1 "comparison_operator" [(cc0)
4838                                                                (const_int 0)])
4839                       (pc)
4840                       (label_ref (match_operand 0 "" ""))))]
4841   ""
4842   "#"
4843   "reload_completed"
4844   [(set (pc)
4845         (if_then_else (match_dup 2)
4846                       (label_ref (match_operand 0 "" ""))
4847                       (pc)))]
4848   "{
4849     operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[1])),
4850                            GET_MODE (operands[1]),
4851                            cc0_rtx, const0_rtx);
4852    }")
4854 ;; This is a bit test and jump sequence.
4856 (define_insn "*bit_cmpqi_branch"
4857   [(set (pc)
4858         (if_then_else (match_operator 0 "comparison_operator"
4859                         [(zero_extract
4860                            (match_operand:QI 1 "nonimmediate_operand" "roR")
4861                            (const_int 1)
4862                            (match_operand 2 "immediate_operand" "i"))
4863                          (const_int 0)])
4864                       (label_ref (match_operand 3 "" ""))
4865                       (pc)))]
4866   "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)"
4867   "*{
4868     if (GET_CODE (operands[0]) == EQ)
4869       OUT_AS2 (sb, %1, %b2);
4870     else
4871       OUT_AS2 (snb, %1, %b2);
4872     return AS1 (page, %3) CR_TAB
4873            AS1 (jmp, %3);
4874   }"
4875   [(set_attr "clobberw" "no")])
4877 ;; This is a bit test and jump sequence but for 16-bit operands.  It's pretty
4878 ;; certain that there must be a way to do this using a zero_extract operation,
4879 ;; but this didn't seem to want to work so we use a bitwise and instead.  This
4880 ;; is exactly as efficient but the combiner handles this OK - the implementation
4881 ;; here isn't quite as nice though.
4883 (define_insn "*bit_cmphi_branch"
4884   [(set
4885     (pc)
4886     (if_then_else
4887      (match_operator 0 "comparison_operator"
4888                      [(and:HI (match_operand:HI 1 "nonimmediate_operand" "roS")
4889                               (match_operand    2 "const_int_operand"    "n"))
4890                       (const_int 0)])
4891      (label_ref (match_operand 3 "" ""))
4892      (pc)))]
4893   "((GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
4894     && find_one_set_bit_p (INTVAL (operands[2])) != -1)"
4895   "*{
4896     int bp = find_one_set_bit_p (INTVAL (operands[2]));
4897     if (INTVAL (operands[2]) >= 8)
4898       operands[4] = GEN_INT (bp - 8);
4899     else
4900       operands[4] = GEN_INT (bp);
4902     if (GET_CODE (operands[0]) == EQ)
4903       {
4904         if (INTVAL (operands[2]) >= 8)
4905           OUT_AS2 (sb, %H1, %b4);
4906         else
4907           OUT_AS2 (sb, %L1, %b4);
4908       }
4909     else
4910       {
4911         if (INTVAL (operands[2]) >= 8)
4912           OUT_AS2 (snb, %H1, %b4);
4913         else
4914           OUT_AS2 (snb, %L1, %b4);
4915       }
4916     return AS1 (page, %3) CR_TAB
4917            AS1 (jmp, %3);
4918   }"
4919   [(set_attr "clobberw" "no")])
4921 ;; Add two operands, compare with a third and branch if equal or not-equal.
4923 (define_insn "*add_and_comp_branch"
4924   [(set
4925     (pc)
4926     (if_then_else
4927      (match_operator 0 "comparison_operator"
4928                      [(plus:HI
4929                        (match_operand:HI 1 "nonimmediate_operand" "ro, rS, rS")
4930                        (match_operand:HI 2 "general_operand"    "rSn,ron,rSn"))
4931                       (match_operand:HI 3 "general_operand"    "rSn,rSn,ron")])
4932      (label_ref (match_operand 4 "" ""))
4933      (pc)))]
4934   "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)"
4935   "*{
4936     OUT_AS2 (mov, w, %L2);
4937     OUT_AS2 (add, w, %L1);
4938     OUT_AS2 (cse, w, %L3);
4939     if (GET_CODE (operands[0]) == EQ)
4940       {
4941         OUT_AS1 (page, 1f);
4942         OUT_AS1 (jmp, 1f);
4943       }
4944     else
4945       {
4946         OUT_AS1 (page, %4);
4947         OUT_AS1 (jmp, %4);
4948       }
4949     OUT_AS2 (mov, w, %H2);
4950     OUT_AS2 (addc, w, %H1);
4951     if (GET_CODE (operands[0]) == EQ)
4952       OUT_AS2 (csne, w, %H3);
4953     else
4954       OUT_AS2 (cse, w, %H3);
4955     OUT_AS1 (page, %4);
4956     OUT_AS1 (jmp, %4);
4957     return AS1 (1:, );
4958   }")
4960 ;; Unconditional jump
4962 (define_insn "jump"
4963   [(set (pc)
4964         (label_ref (match_operand 0 "" "")))]
4965   ""
4966   "page\\t%0\;jmp\\t%0"
4967   [(set_attr "clobberw" "no")])
4969 ;; Indirect jump
4971 (define_insn "indirect_jump"
4972   [(set (pc) (match_operand:HI 0 "nonimmediate_operand" "ro"))]
4973   ""
4974   "page\\t1f\;call\\t1f\;1:mov\\tw,%H0\;mov\\tcallh,w\;mov\\tw,%L0\;mov\\tcalll,w\;ret")
4977 ;; Function call instructions.
4980 (define_expand "call"
4981   [(call (match_operand 0 "" "")
4982          (match_operand:HI 1 "" ""))]
4983   ""
4984   "")
4986 (define_insn "*call"
4987   [(call (mem:HI (match_operand:HI 0 "general_operand" "i,roS"))
4988          (match_operand:HI 1 "" ""))]
4989   ""
4990   "@
4991    page\\t%b0\;call\\t%b0
4992    push\\t%L0%<\;push\\t%H0%>\;page\\t__indcall\;call\\t__indcall")
4994 (define_expand "call_pop"
4995   [(parallel [(call (match_operand 0 "" "")
4996                     (match_operand:HI 1 "" ""))
4997               (set (reg:HI 6)
4998                    (plus:HI (reg:HI 6)
4999                             (match_operand:HI 3 "immediate_operand" "")))])]
5000   ""
5001   "")
5003 (define_insn "*call_pop"
5004   [(call (mem:HI (match_operand:HI 0 "general_operand" "i,roS"))
5005          (match_operand:HI 1 "" ""))
5006    (set (reg:HI 6)
5007         (plus:HI (reg:HI 6)
5008                  (match_operand:HI 2 "immediate_operand" "")))]
5009   ""
5010   "@
5011    page\\t%b0\;call\\t%b0
5012    push\\t%L0%<\;push\\t%H0%>\;page\\t__indcall\;call\\t__indcall")
5014 ;; Undo any splitting of operands that lead to redundant movhi3 instructions.
5016 (define_peephole2
5017   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
5018         (match_operand 1 "nonimmediate_operand" ""))
5019    (parallel [(call (mem:HI (match_dup 0))
5020                     (match_operand:HI 2 "" ""))
5021               (set (reg:HI 6)
5022                    (plus:HI (reg:HI 6)
5023                             (match_operand:HI 3 "immediate_operand" "")))])]
5024   ""
5025   [(parallel [(call (mem:HI (match_dup 1))
5026                     (match_dup 2))
5027               (set (reg:HI 6)
5028                    (plus:HI (reg:HI 6)
5029                             (match_dup 3)))])]
5030   "")
5032 (define_expand "call_value"
5033   [(set (match_operand 0 "" "")
5034         (call (match_operand 1 "" "")
5035               (match_operand:HI 2 "" "")))]
5036   ""
5037   "")
5039 (define_insn "*call_value"
5040   [(set (match_operand 0 "" "")
5041         (call (mem:HI (match_operand:HI 1 "general_operand" "i,roS"))
5042               (match_operand:HI 2 "" "")))]
5043   ""
5044   "@
5045    page\\t%b1\;call\\t%b1
5046    push\\t%L1%<\;push\\t%H1%>\;page\\t__indcall\;call\\t__indcall")
5048 (define_expand "call_value_pop"
5049   [(parallel [(set (match_operand 0 "" "")
5050                    (call (match_operand 1 "" "")
5051                          (match_operand:HI 2 "" "")))
5052               (set (reg:HI 6)
5053                    (plus:HI (reg:HI 6)
5054                             (match_operand:HI 4 "immediate_operand" "")))])]
5055   ""
5056   "")
5058 (define_insn "*call_value_pop"
5059   [(set (match_operand 0 "" "")
5060         (call (mem:HI (match_operand:HI 1 "general_operand" "i,roS"))
5061               (match_operand:HI 2 "" "")))
5062    (set (reg:HI 6)
5063         (plus:HI (reg:HI 6)
5064                  (match_operand:HI 3 "immediate_operand" "")))]
5065   ""
5066   "@
5067    page\\t%b1\;call\\t%b1
5068    push\\t%L1%<\;push\\t%H1%>\;page\\t__indcall\;call\\t__indcall")
5070 ;; Undo any splitting of operands that lead to redundant movhi3 instructions.
5072 (define_peephole2
5073   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
5074         (match_operand 1 "nonimmediate_operand" ""))
5075    (parallel [(set (match_operand 2 "" "")
5076                    (call (mem:HI (match_dup 0))
5077                          (match_operand:HI 3 "" "")))
5078               (set (reg:HI 6)
5079                    (plus:HI (reg:HI 6)
5080                             (match_operand:HI 4 "immediate_operand" "")))])]
5081   ""
5082   [(parallel [(set (match_dup 2)
5083                    (call (mem:HI (match_dup 1))
5084                          (match_dup 3)))
5085               (set (reg:HI 6)
5086                    (plus:HI (reg:HI 6)
5087                             (match_dup 4)))])]
5088   "")
5090 ;; Nop instruction.
5092 ;; We don't really want nops to appear in our code so just insert a comment.
5094 (define_insn "nop"
5095   [(const_int 0)]
5096   ""
5097   "; nop")
5100 ;; SEQ instruction
5102 (define_insn "seq"
5103   [(set (match_operand:QI 0 "register_operand" "=r")
5104         (eq:QI (cc0) (const_int 0)))]
5105   ""
5106   "* return ip2k_gen_sCOND (insn, EQ, operands[0]);")
5108 ;; Tweak SEQ if we can adjust the output operand.  Note that we have to do
5109 ;; this via a peephole because we need to ensure that any reloads have taken
5110 ;; place before we try to do this.  If there's a reload in order to get our
5111 ;; actual result operand then this peephole won't match.
5113 (define_peephole
5114   [(set (match_operand:QI 0 "register_operand" "")
5115         (eq:QI (cc0) (const_int 0)))
5116    (set (reg:QI 10)
5117         (match_dup 0))
5118    (set (match_operand:QI 1 "nonimmediate_operand" "")
5119         (reg:QI 10))]
5120   "find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
5121   "* return ip2k_gen_sCOND (insn, EQ, operands[1]);")
5123 ;; Another peephole match handles the same merge as above but for cases where
5124 ;; we're emulating memory accesses via IP and an offset.
5126 (define_peephole
5127   [(set (match_operand:QI 0 "register_operand" "")
5128         (eq:QI (cc0) (const_int 0)))
5129    (set (reg:QI 10)
5130         (match_dup 0))
5131    (set (mem:QI (plus:HI (reg:HI 4)
5132                          (match_operand:QI 1 "const_int_operand" "")))
5133         (reg:QI 10))]
5134   "(find_regno_note (insn, REG_DEAD, REGNO (operands[0]))
5135     && (INTVAL (operands[1]) < 0x100))"
5136   "*{
5137       if (INTVAL (operands[1]) == 1)
5138         OUT_AS1 (inc, ipl);
5139       else
5140         {
5141           OUT_AS2 (mov, w, %1);
5142           OUT_AS2 (add, ipl, w);
5143         }
5144       ip2k_gen_sCOND (insn, EQ,
5145                       gen_rtx_MEM (QImode, gen_rtx_REG (HImode, REG_IP)));
5146       if (find_regno_note (insn, REG_DEAD, REG_IP))
5147         {
5148           if (INTVAL (operands[1]) == 1)
5149             OUT_AS1 (dec, ipl);
5150           else
5151             {
5152               OUT_AS2 (mov, w, %1);
5153               OUT_AS2 (sub, ipl, w);
5154             }
5155         }
5156       return \"\";
5157   }")
5159 ;; SNE instruction
5161 (define_insn "sne"
5162   [(set (match_operand:QI 0 "register_operand" "=r")
5163         (ne:QI (cc0) (const_int 0)))]
5164   ""
5165   "* return ip2k_gen_sCOND (insn, NE, operands[0]);")
5167 ;; Tweak SNE if we can adjust the output operand.  Note that we have to do
5168 ;; this via a peephole because we need to ensure that any reloads have taken
5169 ;; place before we try to do this.  If there's a reload in order to get our
5170 ;; actual result operand then this peephole won't match.
5172 (define_peephole
5173   [(set (match_operand:QI 0 "register_operand" "")
5174         (ne:QI (cc0) (const_int 0)))
5175    (set (reg:QI 10)
5176         (match_dup 0))
5177    (set (match_operand:QI 1 "nonimmediate_operand" "")
5178         (reg:QI 10))]
5179   "find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))"
5180   "* return ip2k_gen_sCOND (insn, NE, operands[1]);")
5182 ;; Another peephole match handles the same merge as above but for cases where
5183 ;; we're emulating memory accesses via IP and an offset.
5185 (define_peephole
5186   [(set (match_operand:QI 0 "register_operand" "")
5187         (ne:QI (cc0) (const_int 0)))
5188    (set (reg:QI 10)
5189         (match_dup 0))
5190    (set (mem:QI (plus:HI (reg:HI 4)
5191                          (match_operand:QI 1 "const_int_operand" "")))
5192         (reg:QI 10))]
5193   "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))
5194     && (INTVAL (operands[1]) < 0x100))"
5195   "*{
5196       if (INTVAL (operands[1]) == 1)
5197         OUT_AS1 (inc, ipl);
5198       else
5199         {
5200           OUT_AS2 (mov, w, %1);
5201           OUT_AS2 (add, ipl, w);
5202         }
5203       ip2k_gen_sCOND (insn, NE,
5204                       gen_rtx_MEM (QImode, gen_rtx_REG (HImode, REG_IP)));
5205       if (find_regno_note (insn, REG_DEAD, REG_IP))
5206         {
5207           if (INTVAL (operands[1]) == 1)
5208             OUT_AS1 (dec, ipl);
5209           else
5210             {
5211               OUT_AS2 (mov, w, %1);
5212               OUT_AS2 (sub, ipl, w);
5213             }
5214         }
5215       return \"\";
5216   }")
5220 ;; Case Dispatch Table Support.
5222 ;; Called with 5 arguments:
5224 ;; 0. case index
5225 ;; 1. lower bound (const_int)
5226 ;; 2. range (const_int)
5227 ;; 3. label before dispatch table
5228 ;; 4. out-of-bounds label
5230 ;; With the IP2k we actually really want to do a caseqi but that
5231 ;; doesn't exist so we cheat and make it look (to the core of gcc)
5232 ;; like we're going to do the SImode stuff but then truncate it
5233 ;; away when it's no longer looking :-)
5235 (define_expand "casesi"
5236   [(set (match_dup 5)
5237         (truncate:QI (match_operand:SI 0 "general_operand" "g")))
5238    (set (match_dup 5)
5239         (minus:QI (match_dup 5)
5240                   (match_operand 1 "const_int_operand" "n")))
5241    (set (cc0)
5242         (compare (match_dup 5)
5243                  (match_operand 2 "const_int_operand" "n")))
5244    (set (pc)
5245         (if_then_else (gtu (cc0)
5246                            (const_int 0))
5247                       (label_ref (match_operand 4 "" ""))
5248                       (pc)))
5249    (parallel [(set (pc)
5250                    (plus:HI (pc)
5251                             (zero_extend:HI (match_dup 5))))
5252               (use (label_ref (match_operand 3 "" "")))
5253               (use (match_dup 2))])]
5254   ""
5255   "{
5256     operands[5] = gen_reg_rtx (QImode);
5257   }")
5259 ;; There are TWO instructions per dispatch entry (page & jump), so we
5260 ;; multiply by two even though our RTL only indicates a simple addition.
5261 ;; Subsequent linker relaxation may well restore this back to what the
5262 ;; RTL says though!
5264 ;; Note that we handle tables with 128 or more entries differently!
5266 (define_insn "*casedispatch"
5267   [(set (pc)
5268         (plus:HI (pc) (zero_extend:HI
5269                        (match_operand:QI 2 "nonimmediate_operand" "roR,roR"))))
5270    (use (label_ref (match_operand 0 "" "")))
5271    (use (match_operand 1 "const_int_operand"                        "K,  n"))]
5272   ""
5273   "@
5274    mov\\tw,%2\;add\\tw,wreg\;add\\tpcl,w
5275    mov\\tw,%2\;push\\t%0%<\;push\\t#0%<\;add\\tw,wreg\;snc\;inc\\t1(SP)\;add\\t2(SP),w\;snc\;inc\\t1(SP)\;page\\t__indcall\;jmp\\t__indcall%>%>")
5277 ;; Handle cleaning up the switch statement stuff.  We can eliminate some
5278 ;; register moves in some cases.  Note that our pattern is slightly different
5279 ;; to the casesi pattern because our minus has become a plus!
5281 ;; Note that as of 07-FEB-2002 we must have this pattern as it is because
5282 ;; linker relaxation will not work any other way.
5284 (define_peephole
5285   [(set (reg:QI 10)
5286         (plus:QI (match_operand 5 "nonimmediate_operand" "rS,rS,rS,rS")
5287                   (match_operand 1 "const_int_operand"    "M, n, M, n")))
5288    (set (match_operand:QI 0 "register_operand"           "+r, r, r, r")
5289         (reg:QI 10))
5290    (set (cc0)
5291         (compare (match_dup 0)
5292                  (match_operand 2 "const_int_operand"     "K, K, n, n")))
5293    (set (pc)
5294         (if_then_else (gtu (cc0)
5295                            (const_int 0))
5296                       (label_ref (match_operand 4 "" ""))
5297                       (pc)))
5298    (parallel [(set (pc)
5299                    (plus:HI (pc)
5300                             (zero_extend:HI (match_dup 0))))
5301               (use (label_ref (match_operand 3 "" "")))
5302               (use (match_dup 2))])]
5303   "(INTVAL (operands[1]) != 0
5304     && find_regno_note (insn, REG_DEAD, REGNO (operands[0])))"
5305   "*{
5306     switch (which_alternative)
5307       {
5308       case 0:
5309       case 2:
5310         OUT_AS2 (dec, w, %5);
5311         break;
5313       case 1:
5314       case 3:
5315         OUT_AS2 (mov, w, %1);
5316         OUT_AS2 (add, w, %5);
5317         break;
5318       default:
5319         abort ();
5320       }
5322     OUT_AS2 (cmp, w, %2);
5323     OUT_AS1 (sc, );
5324     OUT_AS1 (page, %4);
5325     OUT_AS1 (jmp, %4);
5327     switch (which_alternative)
5328       {
5329       case 0:
5330       case 1:
5331         OUT_AS2 (add, w, WREG);
5332         OUT_AS2 (add, pcl, w);
5333         return \"\";
5335       case 2:
5336       case 3:
5337         OUT_AS1 (push, %0%<);
5338         OUT_AS1 (push, #0%<);
5339         OUT_AS2 (add, w, WREG);
5340         OUT_AS1 (snc, );
5341         OUT_AS1 (inc, 1(SP));
5342         OUT_AS2 (add, 2(SP), w);
5343         OUT_AS1 (snc, );
5344         OUT_AS1 (inc, 1(SP));
5345         OUT_AS1 (page, __indcall);
5346         OUT_AS1 (jmp, __indcall%>%>);
5347         return \"\";
5348       default:
5349         abort ();
5350       }
5351   }")
5353 (define_peephole
5354   [(set (cc0)
5355         (compare (match_operand:QI 0 "nonimmediate_operand" "rS,rS")
5356                  (match_operand 1 "const_int_operand"        "K, n")))
5357    (set (pc)
5358         (if_then_else (gtu (cc0)
5359                            (const_int 0))
5360                       (label_ref (match_operand 2 "" ""))
5361                       (pc)))
5362    (parallel [(set (pc)
5363                    (plus:HI (pc)
5364                             (zero_extend:HI (match_dup 0))))
5365               (use (label_ref (match_operand 3 "" "")))
5366               (use (match_dup 1))])]
5367   ""
5368   "@
5369    mov\\tw,%0\;cmp\\tw,%1\;sc\;page\\t%2\;jmp\\t%2\;add\\tw,wreg\;add\\tpcl,w
5370    mov\\tw,%0\;cmp\\tw,%1\;sc\;page\\t%2\;jmp\\t%2\;push\\t%0%<\;push\\t#0%<\;add\\tw,wreg\;snc\;inc\\t1(SP)\;add\\t2(SP),w\;snc\;inc\\t1(SP)\;page\\t__indcall\;jmp\\t__indcall%>%>")
5372 (define_peephole
5373   [(set (match_operand:HI 0 "nonimmediate_operand" "+roR")
5374         (plus:HI (match_dup 0)
5375                  (const_int -1)))
5376    (set (cc0)
5377         (compare (match_dup 0)
5378                  (match_operand 3 "const_int_operand" "n")))
5379    (set (pc)
5380         (if_then_else (match_operator 2 "comparison_operator"
5381                         [(cc0) (const_int 0)])
5382                       (label_ref (match_operand 1 "" ""))
5383                       (pc)))]
5384   "((GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)
5385     && ((INTVAL (operands[3]) == -1) || (INTVAL (operands[3]) == 65535)))"
5386   "*{
5387     OUT_AS2 (mov, w, #255);
5388     OUT_AS2 (add, %L0, w);
5389     if ((GET_CODE (operands[0]) == REG)
5390         && ((REGNO (operands[0]) == REG_DP)
5391             || (REGNO (operands[0]) == REG_IP)
5392             || (REGNO (operands[0]) == REG_SP)))
5393       {
5394         OUT_AS2 (add, %H0, w);
5395       }
5396     else
5397       {
5398         OUT_AS2 (addc, %H0, w);
5399       }
5400     if (GET_CODE (operands[2]) == EQ)
5401       OUT_AS1 (sc, );
5402     else
5403       OUT_AS1 (snc, );
5404     return AS1 (page, %1) CR_TAB
5405            AS1 (jmp, %1);
5406   }")
5408 (define_peephole
5409   [(set (match_operand:QI 0 "nonimmediate_operand" "+rS")
5410         (plus:QI (match_dup 0)
5411                  (const_int -1)))
5412    (set (cc0)
5413         (match_dup 0))
5414    (set (pc)
5415         (if_then_else (match_operator 2 "comparison_operator"
5416                         [(cc0) (const_int 0)])
5417                       (label_ref (match_operand 1 "" ""))
5418                       (pc)))]
5419   "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)"
5420   "*{
5421     if (GET_CODE (operands[2]) == EQ)
5422       OUT_AS1 (decsnz, %0);
5423     else
5424       OUT_AS1 (decsz, %0);
5425     return AS1 (page, %1) CR_TAB
5426            AS1 (jmp, %1);
5427   }")
5429 ;; Handle move and compare-with-zero operations - we can reuse w across
5430 ;; the two operations.
5432 (define_peephole
5433   [(set (reg:QI 10)
5434         (match_operand:QI 1 "nonimmediate_operand"  "rS"))
5435    (set (match_operand:QI 0 "nonimmediate_operand" "=rS")
5436         (reg:QI 10))
5437    (set (cc0)
5438         (match_operand:QI 2 "nonimmediate_operand"  "rS"))
5439    (set (pc)
5440         (if_then_else (match_operator 3 "comparison_operator"
5441                         [(cc0) (const_int 0)])
5442                       (label_ref (match_operand 4 "" ""))
5443                       (pc)))]
5444   "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)
5445     && (rtx_equal_p (operands[0], operands[2])
5446         || rtx_equal_p (operands[1], operands[2])))"
5447   "*{
5448     OUT_AS2 (mov, w, %1);
5449     OUT_AS2 (mov, %0, w);
5450     if (GET_CODE (operands[3]) == EQ)
5451       OUT_AS1 (snz, );
5452     else
5453       OUT_AS1 (sz, );
5454     return AS1 (page, %4) CR_TAB
5455            AS1 (jmp, %4);
5456   }")
5458 ;; Handle move and compare-with-zero operations - we can reuse w across
5459 ;; the two operations.
5461 (define_peephole
5462   [(set (reg:QI 10)
5463         (match_operand:QI 1 "nonimmediate_operand"  "uS"))
5464    (set (match_operand:QI 0 "nonimmediate_operand" "+uS")
5465         (reg:QI 10))
5466    (set (cc0)
5467         (match_operand:SI 2 "nonimmediate_operand"  "uS"))
5468    (set (pc)
5469         (if_then_else (match_operator 3 "comparison_operator"
5470                         [(cc0) (const_int 0)])
5471                       (label_ref (match_operand 4 "" ""))
5472                       (pc)))]
5473   "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)
5474     && (rtx_equal_p (operands[0],
5475                      ip2k_get_high_half (ip2k_get_high_half (operands[2],
5476                                                              HImode), QImode))
5477         || rtx_equal_p (operands[1],
5478                         ip2k_get_high_half (ip2k_get_high_half (operands[2],
5479                                                                 HImode),
5480                                             QImode))))"
5481   "*{
5482     OUT_AS2 (mov, w, %1);
5483     OUT_AS2 (mov, %0, w);
5484     OUT_AS2 (or, w, %B2);
5485     OUT_AS2 (or, w, %C2);
5486     OUT_AS2 (or, w, %D2);
5487     if (GET_CODE (operands[3]) == EQ)
5488       OUT_AS1 (snz, );
5489     else
5490       OUT_AS1 (sz, );
5491     return AS1 (page, %4) CR_TAB
5492            AS1 (jmp, %4);
5493   }")
5495 ;; Handle move and compare-with-zero operations - we can reuse w across
5496 ;; the two operations.
5498 (define_peephole
5499   [(set (reg:QI 10)
5500         (match_operand:QI 1 "nonimmediate_operand"  "uS"))
5501    (set (match_operand:QI 0 "nonimmediate_operand" "+uS")
5502         (reg:QI 10))
5503    (set (cc0)
5504         (match_operand:HI 2 "nonimmediate_operand"  "uS"))
5505    (set (pc)
5506         (if_then_else (match_operator 3 "comparison_operator"
5507                         [(cc0) (const_int 0)])
5508                       (label_ref (match_operand 4 "" ""))
5509                       (pc)))]
5510   "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)
5511     && (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], QImode))
5512         || rtx_equal_p (operands[1], ip2k_get_high_half (operands[2], QImode))
5513         || rtx_equal_p (operands[0], ip2k_get_low_half (operands[2], QImode))
5514         || rtx_equal_p (operands[1], ip2k_get_low_half (operands[2],QImode))))"
5515   "*{
5516     OUT_AS2 (mov, w, %1);
5517     OUT_AS2 (mov, %0, w);
5518     if (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], QImode))
5519         || rtx_equal_p (operands[1], ip2k_get_high_half (operands[2], QImode)))
5520       OUT_AS2 (or, w, %L2);
5521     else
5522       OUT_AS2 (or, w, %H2);
5523     if (GET_CODE (operands[3]) == EQ)
5524       OUT_AS1 (snz, );
5525     else
5526       OUT_AS1 (sz, );
5527     return AS1 (page, %4) CR_TAB
5528            AS1 (jmp, %4);
5529   }")
5531 ;; Handle move and compare-with-zero operations - we can reuse w across
5532 ;; the two operations.
5534 (define_peephole
5535   [(set (match_operand:HI 0 "nonimmediate_operand" "+uo")
5536         (match_operand:HI 1 "nonimmediate_operand"  "uo"))
5537    (set (cc0)
5538         (match_dup 0))
5539    (set (pc)
5540         (if_then_else (match_operator 2 "comparison_operator"
5541                         [(cc0) (const_int 0)])
5542                       (label_ref (match_operand 3 "" ""))
5543                       (pc)))]
5544   "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)"
5545   "*{
5546     OUT_AS2 (mov, w, %H1);
5547     OUT_AS1 (push, %L1%<);
5548     OUT_AS1 (pop, %L0%>);
5549     OUT_AS2 (mov, %H0, w);
5550     OUT_AS2 (or, w, %L0);
5551     if (GET_CODE (operands[2]) == EQ)
5552       OUT_AS1 (snz, );
5553     else
5554       OUT_AS1 (sz, );
5555     return AS1 (page, %3) CR_TAB
5556            AS1 (jmp, %3);
5557   }")
5559 ;; Handle move and compare-with-zero operations - we can reuse w across
5560 ;; the two operations.
5562 (define_peephole
5563   [(set (match_operand:HI 0 "nonimmediate_operand" "+uo")
5564         (match_operand:HI 1 "nonimmediate_operand"  "uo"))
5565    (set (cc0)
5566         (match_dup 1))
5567    (set (pc)
5568         (if_then_else (match_operator 2 "comparison_operator"
5569                         [(cc0) (const_int 0)])
5570                       (label_ref (match_operand 3 "" ""))
5571                       (pc)))]
5572   "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)"
5573   "*{
5574     OUT_AS2 (mov, w, %H1);
5575     OUT_AS1 (push, %L1%<);
5576     OUT_AS1 (pop, %L0%>);
5577     OUT_AS2 (mov, %H0, w);
5578     OUT_AS2 (or, w, %L0);
5579     if (GET_CODE (operands[2]) == EQ)
5580       OUT_AS1 (snz, );
5581     else
5582       OUT_AS1 (sz, );
5583     return AS1 (page, %3) CR_TAB
5584            AS1 (jmp, %3);
5585   }")
5587 (define_peephole
5588   [(set (match_operand:HI 0 "nonimmediate_operand" "+f,bqdo")
5589         (mem:HI (reg:HI 4)))
5590    (set (cc0)
5591         (match_dup 0))
5592    (set (pc)
5593         (if_then_else (match_operator 1 "comparison_operator"
5594                         [(cc0) (const_int 0)])
5595                       (label_ref (match_operand 2 "" ""))
5596                       (pc)))]
5597   "(GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
5598   "*{
5599     switch (which_alternative)
5600       {
5601       case 0:
5602         OUT_AS1 (push, (IP));
5603         OUT_AS1 (inc, ipl);
5604         OUT_AS2 (mov, w, (IP));
5605         OUT_AS2 (mov, ipl, w);
5606         OUT_AS1 (pop, iph);
5607         OUT_AS2 (or, w, iph);
5608         if (GET_CODE (operands[1]) == EQ)
5609           OUT_AS1 (snz, );
5610         else
5611           OUT_AS1 (sz, );
5612         return AS1 (page, %2) CR_TAB
5613                AS1 (jmp, %2);
5615       case 1:
5616         OUT_AS2 (mov, w, (IP));
5617         OUT_AS2 (mov, %H0, w);
5618         OUT_AS1 (inc, ipl);
5619         OUT_AS2 (mov, w, (IP));
5620         OUT_AS2 (mov, %L0, w);
5621         if (!find_regno_note (insn, REG_DEAD, REG_IP))
5622           OUT_AS1 (dec, ipl);
5623         OUT_AS2 (or, w, %H0);
5624         if (GET_CODE (operands[1]) == EQ)
5625           OUT_AS1 (snz, );
5626         else
5627           OUT_AS1 (sz, );
5628         return AS1 (page, %2) CR_TAB
5629                AS1 (jmp, %2);
5630       default:
5631         abort ();
5632       }
5633   }")
5635 (define_peephole
5636   [(set (match_operand:HI 0 "nonimmediate_operand" "+f,bqdo")
5637         (mem:HI (reg:HI 4)))
5638    (set (cc0)
5639         (mem:HI (reg:HI 4)))
5640    (set (pc)
5641         (if_then_else (match_operator 1 "comparison_operator"
5642                         [(cc0) (const_int 0)])
5643                       (label_ref (match_operand 2 "" ""))
5644                       (pc)))]
5645   "(GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
5646   "*{
5647     switch (which_alternative)
5648       {
5649       case 0:
5650         OUT_AS1 (push, (IP));
5651         OUT_AS1 (inc, ipl);
5652         OUT_AS2 (mov, w, (IP));
5653         OUT_AS2 (mov, ipl, w);
5654         OUT_AS1 (pop, iph);
5655         OUT_AS2 (or, w, iph);
5656         if (GET_CODE (operands[1]) == EQ)
5657           OUT_AS1 (snz, );
5658         else
5659           OUT_AS1 (sz, );
5660         return AS1 (page, %2) CR_TAB
5661                AS1 (jmp, %2);
5663       case 1:
5664         OUT_AS2 (mov, w, (IP));
5665         OUT_AS2 (mov, %H0, w);
5666         OUT_AS1 (inc, ipl);
5667         OUT_AS2 (mov, w, (IP));
5668         OUT_AS2 (mov, %L0, w);
5669         if (!find_regno_note (insn, REG_DEAD, REG_IP))
5670           OUT_AS1 (dec, ipl);
5671         OUT_AS2 (or, w, %H0);
5672         if (GET_CODE (operands[1]) == EQ)
5673           OUT_AS1 (snz, );
5674         else
5675           OUT_AS1 (sz, );
5676         return AS1 (page, %2) CR_TAB
5677                AS1 (jmp, %2);
5678       default:
5679         abort ();
5680       }
5681   }")
5683 ;; Handle move-twice and compare-with-zero operations - we can reuse w across
5684 ;; the two operations.
5686 (define_peephole
5687   [(parallel [(set (match_operand:HI 0 "ip2k_gen_operand" "=uS")
5688                    (match_operand:HI 1 "ip2k_gen_operand"  "uS"))
5689               (set (match_operand:HI 2 "ip2k_gen_operand" "=uS")
5690                    (match_dup 1))])
5691    (set (cc0)
5692         (match_dup 0))
5693    (set (pc)
5694         (if_then_else (match_operator 3 "comparison_operator"
5695                         [(cc0) (const_int 0)])
5696                       (label_ref (match_operand 4 "" ""))
5697                       (pc)))]
5698   "(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)"
5699   "*{
5700     if ((REG_P (operands[0])
5701          && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2)
5702               && ip2k_xexp_not_uses_reg_p (operands[2],
5703                                            REGNO (operands[0]), 2)))
5704         || (REG_P (operands[2])
5705             && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2)
5706                  && ip2k_xexp_not_uses_reg_p (operands[1],
5707                                               REGNO (operands[2]), 2))))
5708       {
5709         OUT_AS2 (mov, w, %L1);
5710         OUT_AS1 (push, %H1%<);
5711         OUT_AS1 (push, %H1%<);
5712         OUT_AS1 (pop, %H0%>);
5713         OUT_AS2 (mov, %L0, w);
5714         OUT_AS1 (pop, %H2%>);
5715         OUT_AS2 (mov, %L2, w);
5716         OUT_AS2 (or, w, %H2);
5717         if (GET_CODE (operands[3]) == EQ)
5718           OUT_AS1 (snz, );
5719         else
5720           OUT_AS1 (sz, );
5721         return AS1 (page, %4) CR_TAB
5722                AS1 (jmp, %4);
5723       }
5724     else
5725       {
5726         OUT_AS2 (mov, w, %L1);
5727         OUT_AS2 (mov, %L0, w);
5728         OUT_AS2 (mov, %L2, w);
5729         OUT_AS2 (mov, w, %H1);
5730         OUT_AS2 (mov, %H0, w);
5731         OUT_AS2 (mov, %H2, w);
5732         OUT_AS2 (or, w, %L2);
5733         if (GET_CODE (operands[3]) == EQ)
5734           OUT_AS1 (snz, );
5735         else
5736           OUT_AS1 (sz, );
5737         return AS1 (page, %4) CR_TAB
5738                AS1 (jmp, %4);
5739       }
5740   }")
5742 (define_peephole
5743   [(parallel [(set (match_operand:HI 0 "ip2k_gen_operand" "=uS")
5744                    (match_operand:HI 1 "ip2k_gen_operand"  "uS"))
5745               (set (match_operand:HI 2 "ip2k_gen_operand" "=uS")
5746                    (match_dup 1))])
5747    (set (cc0)
5748         (match_dup 2))
5749    (set (pc)
5750         (if_then_else (match_operator 3 "comparison_operator"
5751                         [(cc0) (const_int 0)])
5752                       (label_ref (match_operand 4 "" ""))
5753                       (pc)))]
5754   "(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)"
5755   "*{
5756     if ((REG_P (operands[0])
5757          && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2)
5758               && ip2k_xexp_not_uses_reg_p (operands[2],
5759                                            REGNO (operands[0]), 2)))
5760         || (REG_P (operands[2])
5761             && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2)
5762                  && ip2k_xexp_not_uses_reg_p (operands[1],
5763                                               REGNO (operands[2]), 2))))
5764       {
5765         OUT_AS2 (mov, w, %L1);
5766         OUT_AS1 (push, %H1%<);
5767         OUT_AS1 (push, %H1%<);
5768         OUT_AS1 (pop, %H0%>);
5769         OUT_AS2 (mov, %L0, w);
5770         OUT_AS1 (pop, %H2%>);
5771         OUT_AS2 (mov, %L2, w);
5772         OUT_AS2 (or, w, %H2);
5773         if (GET_CODE (operands[3]) == EQ)
5774           OUT_AS1 (snz, );
5775         else
5776           OUT_AS1 (sz, );
5777         return AS1 (page, %4) CR_TAB
5778                AS1 (jmp, %4);
5779       }
5780     else
5781       {
5782         OUT_AS2 (mov, w, %L1);
5783         OUT_AS2 (mov, %L0, w);
5784         OUT_AS2 (mov, %L2, w);
5785         OUT_AS2 (mov, w, %H1);
5786         OUT_AS2 (mov, %H0, w);
5787         OUT_AS2 (mov, %H2, w);
5788         OUT_AS2 (or, w, %L2);
5789         if (GET_CODE (operands[3]) == EQ)
5790           OUT_AS1 (snz, );
5791         else
5792           OUT_AS1 (sz, );
5793         return AS1 (page, %4) CR_TAB
5794                AS1 (jmp, %4);
5795       }
5796   }")
5798 ;; Handle move and compare-with-zero operations - we can reuse w across
5799 ;; the two operations.
5801 (define_peephole
5802   [(set (match_operand:HI 0 "nonimmediate_operand" "+uo")
5803         (match_operand:HI 1 "nonimmediate_operand"  "uo"))
5804    (set (cc0)
5805         (match_operand:SI 2 "nonimmediate_operand"  "uo"))
5806    (set (pc)
5807         (if_then_else (match_operator 3 "comparison_operator"
5808                         [(cc0) (const_int 0)])
5809                       (label_ref (match_operand 4 "" ""))
5810                       (pc)))]
5811   "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)
5812     && (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], HImode))
5813         || rtx_equal_p (operands[1],
5814                         ip2k_get_high_half (operands[2], HImode))))"
5815   "*{
5816     OUT_AS2 (mov, w, %H1);
5817     OUT_AS1 (push, %L1%<);
5818     OUT_AS1 (pop, %L0%>);
5819     OUT_AS2 (mov, %H0, w);
5820     OUT_AS2 (or, w, %B0);
5821     OUT_AS2 (or, w, %C0);
5822     OUT_AS2 (or, w, %D0);
5823     if (GET_CODE (operands[3]) == EQ)
5824       OUT_AS1 (snz, );
5825     else
5826       OUT_AS1 (sz, );
5827     return AS1 (page, %4) CR_TAB
5828            AS1 (jmp, %4);
5829   }")
5831 ;; Handle bitwise-and and compare-with-zero operations on bytes.
5833 (define_peephole
5834   [(set (reg:QI 10)
5835         (match_operand:QI 2 "general_operand" "        g"))
5836    (set (reg:QI 10)
5837         (and:QI (match_operand:QI 1 "general_operand" "g")
5838                 (reg:QI 10)))
5839    (set (match_operand:QI 0 "register_operand"       "+r")
5840         (reg:QI 10))
5841    (set (cc0)
5842         (match_dup 0))
5843    (set (pc)
5844         (if_then_else (match_operator 3 "comparison_operator"
5845                         [(cc0) (const_int 0)])
5846                       (label_ref (match_operand 4 "" ""))
5847                       (pc)))]
5848   "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))
5849     && (GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE))"
5850   "*{
5851     OUT_AS2 (mov, w, %1);
5852     OUT_AS2 (and, w, %2);
5853     if (GET_CODE (operands[3]) == EQ)
5854       OUT_AS1 (snz, );
5855     else
5856       OUT_AS1 (sz, );
5857     return AS1 (page, %4) CR_TAB
5858            AS1 (jmp, %4);
5859   }")
5861 ;; Handle bitwise-xor and compare-with-zero operations on bytes.
5863 (define_peephole
5864   [(set (match_operand:QI 0 "register_operand"       "+r")
5865         (xor:QI (match_operand:QI 1 "general_operand" "g")
5866                 (match_operand:QI 2 "general_operand" "g")))
5867    (set (cc0)
5868         (match_dup 0))
5869    (set (pc)
5870         (if_then_else (match_operator 3 "comparison_operator"
5871                         [(cc0) (const_int 0)])
5872                       (label_ref (match_operand 4 "" ""))
5873                       (pc)))]
5874   "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))
5875     && (GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE))"
5876   "*{
5877     OUT_AS2 (mov, w, %1);
5878     OUT_AS2 (xor, w, %2);
5879     if (GET_CODE (operands[3]) == EQ)
5880       OUT_AS1 (snz, );
5881     else
5882       OUT_AS1 (sz, );
5883     return AS1 (page, %4) CR_TAB
5884            AS1 (jmp, %4);
5885   }")
5887 ;; Cope with reload's vagaries.
5890 (define_insn "*pushqi_reload_popqi"
5891   [(set (match_operand:QI 0 "ip2k_nonsp_reg_operand" "=u, u")
5892         (match_operand:QI 1 "ip2k_short_operand"      "S, S"))
5893    (set (reg:HI 12)
5894         (match_operand:HI 2 "general_operand"         "i,ro"))
5895    (set (match_operand:QI 3 "ip2k_short_operand"     "=S, S")
5896         (match_dup 0))]
5897   ""
5898   "@
5899    push\\t%1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%3%>
5900    push\\t%1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%3%>"
5903 (define_peephole2
5904   [(set (match_operand:QI 0 "ip2k_nonsp_reg_operand" "")
5905         (match_operand:QI 1 "ip2k_short_operand" ""))
5906    (set (reg:HI 12)
5907         (match_operand:HI 2 "general_operand" ""))
5908    (set (match_operand:QI 3 "ip2k_short_operand" "")
5909         (match_dup 0))]
5910   "(ip2k_reorg_split_himode
5911     && peep2_reg_dead_p (3, operands[0])
5912     && ip2k_address_uses_reg_p (operands[1], REG_DP)
5913     && ip2k_address_uses_reg_p (operands[3], REG_DP)
5914     && !(ip2k_address_uses_reg_p (operands[2], REG_SP)
5915          && (GET_CODE (XEXP (operands[2], 0)) == PLUS)
5916          && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 126))
5917     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
5918                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
5919   [(parallel [(set (match_dup 0)
5920                    (match_dup 1))
5921               (set (reg:HI 12)
5922                    (match_dup 2))
5923               (set (match_dup 3)
5924                    (match_dup 0))])]
5925   "")
5927 (define_insn "*pushhi_reload_pophi"
5928   [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "=u, u")
5929         (match_operand:HI 1 "ip2k_short_operand"      "S, S"))
5930    (set (reg:HI 12)
5931         (match_operand:HI 2 "general_operand"         "i,ro"))
5932    (set (match_operand:HI 3 "ip2k_short_operand"     "=S, S")
5933         (match_dup 0))]
5934   ""
5935   "@
5936    push\\t%L1%<\;push\\t%H1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%H3%>\;pop\\t%L3%>
5937    push\\t%L1%<\;push\\t%H1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%H3%>\;pop\\t%L3%>"
5940 (define_peephole2
5941   [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "")
5942         (match_operand:HI 1 "ip2k_short_operand" ""))
5943    (set (reg:HI 12)
5944         (match_operand:HI 2 "general_operand" ""))
5945    (set (match_operand:HI 3 "ip2k_short_operand" "")
5946         (match_dup 0))]
5947   "(ip2k_reorg_split_simode
5948     && peep2_reg_dead_p (3, operands[0])
5949     && ip2k_address_uses_reg_p (operands[1], REG_DP)
5950     && ip2k_address_uses_reg_p (operands[3], REG_DP)
5951     && !(ip2k_address_uses_reg_p (operands[2], REG_SP)
5952          && (GET_CODE (XEXP (operands[2], 0)) == PLUS)
5953          && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 125))
5954     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
5955                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
5956   [(parallel [(set (match_dup 0)
5957                    (match_dup 1))
5958               (set (reg:HI 12)
5959                    (match_dup 2))
5960               (set (match_dup 3)
5961                    (match_dup 0))])]
5962   "")
5964 (define_insn "*pushsi_reload_popsi"
5965   [(set (match_operand:SI 0 "ip2k_nonsp_reg_operand" "=u, u")
5966         (match_operand:SI 1 "ip2k_short_operand"      "S, S"))
5967    (set (reg:HI 12)
5968         (match_operand:HI 2 "general_operand"         "i,ro"))
5969    (set (match_operand:SI 3 "ip2k_short_operand"     "=S, S")
5970         (match_dup 0))]
5971   ""
5972   "@
5973    push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%A3%>\;pop\\t%B3%>\;pop\\t%C3%>\;pop\\t%D3%>
5974    push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%A3%>\;pop\\t%B3%>\;pop\\t%C3%>\;pop\\t%D3%>"
5977 (define_peephole2
5978   [(set (match_operand:SI 0 "ip2k_nonsp_reg_operand" "")
5979         (match_operand:SI 1 "ip2k_short_operand" ""))
5980    (set (reg:HI 12)
5981         (match_operand:HI 2 "general_operand" ""))
5982    (set (match_operand:SI 3 "ip2k_short_operand" "")
5983         (match_dup 0))]
5984   "(ip2k_reorg_split_dimode
5985     && peep2_reg_dead_p (3, operands[0])
5986     && ip2k_address_uses_reg_p (operands[1], REG_DP)
5987     && ip2k_address_uses_reg_p (operands[3], REG_DP)
5988     && ! (ip2k_address_uses_reg_p (operands[2], REG_SP)
5989           && (GET_CODE (XEXP (operands[2], 0)) == PLUS)
5990           && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 123)))"
5991   [(parallel [(set (match_dup 0)
5992                    (match_dup 1))
5993               (set (reg:HI 12)
5994                    (match_dup 2))
5995               (set (match_dup 3)
5996                    (match_dup 0))])]
5997   "")
5999 (define_insn "*pushdi_reload_popdi"
6000   [(set (match_operand:DI 0 "ip2k_nonsp_reg_operand" "=u, u")
6001         (match_operand:DI 1 "ip2k_short_operand"      "S, S"))
6002    (set (reg:HI 12)
6003         (match_operand:HI 2 "general_operand"         "i,ro"))
6004    (set (match_operand:DI 3 "ip2k_short_operand"     "=S, S")
6005         (match_dup 0))]
6006   ""
6007   "@
6008    push\\t%S1%<\;push\\t%T1%<\;push\\t%U1%<\;push\\t%V1%<\;push\\t%W1%<\;push\\t%X1%<\;push\\t%Y1%<\;push\\t%Z1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%Z3%>\;pop\\t%Y3%>\;pop\\t%X3%>\;pop\\t%W3%>\;pop\\t%V3%>\;pop\\t%U3%>\;pop\\t%T3%>\;pop\\t%S3%>
6009    push\\t%S1%<\;push\\t%T1%<\;push\\t%U1%<\;push\\t%V1%<\;push\\t%W1%<\;push\\t%X1%<\;push\\t%Y1%<\;push\\t%Z1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%Z3%>\;pop\\t%Y3%>\;pop\\t%X3%>\;pop\\t%W3%>\;pop\\t%V3%>\;pop\\t%U3%>\;pop\\t%T3%>\;pop\\t%S3%>"
6012 (define_peephole2
6013   [(set (match_operand:DI 0 "ip2k_nonsp_reg_operand" "")
6014         (match_operand:DI 1 "ip2k_short_operand" ""))
6015    (set (reg:HI 12)
6016         (match_operand:HI 2 "general_operand" ""))
6017    (set (match_operand:DI 3 "ip2k_short_operand" "")
6018         (match_dup 0))]
6019   "((ip2k_reorg_in_progress || ip2k_reorg_completed)
6020     && peep2_reg_dead_p (3, operands[0])
6021     && ip2k_address_uses_reg_p (operands[1], REG_DP)
6022     && ip2k_address_uses_reg_p (operands[3], REG_DP)
6023     && ! (ip2k_address_uses_reg_p (operands[2], REG_SP)
6024           && (GET_CODE (XEXP (operands[2], 0)) == PLUS)
6025           && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 119)))"
6026   [(parallel [(set (match_dup 0)
6027                    (match_dup 1))
6028               (set (reg:HI 12)
6029                    (match_dup 2))
6030               (set (match_dup 3)
6031                    (match_dup 0))])]
6032   "")
6034 ;; FIXME: Disabled because in lshiftrt:SI op1 must match op0
6035 (define_peephole2
6036   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6037         (match_operator 3 "ip2k_binary_operator"
6038                         [(match_operand 1 "general_operand" "")
6039                          (match_operand 2 "general_operand" "")]))
6040    (set (match_operand 4 "nonimmediate_operand" "")
6041         (match_dup 0))]
6042   "0 && (peep2_reg_dead_p (2, operands[0])
6043          && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6044                                       GET_MODE_SIZE (GET_MODE (operands[0]))))"
6045   [(set (match_dup 4)
6046         (match_op_dup 3 [(match_dup 1)
6047                          (match_dup 2)]))]
6048   "")
6050 (define_peephole2
6051   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6052         (match_operator 3 "ip2k_binary_operator"
6053                         [(zero_extend:HI
6054                           (match_operand 1 "general_operand" ""))
6055                          (match_operand 2 "general_operand" "")]))
6056    (set (match_operand 4 "nonimmediate_operand" "")
6057         (match_dup 0))]
6058   "(peep2_reg_dead_p (2, operands[0])
6059     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6060                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6061   [(set (match_dup 4)
6062         (match_op_dup 3 [(zero_extend:HI (match_dup 1))
6063                          (match_dup 2)]))]
6064   "")
6066 (define_peephole2
6067   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6068         (match_operator 3 "ip2k_binary_operator"
6069                         [(match_operand 1 "general_operand" "")
6070                          (zero_extend:HI
6071                           (match_operand 2 "general_operand" ""))]))
6072    (set (match_operand 4 "nonimmediate_operand" "")
6073         (match_dup 0))]
6074   "(peep2_reg_dead_p (2, operands[0])
6075     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6076                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6077   [(set (match_dup 4)
6078         (match_op_dup 3 [(match_dup 1)
6079                          (zero_extend:HI (match_dup 2))]))]
6080   "")
6082 (define_peephole2
6083   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6084         (match_operator 3 "ip2k_binary_operator"
6085                         [(zero_extend:SI
6086                           (match_operand 1 "general_operand" ""))
6087                          (match_operand 2 "general_operand" "")]))
6088    (set (match_operand 4 "nonimmediate_operand" "")
6089         (match_dup 0))]
6090   "(peep2_reg_dead_p (2, operands[0])
6091     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6092                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6093   [(set (match_dup 4)
6094         (match_op_dup 3 [(zero_extend:SI (match_dup 1))
6095                          (match_dup 2)]))]
6096   "")
6098 (define_peephole2
6099   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6100         (match_operator 3 "ip2k_binary_operator"
6101                         [(match_operand 1 "general_operand" "")
6102                          (zero_extend:SI
6103                           (match_operand 2 "general_operand" ""))]))
6104    (set (match_operand 4 "nonimmediate_operand" "")
6105         (match_dup 0))]
6106   "(peep2_reg_dead_p (2, operands[0])
6107     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6108                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6109   [(set (match_dup 4)
6110         (match_op_dup 3 [(match_dup 1)
6111                          (zero_extend:SI (match_dup 2))]))]
6112   "")
6114 (define_peephole2
6115   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6116         (match_operand 1 "nonimmediate_operand" ""))
6117    (set (match_operand 2 "nonimmediate_operand" "")
6118         (match_operator 3 "ip2k_binary_operator"
6119                         [(match_operand 4 "general_operand" "")
6120                          (match_dup 0)]))]
6121   "0 && ((peep2_reg_dead_p (2, operands[0])
6122     || rtx_equal_p (operands[0], operands[2]))
6123     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6124                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6125   [(set (match_dup 2)
6126         (match_op_dup 3 [(match_dup 4)
6127                          (match_dup 1)]))]
6128   "")
6130 (define_peephole2
6131   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6132         (match_operand 1 "nonimmediate_operand" ""))
6133    (set (match_operand 2 "nonimmediate_operand" "")
6134         (match_operator 3 "ip2k_binary_operator"
6135                         [(zero_extend:HI
6136                           (match_operand 4 "general_operand" ""))
6137                          (match_dup 0)]))]
6138   "((peep2_reg_dead_p (2, operands[0])
6139      || rtx_equal_p (operands[0], operands[2]))
6140     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6141                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6142   [(set (match_dup 2)
6143         (match_op_dup 3 [(zero_extend:HI (match_dup 4))
6144                          (match_dup 1)]))]
6145   "")
6147 (define_peephole2
6148   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6149         (match_operand 1 "nonimmediate_operand" ""))
6150    (set (match_operand 2 "nonimmediate_operand" "")
6151         (match_operator 3 "ip2k_binary_operator"
6152                         [(zero_extend:SI
6153                           (match_operand 4 "general_operand" ""))
6154                          (match_dup 0)]))]
6155   "((peep2_reg_dead_p (2, operands[0])
6156      || rtx_equal_p (operands[0], operands[2]))
6157     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6158                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6159   [(set (match_dup 2)
6160         (match_op_dup 3 [(zero_extend:SI (match_dup 4))
6161                          (match_dup 1)]))]
6162   "")
6164 (define_peephole2
6165   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6166         (match_operand 1 "nonimmediate_operand" ""))
6167    (set (match_operand 2 "nonimmediate_operand" "")
6168         (match_operator 3 "ip2k_binary_operator"
6169                         [(match_dup 0)
6170                          (match_operand 4 "general_operand" "")]))]
6171   "0 && ((peep2_reg_dead_p (2, operands[0])
6172     || rtx_equal_p (operands[0], operands[2]))
6173     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6174                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6175   [(set (match_dup 2)
6176         (match_op_dup 3 [(match_dup 1)
6177                          (match_dup 4)]))]
6178   "")
6180 (define_peephole2
6181   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6182         (match_operand 1 "nonimmediate_operand" ""))
6183    (set (match_operand 2 "nonimmediate_operand" "")
6184         (match_operator 3 "ip2k_binary_operator"
6185                         [(match_dup 0)
6186                          (zero_extend:HI
6187                           (match_operand 4 "general_operand" ""))]))]
6188   "((peep2_reg_dead_p (2, operands[0])
6189      || rtx_equal_p (operands[0], operands[2]))
6190     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6191                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6192   [(set (match_dup 2)
6193         (match_op_dup 3 [(match_dup 1)
6194                          (zero_extend:HI (match_dup 4))]))]
6195   "")
6197 (define_peephole2
6198   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6199         (match_operand 1 "nonimmediate_operand" ""))
6200    (set (match_operand 2 "nonimmediate_operand" "")
6201         (match_operator 3 "ip2k_binary_operator"
6202                         [(match_dup 0)
6203                          (zero_extend:SI
6204                           (match_operand 4 "general_operand" ""))]))]
6205   "((peep2_reg_dead_p (2, operands[0])
6206      || rtx_equal_p (operands[0], operands[2]))
6207     && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]),
6208                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6209   [(set (match_dup 2)
6210         (match_op_dup 3 [(match_dup 1)
6211                          (zero_extend:SI (match_dup 4))]))]
6212   "")
6214 (define_peephole2
6215   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6216         (match_operand 1 "nonimmediate_operand" ""))
6217    (set (cc0)
6218         (match_operator 2 "ip2k_binary_operator"
6219                         [(match_operand 3 "general_operand" "")
6220                          (match_dup 0)]))]
6221   "0 && (peep2_reg_dead_p (2, operands[0])
6222     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6223                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6224   [(set (cc0)
6225         (match_op_dup 2 [(match_dup 3)
6226                          (match_dup 1)]))]
6227   "")
6229 (define_peephole2
6230   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6231         (match_operand 1 "nonimmediate_operand" ""))
6232    (set (cc0)
6233         (match_operator 2 "ip2k_binary_operator"
6234                         [(zero_extend:HI
6235                           (match_operand 3 "general_operand" ""))
6236                          (match_dup 0)]))]
6237   "(peep2_reg_dead_p (2, operands[0])
6238     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6239                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6240   [(set (cc0)
6241         (match_op_dup 2 [(zero_extend:HI (match_dup 3))
6242                          (match_dup 1)]))]
6243   "")
6245 (define_peephole2
6246   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6247         (match_operand 1 "nonimmediate_operand" ""))
6248    (set (cc0)
6249         (match_operator 2 "ip2k_binary_operator"
6250                         [(zero_extend:SI
6251                           (match_operand 3 "general_operand" ""))
6252                          (match_dup 0)]))]
6253   "(peep2_reg_dead_p (2, operands[0])
6254     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6255                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6256   [(set (cc0)
6257         (match_op_dup 2 [(zero_extend:SI (match_dup 3))
6258                          (match_dup 1)]))]
6259   "")
6261 (define_peephole2
6262   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6263         (match_operand 1 "nonimmediate_operand" ""))
6264    (set (cc0)
6265         (match_operator 2 "ip2k_binary_operator"
6266                         [(match_dup 0)
6267                          (match_operand 3 "general_operand" "")]))]
6268   "(peep2_reg_dead_p (2, operands[0])
6269     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6270                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6271   [(set (cc0)
6272         (match_op_dup 2 [(match_dup 1)
6273                          (match_dup 3)]))]
6274   "")
6276 (define_peephole2
6277   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6278         (match_operand 1 "nonimmediate_operand" ""))
6279    (set (cc0)
6280         (match_operator 2 "ip2k_binary_operator"
6281                         [(match_dup 0)
6282                          (zero_extend:HI
6283                           (match_operand 3 "general_operand" ""))]))]
6284   "(peep2_reg_dead_p (2, operands[0])
6285     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6286                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6287   [(set (cc0)
6288         (match_op_dup 2 [(match_dup 1)
6289                          (zero_extend:HI (match_dup 3))]))]
6290   "")
6292 (define_peephole2
6293   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6294         (match_operand 1 "nonimmediate_operand" ""))
6295    (set (cc0)
6296         (match_operator 2 "ip2k_binary_operator"
6297                         [(match_dup 0)
6298                          (zero_extend:SI
6299                           (match_operand 3 "general_operand" ""))]))]
6300   "(peep2_reg_dead_p (2, operands[0])
6301     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6302                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6303   [(set (cc0)
6304         (match_op_dup 2 [(match_dup 1)
6305                          (zero_extend:SI (match_dup 3))]))]
6306   "")
6308 (define_peephole2
6309   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6310         (match_operator 3 "ip2k_unary_operator"
6311                         [(match_operand 1 "general_operand" "")]))
6312    (set (match_operand 2 "nonimmediate_operand" "")
6313         (match_dup 0))]
6314   "(peep2_reg_dead_p (2, operands[0])
6315     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
6316                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6317   [(set (match_dup 2)
6318         (match_op_dup 3 [(match_dup 1)]))]
6319   "")
6321 (define_peephole2
6322   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6323         (match_operand 1 "nonimmediate_operand" ""))
6324    (set (match_operand 2 "nonimmediate_operand" "")
6325         (match_operator 3 "ip2k_unary_operator" [(match_dup 0)]))]
6326   "(peep2_reg_dead_p (2, operands[0])
6327     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
6328                                  GET_MODE_SIZE (GET_MODE (operands[0]))))"
6329   [(set (match_dup 2)
6330         (match_op_dup 3 [(match_dup 1)]))]
6331   "")
6333 (define_peephole2
6334   [(set (match_operand 0 "ip2k_nonsp_reg_operand" "")
6335         (match_operand 1 "nonimmediate_operand" ""))
6336    (set (cc0)
6337         (match_dup 0))]
6338   "peep2_reg_dead_p (2, operands[0])"
6339   [(set (cc0)
6340         (match_dup 1))]
6341   "")
6343 ;; Look for places where we can shorten a compare operation.
6345 (define_peephole2
6346   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6347         (const_int 0))
6348    (set (cc0)
6349         (match_operand:HI 1 "nonimmediate_operand" ""))
6350    (set (pc)
6351         (if_then_else (match_operator 2 "comparison_operator"
6352                         [(cc0) (const_int 0)])
6353                       (label_ref (match_operand 3 "" ""))
6354                       (pc)))]
6355   "(rtx_equal_p (ip2k_get_high_half (operands[1], QImode), operands[0]))"
6356   [(set (match_dup 0)
6357         (const_int 0))
6358    (set (cc0)
6359         (match_dup 4))
6360    (set (pc)
6361         (if_then_else (match_op_dup 2
6362                         [(cc0) (const_int 0)])
6363                       (label_ref (match_dup 3))
6364                       (pc)))]
6365   "{
6366     operands[4] = ip2k_get_low_half (operands[1], QImode);
6367   }")
6369 ;; Look for places where we can shorten a compare operation.
6371 (define_peephole2
6372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6373         (const_int 0))
6374    (set (cc0)
6375         (compare (match_operand:HI 1 "nonimmediate_operand" "")
6376                  (match_operand 2 "const_int_operand" "")))
6377    (set (pc)
6378         (if_then_else (match_operator 3 "comparison_operator"
6379                         [(cc0) (const_int 0)])
6380                       (label_ref (match_operand 4 "" ""))
6381                       (pc)))]
6382   "(rtx_equal_p (ip2k_get_high_half (operands[1], QImode), operands[0])
6383     && (abs (INTVAL (operands[2]) <= 127)))"
6384   [(set (match_dup 0)
6385         (const_int 0))
6386    (set (cc0)
6387         (compare (match_dup 5)
6388                  (match_dup 6)))
6389    (set (pc)
6390         (if_then_else (match_op_dup 3
6391                         [(cc0) (const_int 0)])
6392                       (label_ref (match_dup 4))
6393                       (pc)))]
6394   "{
6395     operands[5] = ip2k_get_low_half (operands[1], QImode);
6396     operands[6] = gen_int_mode (INTVAL (operands[2]) & 0xff, QImode);
6397   }")
6399 ;; This is one of those cases where gcc just can't untangle our wishes.  We
6400 ;; want to add some values but get two copies of the result.  In this instance
6401 ;; however, the seconds copy can be made more cheaply by combining things.
6403 (define_peephole
6404   [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand"       "+&u")
6405         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "rS")
6406                  (match_operand:HI 2 "general_operand"     "rSi")))
6407    (set (match_operand:HI 3 "ip2k_gen_operand"            "=&uS")
6408         (match_dup 0))]
6409   "(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]),
6410                               GET_MODE_SIZE (GET_MODE (operands[0])))
6411     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
6412                                  GET_MODE_SIZE (GET_MODE (operands[0])))
6413     && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6414                                  GET_MODE_SIZE (GET_MODE (operands[0])))
6415     && (!REG_P (operands[3])
6416         || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]),
6417                                       GET_MODE_SIZE (GET_MODE (operands[3])))
6418             && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]),
6419                                          GET_MODE_SIZE (GET_MODE (operands[3]))))))"
6420   "mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\t%L3,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;mov\\t%H3,w")
6422 (define_peephole
6423   [(set (match_operand:HI 0 "ip2k_short_operand"           "+&S")
6424         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "rS")
6425                  (match_operand:HI 2 "general_operand"     "rSi")))
6426    (set (match_operand:HI 3 "ip2k_nonsp_reg_operand"       "=&u")
6427         (match_dup 0))]
6428   "(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]),
6429                               GET_MODE_SIZE (GET_MODE (operands[3])))
6430     && ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]),
6431                                  GET_MODE_SIZE (GET_MODE (operands[3])))
6432     && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]),
6433                                  GET_MODE_SIZE (GET_MODE (operands[3])))
6434     && ! rtx_equal_p (operands[0], operands[1])
6435     && ! rtx_equal_p (operands[0], operands[2]))"
6436   "mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\t%L3,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;mov\\t%H3,w")
6438 ;; Some splits zero the MSByte of a word that we then use for shifting.  We
6439 ;; can therefore replace full shifts with zero-extended ones.  These are
6440 ;; cheaper for us.
6442 (define_peephole2
6443   [(set (match_operand:QI 0 "register_operand" "")
6444         (const_int 0))
6445    (set (match_operand:HI 1 "nonimmediate_operand" "")
6446         (ashift:HI (match_operand:HI 2 "register_operand" "")
6447                    (match_operand 3 "const_int_operand" "")))]
6448   "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0])
6449     && peep2_reg_dead_p (2, operands[0]))"
6450   [(set (match_dup 1)
6451         (ashift:HI (zero_extend:HI (match_dup 4))
6452                    (match_dup 3)))]
6453   "{
6454     operands[4] = ip2k_get_low_half (operands[2], QImode);
6455   }")
6457 (define_peephole2
6458   [(set (match_operand:QI 0 "register_operand" "")
6459         (const_int 0))
6460    (set (match_operand:HI 1 "nonimmediate_operand" "")
6461         (ashift:HI (match_operand:HI 2 "register_operand" "")
6462                    (match_operand 3 "const_int_operand" "")))]
6463   "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]))"
6464   [(set (match_dup 0)
6465         (const_int 0))
6466    (set (match_dup 1)
6467         (ashift:HI (zero_extend:HI (match_dup 4))
6468                    (match_dup 3)))]
6469   "{
6470     operands[4] = ip2k_get_low_half (operands[2], QImode);
6471   }")
6473 ;; Some splits zero the MSByte of a word that we then use for multiplying.  We
6474 ;; can therefore replace the full multiplies with zero-extended ones.
6475 ;; These are cheaper for us.
6477 (define_peephole2
6478   [(set (match_operand:QI 0 "register_operand" "")
6479         (const_int 0))
6480    (set (match_operand:HI 1 "nonimmediate_operand" "")
6481         (mult:HI (match_operand:HI 2 "register_operand" "")
6482                  (zero_extend:HI
6483                   (match_operand:QI 3 "const_int_operand" ""))))]
6484   "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0])
6485     && (peep2_reg_dead_p (2, operands[0])
6486         || rtx_equal_p (operands[1], operands[2])))"
6487   [(set (match_dup 1)
6488         (mult:HI (zero_extend:HI (match_dup 4))
6489                  (zero_extend:HI (match_dup 3))))]
6490   "{
6491     operands[4] = ip2k_get_low_half (operands[2], QImode);
6492   }")
6494 (define_peephole2
6495   [(set (match_operand:QI 0 "register_operand" "")
6496         (const_int 0))
6497    (set (match_operand:HI 1 "nonimmediate_operand" "")
6498         (mult:HI (match_operand:HI 2 "register_operand" "")
6499                  (zero_extend:HI
6500                   (match_operand:QI 3 "const_int_operand" ""))))]
6501   "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]))"
6502   [(set (match_dup 0)
6503         (const_int 0))
6504    (set (match_dup 1)
6505         (mult:HI (zero_extend:HI (match_dup 4))
6506                  (zero_extend:HI (match_dup 3))))]
6507   "{
6508     operands[4] = ip2k_get_low_half (operands[2], QImode);
6509   }")
6511 ;; Merge in a redundant move before a zero-extended multiply.
6513 (define_peephole2
6514   [(set (match_operand:QI 0 "register_operand" "")
6515         (match_operand:QI 1 "general_operand" ""))
6516    (set (match_operand:HI 2 "nonimmediate_operand" "")
6517         (mult:HI (zero_extend:HI (match_dup 0))
6518                  (zero_extend:HI
6519                   (match_operand:QI 3 "const_int_operand" ""))))]
6520   "(peep2_reg_dead_p (2, operands[0])
6521     || rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0])
6522     || rtx_equal_p (ip2k_get_low_half (operands[2], QImode), operands[0]))"
6523   [(set (match_dup 2)
6524         (mult:HI (zero_extend:HI (match_dup 1))
6525                  (zero_extend:HI (match_dup 3))))]
6526   "")
6528 ;; Pick up redundant clears followed by adds - these can just become moves.
6530 (define_peephole2
6531   [(set (match_operand 0 "register_operand" "")
6532         (const_int 0))
6533    (set (match_operand 2 "nonimmediate_operand" "")
6534         (plus (match_dup 0)
6535               (match_operand 1 "general_operand" "")))]
6536   "peep2_reg_dead_p (2, operands[0])"
6537   [(set (match_dup 2)
6538         (match_dup 1))]
6539   "")
6541 (define_peephole2
6542   [(set (match_operand 0 "register_operand" "")
6543         (const_int 0))
6544    (set (match_dup 0)
6545         (plus (match_dup 0)
6546               (match_operand 1 "general_operand" "")))]
6547   ""
6548   [(set (match_dup 0)
6549         (match_dup 1))]
6550   "")
6552 ;; Clear up an add followed by a push of the result.  The fact that this 
6553 ;; isn't picked up consistently within the combiner suggests a bug somewhere.
6555 (define_peephole2
6556   [(set (match_operand:HI 0 "register_operand" "")
6557         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6558                  (match_operand:HI 2 "general_operand" "")))
6559    (set (mem:HI (post_dec:HI (reg:HI 6)))
6560         (match_dup 0))]
6561   "peep2_reg_dead_p (2, operands[0])"
6562   [(set (mem:HI (post_dec:HI (reg:HI 6)))
6563         (plus:HI (match_dup 1)
6564                  (match_dup 2)))]
6565   "")
6567 ;; Tidy up stack slot addressing where we've eliminated some registers.
6568 ;;   This looks like something strange going on though as gcc-2.97 didn't
6569 ;; exhibit this behavior, whereas gcc-3.0.4 does.
6571 (define_peephole2
6572   [(set (match_operand:HI 0 "register_operand" "")
6573         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6574                  (match_operand 2 "const_int_operand" "")))
6575    (set (mem:HI (post_dec:HI (reg:HI 6)))
6576         (plus:HI (match_dup 0)
6577                  (match_operand 3 "const_int_operand" "")))]
6578   "peep2_reg_dead_p (2, operands[0])"
6579   [(set (mem:HI (post_dec:HI (reg:HI 6)))
6580         (plus:HI (match_dup 1)
6581                  (match_dup 4)))]
6582   "{
6583     operands[4] = gen_int_mode (INTVAL (operands[2]) + INTVAL (operands[3]),
6584                                 HImode);
6585   }")
6587 ;; Match duplicate loads of a symbol ref.  This isn't something that we want to
6588 ;; do at the peephole2 stage because more often than not we'll make one of the
6589 ;; two loads redundant after we run peephole2.  We catch the remaining cases
6590 ;; here though
6592 (define_peephole
6593   [(set (match_operand:HI 0 "nonimmediate_operand" "+uS")
6594         (match_operand 1 "ip2k_symbol_ref_operand"   "i"))
6595    (set (match_operand:HI 2 "nonimmediate_operand" "=uS")
6596         (match_dup 1))]
6597   "((!REG_P (operands[0]) || (REGNO (operands[0]) != REG_DP))
6598     && (!REG_P (operands[2]) || (REGNO (operands[2]) != REG_DP)))"
6599   "mov\\tw,%L1\;mov\\t%L0,w\;mov\\t%L2,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\t%H2,w")
6601 (define_peephole
6602   [(set (match_operand:HI 0 "nonimmediate_operand" "+&uS")
6603         (match_operand 1 "ip2k_symbol_ref_operand"   "i"))
6604    (set (match_operand:HI 2 "nonimmediate_operand" "=&uS")
6605         (match_dup 0))]
6606   ""
6607   "*{
6608     if ((REG_P (operands[0])
6609          && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2)
6610               && ip2k_xexp_not_uses_reg_p (operands[2],
6611                                            REGNO (operands[0]), 2)))
6612         || (REG_P (operands[2])
6613             && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2)
6614                  && ip2k_xexp_not_uses_reg_p (operands[1],
6615                                               REGNO (operands[2]), 2))))
6616       {
6617         return AS2 (mov, w, %L1) CR_TAB
6618                AS1 (push, %H1%<) CR_TAB
6619                AS1 (push, %H1%<) CR_TAB
6620                AS1 (pop, %H0%>) CR_TAB
6621                AS2 (mov, %L0, w) CR_TAB
6622                AS1 (pop, %H2%>) CR_TAB
6623                AS2 (mov, %L2, w);
6624       }
6625     else
6626       {
6627         return AS2 (mov, w, %L1) CR_TAB
6628                AS2 (mov, %L0, w) CR_TAB
6629                AS2 (mov, %L2, w) CR_TAB
6630                AS2 (mov, w, %H1) CR_TAB
6631                AS2 (mov, %H0, w) CR_TAB
6632                AS2 (mov, %H2, w);
6633       }
6634   }")
6636 ;; Handle the common array indexing pattern.
6637 ;; This is of the form A = X + (Y * C).
6638 ;; We use splits earlier in this file to get our interesting cases into the
6639 ;; same form (i.e. zero-extended multiply and add).
6641 (define_insn "*mulacchi"
6642   [(set (match_operand:HI 3 "nonimmediate_operand"                   "=rS")
6643         (plus:HI (mult:HI (zero_extend:HI
6644                            (match_operand:QI 1 "nonimmediate_operand" "rS"))
6645                           (zero_extend:HI
6646                            (match_operand:QI 2 "const_int_operand"     "n")))
6647                  (match_operand:HI 0 "general_operand"                "rSi")))]
6648   ""
6649   "*{
6650     if (immediate_operand (operands[0], HImode)
6651         && REG_P (operands[3])
6652         && (REGNO (operands[3]) == REG_DP)
6653         && (INTVAL (operands[2]) == 2))
6654       return AS2 (mov, w, %1) CR_TAB
6655              AS1 (loadl, %x0) CR_TAB
6656              AS1 (loadh, %x0) CR_TAB
6657              AS2 (add, dpl, w) CR_TAB
6658              AS2 (add, dpl, w);
6659     else
6660       return AS2 (mov, w, %1) CR_TAB
6661              AS2 (mulu, w, %2) CR_TAB
6662              AS2 (add, w, %L0) CR_TAB
6663              AS2 (mov, %L3, w) CR_TAB
6664              AS2 (mov, w, %H0) CR_TAB
6665              AS2 (addc, w, MULH) CR_TAB
6666              AS2 (mov, %H3, w);
6667   }")
6669 (define_peephole2
6670   [(set (match_operand:HI 0 "register_operand" "")
6671         (mult:HI (zero_extend:HI
6672                    (match_operand:QI 1 "nonimmediate_operand" ""))
6673                  (zero_extend:HI
6674                    (match_operand 2 "const_int_operand" ""))))
6675    (set (match_operand:HI 3 "nonimmediate_operand" "")
6676         (plus:HI (match_dup 0)
6677                  (match_operand:HI 4 "general_operand" "")))]
6678   "(((! REG_P (operands[3]))
6679      || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]),
6680                                    GET_MODE_SIZE (GET_MODE (operands[3])))
6681          && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]),
6682                                       GET_MODE_SIZE (GET_MODE (operands[3])))))
6683     && peep2_reg_dead_p (2, operands[0]))"
6684   [(set (match_dup 3)
6685         (plus:HI (mult:HI (zero_extend:HI
6686                             (match_dup 1))
6687                           (zero_extend:HI
6688                             (match_dup 2)))
6689                  (match_dup 4)))]
6690   "")
6692 (define_insn "*mulhi_and_accumulate"
6693   [(set (match_operand:HI 0 "nonimmediate_operand"           "=rS")
6694         (mult:HI (zero_extend:HI
6695                    (match_operand:QI 1 "nonimmediate_operand" "rS"))
6696                  (zero_extend:HI
6697                    (match_operand:QI 2 "const_int_operand"     "n"))))
6698    (set (match_operand:HI 3 "nonimmediate_operand"           "=rS")
6699         (plus:HI (match_dup 0)
6700                  (match_operand:HI 4 "general_operand"      "%rSi")))]
6701   "((! REG_P (operands[3]))
6702     || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]),
6703                                   GET_MODE_SIZE (GET_MODE (operands[3])))
6704         && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]),
6705                                      GET_MODE_SIZE (GET_MODE (operands[3])))))"
6706   "*{
6707     return AS2 (mov, w, %1) CR_TAB
6708            AS2 (mulu, w, %2) CR_TAB
6709            AS2 (mov, %L0, w) CR_TAB
6710            AS2 (add, w, %L4) CR_TAB
6711            AS2 (mov, %L3, w) CR_TAB
6712            AS2 (mov, w, %H4) CR_TAB
6713            AS2 (addc, w, MULH) CR_TAB
6714            AS2 (mov, %H3, w) CR_TAB
6715            AS2 (mov, w, MULH) CR_TAB
6716            AS2 (mov, %H0, w);
6717   }")
6719 (define_peephole2
6720   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6721         (mult:HI (zero_extend:HI
6722                    (match_operand:QI 1 "nonimmediate_operand" ""))
6723                  (zero_extend:HI
6724                    (match_operand 2 "const_int_operand" ""))))
6725    (set (match_operand:HI 3 "nonimmediate_operand" "")
6726         (plus:HI (match_dup 0)
6727                  (match_operand:HI 4 "general_operand" "")))]
6728   "((! REG_P (operands[3]))
6729     || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]),
6730                                   GET_MODE_SIZE (GET_MODE (operands[3])))
6731         && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]),
6732                                      GET_MODE_SIZE (GET_MODE (operands[3])))))"
6733   [(parallel [(set (match_dup 0)
6734                    (mult:HI (zero_extend:HI
6735                               (match_dup 1))
6736                             (zero_extend:HI
6737                               (match_dup 2))))
6738               (set (match_dup 3)
6739                    (plus:HI (match_dup 0)
6740                             (match_dup 4)))])]
6741   "")
6743 ;; Handle the common array indexing pattern.
6744 ;; This is of the form A = X + (Y * C).
6745 ;; We use splits earlier in this file to get our interesting cases into the 
6746 ;; same form (i.e. multiply and add).
6748 (define_peephole
6749   [(set (match_operand:HI 0 "register_operand"              "=r")
6750         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS")
6751                  (zero_extend:HI
6752                    (match_operand:QI 2 "const_int_operand"   "n"))))
6753    (set (match_operand:HI 3 "nonimmediate_operand"         "=rS")
6754         (plus:HI (match_dup 0)
6755                  (match_operand:HI 4 "general_operand"    "%rSi")))]
6756   "((!REG_P (operands[3])
6757      || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]),
6758                                    GET_MODE_SIZE (GET_MODE (operands[3])))))
6759     && find_regno_note (insn, REG_DEAD, REGNO (operands[0])))"
6760   "*{
6761     if (immediate_operand (operands[4], HImode)
6762         && REG_P (operands[3])
6763         && (REGNO (operands[3]) == REG_DP)
6764         && (INTVAL (operands[2]) == 2)
6765         && ip2k_xexp_not_uses_reg_p (operands[1], REG_DP,
6766                                      GET_MODE_SIZE (HImode)))
6767       return AS2 (clrb, STATUS, 0) CR_TAB
6768              AS1 (loadl, %x4) CR_TAB
6769              AS1 (loadh, %x4) CR_TAB
6770              AS2 (rl, w, %L1) CR_TAB
6771              AS2 (add, dpl, w) CR_TAB
6772              AS2 (rl, w, %H1) CR_TAB
6773              AS2 (add, dph, w);
6774     else if (!REG_P (operands[3])
6775              || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]),
6776                                            GET_MODE_SIZE (GET_MODE (operands[3])))
6777                  && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]),
6778                                                GET_MODE_SIZE (GET_MODE (operands[3])))))
6779       return AS2 (mov, w, %L1) CR_TAB
6780              AS2 (mulu, w, %2) CR_TAB
6781              AS2 (add, w, %L4) CR_TAB
6782              AS2 (mov, %L3, w) CR_TAB
6783              AS2 (mov, w, %H4) CR_TAB
6784              AS2 (addc, w, MULH) CR_TAB
6785              AS2 (mov, %H3, w) CR_TAB
6786              AS2 (mov, w, %H1) CR_TAB
6787              AS2 (mulu, w, %2) CR_TAB
6788              AS2 (add, %H3, w);
6789     else
6790       return AS2 (mov, w, %L1) CR_TAB
6791              AS2 (mulu, w, %2) CR_TAB
6792              AS2 (add, w, %L4) CR_TAB
6793              AS1 (push, wreg%<) CR_TAB
6794              AS2 (mov, w, %H4) CR_TAB
6795              AS2 (addc, w, MULH) CR_TAB
6796              AS1 (push, wreg%<) CR_TAB
6797              AS2 (mov, w, %H1) CR_TAB
6798              AS2 (mulu, w, %2) CR_TAB
6799              AS1 (pop, %H3%>) CR_TAB
6800              AS1 (pop, %L3%>) CR_TAB
6801              AS2 (add, %H3, w);
6802   }")
6804 ;; Handle the more complex variant of the preceding multiply and accumulate
6805 ;; variant of the preceding multiply-and-add operation.  This one would 
6806 ;; otherwise fail to match because the result never goes dead.
6808 (define_peephole
6809   [(set (match_operand:HI 0 "nonimmediate_operand"         "=rS")
6810         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS")
6811                  (zero_extend:HI
6812                    (match_operand:QI 2 "const_int_operand"   "n"))))
6813    (set (match_dup 0)
6814         (plus:HI (match_dup 0)
6815                  (match_operand:HI 3 "general_operand"    "%rSi")))]
6816   "(!REG_P (operands[0])
6817     || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]),
6818                                   GET_MODE_SIZE (GET_MODE (operands[0])))
6819         && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]),
6820                                      GET_MODE_SIZE (GET_MODE (operands[0])))
6821         && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]),
6822                                      GET_MODE_SIZE (GET_MODE (operands[0])))))"
6823   "*{
6824     if (immediate_operand (operands[3], HImode)
6825         && REG_P (operands[0])
6826         && (REGNO (operands[0]) == REG_DP)
6827         && (INTVAL (operands[2]) == 2))
6828       return AS2 (clrb, STATUS, 0) CR_TAB
6829              AS1 (loadl, %x3) CR_TAB
6830              AS1 (loadh, %x3) CR_TAB
6831              AS2 (rl, w, %L1) CR_TAB
6832              AS2 (add, dpl, w) CR_TAB
6833              AS2 (rl, w, %H1) CR_TAB
6834              AS2 (add, dph, w);
6835     else
6836       return AS2 (mov, w, %L1) CR_TAB
6837              AS2 (mulu, w, %2) CR_TAB
6838              AS2 (add, w, %L3) CR_TAB
6839              AS2 (mov, %L0, w) CR_TAB
6840              AS2 (mov, w, %H3) CR_TAB
6841              AS2 (addc, w, MULH) CR_TAB
6842              AS2 (mov, %H0, w) CR_TAB
6843              AS2 (mov, w, %H1) CR_TAB
6844              AS2 (mulu, w, %2) CR_TAB
6845              AS2 (add, %H0, w);
6846   }")
6848 ;; Handle the a complex variant of the preceding multiply and add
6849 ;; operations where the intermediate result is also required.
6851 (define_peephole
6852   [(set (match_operand:HI 0 "nonimmediate_operand"         "=rS")
6853         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS")
6854                  (zero_extend:HI
6855                    (match_operand:QI 2 "const_int_operand"   "n"))))
6856    (set (match_operand:HI 3 "nonimmediate_operand"         "=rS")
6857         (plus:HI (match_dup 0)
6858                  (match_operand:HI 4 "general_operand"    "%rSi")))]
6859   "((!REG_P (operands[3])
6860      || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]),
6861                                    GET_MODE_SIZE (GET_MODE (operands[3])))
6862          && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]),
6863                                       GET_MODE_SIZE (GET_MODE (operands[3])))
6864          && ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]),
6865                                       GET_MODE_SIZE (GET_MODE (operands[3])))
6866          && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]),
6867                                       GET_MODE_SIZE (GET_MODE (operands[3])))))
6868     && (INTVAL (operands[2]) != 2))"
6869   "* return AS2 (mov, w, %H4) CR_TAB
6870             AS2 (mov, %H3, w) CR_TAB
6871             AS2 (mov, w, %L1) CR_TAB
6872             AS2 (mulu, w, %2) CR_TAB
6873             AS2 (mov, %L0, w) CR_TAB
6874             AS2 (add, w, %L4) CR_TAB
6875             AS2 (mov, %L3, w) CR_TAB
6876             AS2 (mov, w, MULH) CR_TAB
6877             AS2 (mov, %H0, w) CR_TAB
6878             AS2 (addc, %H3, w) CR_TAB
6879             AS2 (mov, w, %H1) CR_TAB
6880             AS2 (mulu, w, %2) CR_TAB
6881             AS2 (add, %H3, w) CR_TAB
6882             AS2 (add, %H0, w);")
6884 ;; Byte swapping!
6886 (define_peephole
6887   [(set (reg:QI 10)
6888         (match_operand:QI 1 "nonimmediate_operand" "rS"))
6889    (set (match_operand:QI 0 "register_operand"     "=r")
6890         (reg:QI 10))
6891    (set (reg:QI 10)
6892         (match_operand:QI 2 "nonimmediate_operand" "rS"))
6893    (set (match_dup 1)
6894         (reg:QI 10))
6895    (set (reg:QI 10)
6896         (match_dup 0))
6897    (set (match_dup 2)
6898         (reg:QI 10))]
6899   "find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))"
6900   "push\\t%1%<\;push\\t%2%<\;pop\\t%1%>\;pop\\t%2%>")