OSDN Git Service

777a03ee74e088ca569a5ec92fbfeb50ffa20e33
[pf3gnuchains/gcc-fork.git] / gcc / config / mcore / mcore.md
1 ;;  Machine description the Motorola MCore
2 ;;  Copyright (C) 1993, 1999, 2000, 2004, 2005
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Motorola.
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.
12
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.
17
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, 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25
26
27 ;; -------------------------------------------------------------------------
28 ;; Attributes
29 ;; -------------------------------------------------------------------------
30
31 ; Target CPU.
32
33 (define_attr "type" "brcond,branch,jmp,load,store,move,alu,shift"
34   (const_string "alu"))
35
36 ;; If a branch destination is within -2048..2047 bytes away from the
37 ;; instruction it can be 2 bytes long.  All other conditional branches
38 ;; are 10 bytes long, and all other unconditional branches are 8 bytes.
39 ;;
40 ;; the assembler handles the long-branch span case for us if we use
41 ;; the "jb*" mnemonics for jumps/branches. This pushes the span
42 ;; calculations and the literal table placement into the assembler,
43 ;; where their interactions can be managed in a single place.
44
45 ;; All MCORE instructions are two bytes long.
46
47 (define_attr "length" "" (const_int 2))
48
49 ;; Scheduling.  We only model a simple load latency.
50 (define_insn_reservation "any_insn" 1
51                          (eq_attr "type" "!load")
52                          "nothing")
53 (define_insn_reservation "memory" 2
54                          (eq_attr "type" "load")
55                          "nothing")
56
57 (include "predicates.md")
58
59 ;; -------------------------------------------------------------------------
60 ;; Test and bit test
61 ;; -------------------------------------------------------------------------
62
63 (define_insn ""
64   [(set (reg:SI 17) 
65         (sign_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
66                          (const_int 1)
67                          (match_operand:SI 1 "mcore_literal_K_operand" "K")))]
68   ""
69   "btsti        %0,%1"
70   [(set_attr "type" "shift")])
71
72 (define_insn ""
73   [(set (reg:SI 17) 
74         (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
75                          (const_int 1)
76                          (match_operand:SI 1 "mcore_literal_K_operand" "K")))]
77   ""
78   "btsti        %0,%1"
79   [(set_attr "type" "shift")])
80
81 ;;; This is created by combine.
82 (define_insn ""
83   [(set (reg:CC 17)
84         (ne:CC (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
85                                 (const_int 1)
86                                 (match_operand:SI 1 "mcore_literal_K_operand" "K"))
87                (const_int 0)))]
88   ""
89   "btsti        %0,%1"
90   [(set_attr "type" "shift")])
91
92
93 ;; Created by combine from conditional patterns below (see sextb/btsti rx,31)
94
95 (define_insn ""
96   [(set (reg:CC 17)
97         (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
98                             (const_int 7))
99                (const_int 0)))]
100   "GET_CODE(operands[0]) == SUBREG && 
101       GET_MODE(SUBREG_REG(operands[0])) == QImode"
102   "btsti        %0,7"
103   [(set_attr "type" "shift")])
104
105 (define_insn ""
106   [(set (reg:CC 17)
107         (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
108                             (const_int 15))
109                (const_int 0)))]
110   "GET_CODE(operands[0]) == SUBREG && 
111       GET_MODE(SUBREG_REG(operands[0])) == HImode"
112   "btsti        %0,15"
113   [(set_attr "type" "shift")])
114
115 (define_split
116   [(set (pc)
117         (if_then_else (ne (eq:CC (zero_extract:SI
118                                   (match_operand:SI 0 "mcore_arith_reg_operand" "")
119                                   (const_int 1)
120                                   (match_operand:SI 1 "mcore_literal_K_operand" ""))
121                                  (const_int 0))
122                           (const_int 0))
123                       (label_ref (match_operand 2 "" ""))
124                       (pc)))]
125   ""
126   [(set (reg:CC 17)
127         (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))
128    (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
129                            (label_ref (match_dup 2))
130                            (pc)))]
131   "")
132
133 (define_split
134   [(set (pc)
135         (if_then_else (eq (ne:CC (zero_extract:SI
136                                   (match_operand:SI 0 "mcore_arith_reg_operand" "")
137                                   (const_int 1)
138                                   (match_operand:SI 1 "mcore_literal_K_operand" ""))
139                                  (const_int 0))
140                           (const_int 0))
141                       (label_ref (match_operand 2 "" ""))
142                       (pc)))]
143   ""
144   [(set (reg:CC 17)
145         (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))
146    (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
147                            (label_ref (match_dup 2))
148                            (pc)))]
149   "")
150
151 ;; XXX - disabled by nickc because it fails on libiberty/fnmatch.c
152 ;;
153 ;; ; Experimental - relax immediates for and, andn, or, and tst to allow
154 ;; ;    any immediate value (or an immediate at all -- or, andn, & tst).  
155 ;; ;    This is done to allow bit field masks to fold together in combine.
156 ;; ;    The reload phase will force the immediate into a register at the
157 ;; ;    very end.  This helps in some cases, but hurts in others: we'd
158 ;; ;    really like to cse these immediates.  However, there is a phase
159 ;; ;    ordering problem here.  cse picks up individual masks and cse's
160 ;; ;    those, but not folded masks (cse happens before combine).  It's
161 ;; ;    not clear what the best solution is because we really want cse
162 ;; ;    before combine (leaving the bit field masks alone).   To pick up
163 ;; ;    relaxed immediates use -mrelax-immediates.  It might take some
164 ;; ;    experimenting to see which does better (i.e. regular imms vs.
165 ;; ;    arbitrary imms) for a particular code.   BRC
166 ;; 
167 ;; (define_insn ""
168 ;;   [(set (reg:CC 17)
169 ;;      (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
170 ;;                     (match_operand:SI 1 "mcore_arith_any_imm_operand" "rI"))
171 ;;             (const_int 0)))]
172 ;;   "TARGET_RELAX_IMM"
173 ;;   "tst       %0,%1")
174 ;; 
175 ;; (define_insn ""
176 ;;   [(set (reg:CC 17)
177 ;;      (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
178 ;;                     (match_operand:SI 1 "mcore_arith_M_operand" "r"))
179 ;;             (const_int 0)))]
180 ;;   "!TARGET_RELAX_IMM"
181 ;;   "tst       %0,%1")
182
183 (define_insn ""
184   [(set (reg:CC 17)
185         (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
186                        (match_operand:SI 1 "mcore_arith_M_operand" "r"))
187                (const_int 0)))]
188   ""
189   "tst  %0,%1")
190
191
192 (define_split 
193   [(parallel[
194       (set (reg:CC 17)
195            (ne:CC (ne:SI (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
196                                  (match_operand:SI 1 "mcore_arith_reg_operand" "r"))
197                          (const_int 0))
198                   (const_int 0)))
199       (clobber (match_operand:CC 2 "mcore_arith_reg_operand" "=r"))])]
200   ""
201   [(set (reg:CC 17) (ne:SI (match_dup 0) (const_int 0)))
202    (set (reg:CC 17) (leu:CC (match_dup 0) (match_dup 1)))])
203
204 ;; -------------------------------------------------------------------------
205 ;; SImode signed integer comparisons
206 ;; -------------------------------------------------------------------------
207
208 (define_insn "decne_t"
209   [(set (reg:CC 17) (ne:CC (plus:SI (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
210                                     (const_int -1))               
211                            (const_int 0)))
212    (set (match_dup 0)
213         (plus:SI (match_dup 0)
214                  (const_int -1)))]
215   ""
216   "decne        %0")
217
218 ;; The combiner seems to prefer the following to the former.
219 ;;
220 (define_insn ""
221   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
222                            (const_int 1)))
223    (set (match_dup 0)
224         (plus:SI (match_dup 0)
225                  (const_int -1)))]
226   ""
227   "decne        %0")
228
229 (define_insn "cmpnesi_t"
230   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
231                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
232   ""
233   "cmpne        %0,%1")
234
235 (define_insn "cmpneisi_t"
236   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
237                            (match_operand:SI 1 "mcore_arith_K_operand" "K")))]
238   ""
239   "cmpnei       %0,%1")
240
241 (define_insn "cmpgtsi_t"
242   [(set (reg:CC 17) (gt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
243                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
244   ""
245   "cmplt        %1,%0")
246
247 (define_insn ""
248   [(set (reg:CC 17) (gt:CC (plus:SI
249                             (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
250                             (const_int -1))
251                            (const_int 0)))
252    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
253   ""
254   "decgt        %0")
255
256 (define_insn "cmpltsi_t"
257   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
258                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
259   ""
260   "cmplt        %0,%1")
261
262 ; cmplti is 1-32
263 (define_insn "cmpltisi_t"
264   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
265                            (match_operand:SI 1 "mcore_arith_J_operand" "J")))]
266   ""
267   "cmplti       %0,%1")
268
269 ; covers cmplti x,0
270 (define_insn ""
271   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
272                          (const_int 0)))]
273   ""
274   "btsti        %0,31")
275
276 (define_insn ""
277   [(set (reg:CC 17) (lt:CC (plus:SI
278                             (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
279                             (const_int -1))
280                            (const_int 0)))
281    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
282   ""
283   "declt        %0")
284
285 ;; -------------------------------------------------------------------------
286 ;; SImode unsigned integer comparisons
287 ;; -------------------------------------------------------------------------
288
289 (define_insn "cmpgeusi_t"
290   [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
291                             (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
292   ""
293   "cmphs        %0,%1")
294
295 (define_insn "cmpgeusi_0"
296   [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
297                             (const_int 0)))]
298   ""
299   "cmpnei       %0, 0")
300
301 (define_insn "cmpleusi_t"
302   [(set (reg:CC 17) (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
303                             (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
304   ""
305   "cmphs        %1,%0")
306
307 ;; We save the compare operands in the cmpxx patterns and use them when
308 ;; we generate the branch.
309
310 ;; We accept constants here, in case we can modify them to ones which
311 ;; are more efficient to load.  E.g. change 'x <= 62' to 'x < 63'.
312
313 (define_expand "cmpsi"
314   [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "")
315                                 (match_operand:SI 1 "nonmemory_operand" "")))]
316   ""
317   "
318 { arch_compare_op0 = operands[0];
319   arch_compare_op1 = operands[1];
320   DONE;
321 }")
322
323 ;; -------------------------------------------------------------------------
324 ;; Logical operations
325 ;; -------------------------------------------------------------------------
326
327 ;; Logical AND clearing a single bit.  andsi3 knows that we have this
328 ;; pattern and allows the constant literal pass through.
329 ;;
330
331 ;; RBE 2/97: don't need this pattern any longer...
332 ;; RBE: I don't think we need both "S" and exact_log2() clauses.
333 ;;(define_insn ""
334 ;;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
335 ;;      (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
336 ;;              (match_operand:SI 2 "const_int_operand" "S")))]
337 ;;  "mcore_arith_S_operand (operands[2])"
338 ;;  "bclri      %0,%Q2")
339 ;;
340
341 (define_insn "andnsi3"
342   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
343         (and:SI (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))
344                 (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
345   ""
346   "andn %0,%1")
347
348 (define_expand "andsi3"
349   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
350         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
351                 (match_operand:SI 2 "nonmemory_operand" "")))]
352   ""
353   "
354 {
355   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0
356       && ! mcore_arith_S_operand (operands[2]))
357     {
358       int not_value = ~ INTVAL (operands[2]);
359       if (   CONST_OK_FOR_I (not_value)
360           || CONST_OK_FOR_M (not_value)
361           || CONST_OK_FOR_N (not_value))
362         {
363           operands[2] = copy_to_mode_reg (SImode, GEN_INT (not_value));
364           emit_insn (gen_andnsi3 (operands[0], operands[2], operands[1]));
365           DONE;
366         }
367     }
368
369   if (! mcore_arith_K_S_operand (operands[2], SImode))
370     operands[2] = copy_to_mode_reg (SImode, operands[2]);
371 }")
372
373 (define_insn ""
374   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
375         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0")
376                 (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,K,0,S")))]
377   "TARGET_RELAX_IMM"
378   "*
379 {
380    switch (which_alternative)
381      {
382      case 0: return \"and       %0,%2\";
383      case 1: return \"andi      %0,%2\";
384      case 2: return \"and       %0,%1\";
385      /* case -1: return \"bclri %0,%Q2\";        will not happen */
386      case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2]));
387      default: gcc_unreachable ();
388      }
389 }")
390
391 ;; This was the old "S" which was "!(2^n)" */
392 ;; case -1: return \"bclri      %0,%Q2\";        will not happen */
393
394 (define_insn ""
395   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
396         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0")
397                 (match_operand:SI 2 "mcore_arith_K_S_operand" "r,K,0,S")))]
398   "!TARGET_RELAX_IMM"
399   "*
400 {
401    switch (which_alternative)
402      {
403      case 0: return \"and       %0,%2\";
404      case 1: return \"andi      %0,%2\";
405      case 2: return \"and       %0,%1\";
406      case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2]));
407      default: gcc_unreachable ();
408      }
409 }")
410
411 ;(define_insn "iorsi3"
412 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
413 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
414 ;               (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
415 ;  ""
416 ;  "or  %0,%2")
417
418 ; need an expand to resolve ambiguity betw. the two iors below.
419 (define_expand "iorsi3"
420   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
421         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
422                 (match_operand:SI 2 "nonmemory_operand" "")))]
423   ""
424   "
425 {
426    if (! mcore_arith_M_operand (operands[2], SImode))
427       operands[2] = copy_to_mode_reg (SImode, operands[2]);
428 }")
429
430 (define_insn ""
431   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
432         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
433                 (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,M,T")))]
434   "TARGET_RELAX_IMM"
435   "*
436 {
437    switch (which_alternative)
438      {
439      case 0: return \"or        %0,%2\";
440      case 1: return \"bseti     %0,%P2\";
441      case 2: return mcore_output_bseti (operands[0], INTVAL (operands[2]));
442      default: gcc_unreachable ();
443      }
444 }")
445
446 (define_insn ""
447   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
448         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
449                 (match_operand:SI 2 "mcore_arith_M_operand" "r,M,T")))]
450   "!TARGET_RELAX_IMM"
451   "*
452 {
453    switch (which_alternative)
454      {
455      case 0: return \"or        %0,%2\";
456      case 1: return \"bseti     %0,%P2\";
457      case 2: return mcore_output_bseti (operands[0], INTVAL (operands[2]));
458      default: gcc_unreachable ();
459      }
460 }")
461
462 ;(define_insn ""
463 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
464 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
465 ;               (match_operand:SI 2 "const_int_operand" "M")))]
466 ;  "exact_log2 (INTVAL (operands[2])) >= 0"
467 ;  "bseti       %0,%P2")
468
469 ;(define_insn ""
470 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
471 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
472 ;               (match_operand:SI 2 "const_int_operand" "i")))]
473 ;  "mcore_num_ones (INTVAL (operands[2])) < 3"
474 ;  "* return mcore_output_bseti (operands[0], INTVAL (operands[2]));")
475
476 (define_insn "xorsi3"
477   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
478         (xor:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
479                 (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
480   ""
481   "xor  %0,%2")
482
483 ; these patterns give better code then gcc invents if
484 ; left to its own devices
485
486 (define_insn "anddi3"
487   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
488         (and:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
489                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
490   ""
491   "and  %0,%2\;and      %R0,%R2"
492   [(set_attr "length" "4")])
493
494 (define_insn "iordi3"
495   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
496         (ior:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
497                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
498   ""
499   "or   %0,%2\;or       %R0,%R2"
500   [(set_attr "length" "4")])
501
502 (define_insn "xordi3"
503   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
504         (xor:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
505                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
506   ""
507   "xor  %0,%2\;xor      %R0,%R2"
508   [(set_attr "length" "4")])
509
510 ;; -------------------------------------------------------------------------
511 ;; Shifts and rotates
512 ;; -------------------------------------------------------------------------
513
514 ;; Only allow these if the shift count is a convenient constant.
515 (define_expand "rotlsi3"
516   [(set (match_operand:SI            0 "mcore_arith_reg_operand" "")
517         (rotate:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
518                    (match_operand:SI 2 "nonmemory_operand" "")))]
519   ""
520   "if (! mcore_literal_K_operand (operands[2], SImode))
521          FAIL;
522   ")
523
524 ;; We can only do constant rotates, which is what this pattern provides.
525 ;; The combiner will put it together for us when we do:
526 ;;      (x << N) | (x >> (32 - N))
527 (define_insn ""
528   [(set (match_operand:SI              0 "mcore_arith_reg_operand" "=r")
529         (rotate:SI (match_operand:SI   1 "mcore_arith_reg_operand"  "0")
530                      (match_operand:SI 2 "mcore_literal_K_operand"  "K")))]
531   ""
532   "rotli        %0,%2"
533   [(set_attr "type" "shift")])
534
535 (define_insn "ashlsi3"
536   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
537         (ashift:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
538                    (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
539   ""
540   "@
541         lsl     %0,%2
542         lsli    %0,%2"
543   [(set_attr "type" "shift")])
544
545 (define_insn ""
546   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
547         (ashift:SI (const_int 1)
548                    (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
549   ""
550   "bgenr        %0,%1"
551   [(set_attr "type" "shift")])
552
553 (define_insn "ashrsi3"
554   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
555         (ashiftrt:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
556                      (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
557   ""
558   "@
559         asr     %0,%2
560         asri    %0,%2"
561   [(set_attr "type" "shift")])
562
563 (define_insn "lshrsi3"
564   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
565         (lshiftrt:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
566                      (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
567   ""
568   "@
569         lsr     %0,%2
570         lsri    %0,%2"
571   [(set_attr "type" "shift")])
572
573 ;(define_expand "ashldi3"
574 ;  [(parallel[(set (match_operand:DI 0 "mcore_arith_reg_operand" "")
575 ;                 (ashift:DI (match_operand:DI 1 "mcore_arith_reg_operand" "")
576 ;                            (match_operand:DI 2 "immediate_operand" "")))
577 ;
578 ;            (clobber (reg:CC 17))])]
579 ;           
580 ;  ""
581 ;  "
582 ;{
583 ;  if (GET_CODE (operands[2]) != CONST_INT
584 ;      || INTVAL (operands[2]) != 1)
585 ;    FAIL;
586 ;}")
587 ;
588 ;(define_insn ""
589 ;  [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
590 ;       (ashift:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
591 ;                    (const_int 1)))
592 ;   (clobber (reg:CC 17))]
593 ;  ""
594 ;  "lsli        %R0,0\;rotli    %0,0"
595 ;  [(set_attr "length" "4") (set_attr "type" "shift")])
596
597 ;; -------------------------------------------------------------------------
598 ;; Index instructions
599 ;; -------------------------------------------------------------------------
600 ;; The second of each set of patterns is borrowed from the alpha.md file.
601 ;; These variants of the above insns can occur if the second operand
602 ;; is the frame pointer.  This is a kludge, but there doesn't
603 ;; seem to be a way around it.  Only recognize them while reloading.
604
605 ;; We must use reload_operand for some operands in case frame pointer
606 ;; elimination put a MEM with invalid address there.  Otherwise,
607 ;; the result of the substitution will not match this pattern, and reload
608 ;; will not be able to correctly fix the result.
609
610 ;; indexing longlongs or doubles (8 bytes)
611
612 (define_insn "indexdi_t"
613   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
614         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
615                           (const_int 8))
616                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
617   ""
618   "*
619     if (! mcore_is_same_reg (operands[1], operands[2]))
620       {
621         output_asm_insn (\"ixw\\t%0,%1\", operands);
622         output_asm_insn (\"ixw\\t%0,%1\", operands);
623       }
624     else
625       {
626         output_asm_insn (\"ixh\\t%0,%1\", operands);
627         output_asm_insn (\"ixh\\t%0,%1\", operands);
628       }
629     return \"\";
630   "
631 ;; if operands[1] == operands[2], the first option above is wrong! -- dac
632 ;; was this... -- dac
633 ;; ixw  %0,%1\;ixw      %0,%1"
634
635   [(set_attr "length" "4")])
636
637 (define_insn ""
638   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
639         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
640                                    (const_int 8))
641                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
642                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
643   "reload_in_progress"
644   "@
645         ixw     %0,%1\;ixw      %0,%1\;addu     %0,%3
646         ixw     %0,%1\;ixw      %0,%1\;addi     %0,%3
647         ixw     %0,%1\;ixw      %0,%1\;subi     %0,%M3"
648   [(set_attr "length" "6")])
649
650 ;; indexing longs (4 bytes)
651
652 (define_insn "indexsi_t"
653   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
654         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
655                           (const_int 4))
656                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
657   ""
658   "ixw  %0,%1")
659
660 (define_insn ""
661   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
662         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
663                                    (const_int 4))
664                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
665                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
666   "reload_in_progress"
667   "@
668         ixw     %0,%1\;addu     %0,%3
669         ixw     %0,%1\;addi     %0,%3
670         ixw     %0,%1\;subi     %0,%M3"
671   [(set_attr "length" "4")])
672
673 ;; indexing shorts (2 bytes)
674
675 (define_insn "indexhi_t"
676   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
677         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
678                           (const_int 2))
679                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
680   ""
681   "ixh  %0,%1")
682
683 (define_insn ""
684   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
685         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
686                                    (const_int 2))
687                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
688                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
689   "reload_in_progress"
690   "@
691         ixh     %0,%1\;addu     %0,%3
692         ixh     %0,%1\;addi     %0,%3
693         ixh     %0,%1\;subi     %0,%M3"
694   [(set_attr "length" "4")])
695
696 ;;
697 ;; Other sizes may be handy for indexing. 
698 ;; the tradeoffs to consider when adding these are
699 ;;      code size, execution time [vs. mul it is easy to win],
700 ;;      and register pressure -- these patterns don't use an extra
701 ;;      register to build the offset from the base
702 ;;      and whether the compiler will not come up with some other idiom.
703 ;;
704
705 ;; -------------------------------------------------------------------------
706 ;; Addition, Subtraction instructions
707 ;; -------------------------------------------------------------------------
708
709 (define_expand "addsi3"
710   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
711         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
712                  (match_operand:SI 2 "nonmemory_operand" "")))]
713   ""
714   "
715 {
716   extern int flag_omit_frame_pointer;
717
718   /* If this is an add to the frame pointer, then accept it as is so
719      that we can later fold in the fp/sp offset from frame pointer
720      elimination.  */
721   if (flag_omit_frame_pointer
722       && GET_CODE (operands[1]) == REG
723       && (REGNO (operands[1]) == VIRTUAL_STACK_VARS_REGNUM
724           || REGNO (operands[1]) == FRAME_POINTER_REGNUM))
725     {
726       emit_insn (gen_addsi3_fp (operands[0], operands[1], operands[2]));
727       DONE;
728     }
729
730   /* Convert adds to subtracts if this makes loading the constant cheaper.
731      But only if we are allowed to generate new pseudos.  */
732   if (! (reload_in_progress || reload_completed)
733       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < -32)
734     {
735       int neg_value = - INTVAL (operands[2]);
736       if (   CONST_OK_FOR_I (neg_value)
737           || CONST_OK_FOR_M (neg_value)
738           || CONST_OK_FOR_N (neg_value))
739         {
740           operands[2] = copy_to_mode_reg (SImode, GEN_INT (neg_value));
741           emit_insn (gen_subsi3 (operands[0], operands[1], operands[2]));
742           DONE;
743         }
744     } 
745
746   if (! mcore_addsub_operand (operands[2], SImode))
747     operands[2] = copy_to_mode_reg (SImode, operands[2]);
748 }")
749  
750 ;; RBE: for some constants which are not in the range which allows
751 ;; us to do a single operation, we will try a paired addi/addi instead
752 ;; of a movi/addi. This relieves some register pressure at the expense
753 ;; of giving away some potential constant reuse.
754 ;;
755 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
756 ;; for later reference
757 ;; 
758 ;; (define_insn "addsi3_i2"
759 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
760 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
761 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
762 ;;   "GET_CODE(operands[2]) == CONST_INT
763 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
764 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
765 ;;   "*
766 ;; {
767 ;;    int n = INTVAL(operands[2]);
768 ;;    if (n > 0)
769 ;;      {
770 ;;        operands[2] = GEN_INT(n - 32);
771 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
772 ;;      }
773 ;;    else
774 ;;      {
775 ;;        n = (-n);
776 ;;        operands[2] = GEN_INT(n - 32);
777 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
778 ;;      }
779 ;; }"
780 ;;  [(set_attr "length" "4")])
781
782 (define_insn "addsi3_i"
783   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
784         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
785                  (match_operand:SI 2 "mcore_addsub_operand" "r,J,L")))]
786   ""
787   "@
788         addu    %0,%2
789         addi    %0,%2
790         subi    %0,%M2")
791
792 ;; This exists so that address computations based on the frame pointer
793 ;; can be folded in when frame pointer elimination occurs.  Ordinarily
794 ;; this would be bad because it allows insns which would require reloading,
795 ;; but without it, we get multiple adds where one would do.
796
797 (define_insn "addsi3_fp"
798   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
799         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
800                  (match_operand:SI 2 "immediate_operand" "r,J,L")))]
801   "flag_omit_frame_pointer
802    && (reload_in_progress || reload_completed || REGNO (operands[1]) == FRAME_POINTER_REGNUM)"
803   "@
804         addu    %0,%2
805         addi    %0,%2
806         subi    %0,%M2")
807
808 ;; RBE: for some constants which are not in the range which allows
809 ;; us to do a single operation, we will try a paired addi/addi instead
810 ;; of a movi/addi. This relieves some register pressure at the expense
811 ;; of giving away some potential constant reuse.
812 ;;
813 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
814 ;; for later reference
815 ;; 
816 ;; (define_insn "subsi3_i2"
817 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
818 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
819 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
820 ;;   "TARGET_RBETEST && GET_CODE(operands[2]) == CONST_INT
821 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
822 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
823 ;;   "*
824 ;; {
825 ;;    int n = INTVAL(operands[2]);
826 ;;    if ( n > 0)
827 ;;      {
828 ;;        operands[2] = GEN_INT( n - 32);
829 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
830 ;;      }
831 ;;    else
832 ;;      {
833 ;;        n = (-n);
834 ;;        operands[2] = GEN_INT(n - 32);
835 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
836 ;;      }
837 ;; }"
838 ;;   [(set_attr "length" "4")])
839
840 ;(define_insn "subsi3"
841 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
842 ;       (minus:SI (match_operand:SI 1 "mcore_arith_K_operand" "0,0,r,K")
843 ;                 (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0,0")))]
844 ;  ""
845 ;  "@
846 ;       sub     %0,%2
847 ;       subi    %0,%2
848 ;       rsub    %0,%1
849 ;       rsubi   %0,%1")
850
851 (define_insn "subsi3"
852   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
853         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r")
854                   (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0")))]
855   ""
856   "@
857         subu    %0,%2
858         subi    %0,%2
859         rsub    %0,%1")
860
861 (define_insn ""
862   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
863         (minus:SI (match_operand:SI 1 "mcore_literal_K_operand" "K")
864                   (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
865   ""
866   "rsubi        %0,%1")
867
868 (define_insn "adddi3"
869   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
870         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
871                  (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
872    (clobber (reg:CC 17))]
873   ""
874   "*
875   {
876     if (TARGET_LITTLE_END)
877       return \"cmplt    %0,%0\;addc     %0,%2\;addc     %R0,%R2\";
878     return \"cmplt      %R0,%R0\;addc   %R0,%R2\;addc   %0,%2\";
879   }"
880   [(set_attr "length" "6")])
881
882 ;; special case for "longlong += 1"
883 (define_insn ""
884   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
885         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
886                  (const_int 1)))
887    (clobber (reg:CC 17))]
888   ""
889   "*
890   {
891    if (TARGET_LITTLE_END)
892       return \"addi     %0,1\;cmpnei %0,0\;incf %R0\";
893     return \"addi       %R0,1\;cmpnei %R0,0\;incf       %0\";
894   }"
895   [(set_attr "length" "6")])
896
897 ;; special case for "longlong -= 1"
898 (define_insn ""
899   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
900         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
901                  (const_int -1)))
902    (clobber (reg:CC 17))]
903   ""
904   "*
905   {
906     if (TARGET_LITTLE_END)
907        return \"cmpnei %0,0\;decf       %R0\;subi       %0,1\";
908     return \"cmpnei %R0,0\;decf %0\;subi        %R0,1\";
909   }"
910   [(set_attr "length" "6")])
911
912 ;; special case for "longlong += const_int"
913 ;; we have to use a register for the const_int because we don't
914 ;; have an unsigned compare immediate... only +/- 1 get to
915 ;; play the no-extra register game because they compare with 0.
916 ;; This winds up working out for any literal that is synthesized
917 ;; with a single instruction. The more complicated ones look
918 ;; like the get broken into subreg's to get initialized too soon
919 ;; for us to catch here. -- RBE 4/25/96
920 ;; only allow for-sure positive values.
921
922 (define_insn ""
923   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
924         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
925                  (match_operand:SI 2 "const_int_operand" "r")))
926    (clobber (reg:CC 17))]
927   "GET_CODE (operands[2]) == CONST_INT
928    && INTVAL (operands[2]) > 0 && ! (INTVAL (operands[2]) & 0x80000000)"
929   "*
930 {
931   gcc_assert (GET_MODE (operands[2]) == SImode);
932   if (TARGET_LITTLE_END)
933     return \"addu       %0,%2\;cmphs    %0,%2\;incf     %R0\";
934   return \"addu %R0,%2\;cmphs   %R0,%2\;incf    %0\";
935 }"
936   [(set_attr "length" "6")])
937
938 ;; optimize "long long" + "unsigned long"
939 ;; won't trigger because of how the extension is expanded upstream.
940 ;; (define_insn ""
941 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
942 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
943 ;;               (zero_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
944 ;;    (clobber (reg:CC 17))]
945 ;;   "0"
946 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0"
947 ;;   [(set_attr "length" "6")])
948
949 ;; optimize "long long" + "signed long"
950 ;; won't trigger because of how the extension is expanded upstream.
951 ;; (define_insn ""
952 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
953 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
954 ;;               (sign_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
955 ;;    (clobber (reg:CC 17))]
956 ;;   "0"
957 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0\;btsti       %2,31\;dect     %0"
958 ;;   [(set_attr "length" "6")])
959
960 (define_insn "subdi3"
961   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
962         (minus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
963                   (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
964    (clobber (reg:CC 17))]
965   ""
966   "*
967   {
968     if (TARGET_LITTLE_END)
969       return \"cmphs    %0,%0\;subc     %0,%2\;subc     %R0,%R2\";
970     return \"cmphs      %R0,%R0\;subc   %R0,%R2\;subc   %0,%2\";
971   }"
972   [(set_attr "length" "6")])
973
974 ;; -------------------------------------------------------------------------
975 ;; Multiplication instructions
976 ;; -------------------------------------------------------------------------
977
978 (define_insn "mulsi3"
979   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
980         (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
981                  (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
982   ""
983   "mult %0,%2")
984
985 ;;
986 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
987 ;;
988 ;; Different constraints based on the architecture revision...
989 ;;
990 (define_expand "divsi3"
991   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
992         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
993                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
994   "TARGET_DIV"
995   "")
996  
997 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
998 ;;
999 (define_insn ""
1000   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1001         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1002                 (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
1003   "TARGET_DIV"
1004   "divs %0,%2")
1005
1006 ;;
1007 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
1008 ;;
1009 ;; Different constraints based on the architecture revision...
1010 ;;
1011 (define_expand "udivsi3"
1012   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1013         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1014                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1015   "TARGET_DIV"
1016   "")
1017  
1018 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
1019 (define_insn ""
1020   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1021         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1022                  (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
1023   "TARGET_DIV"
1024   "divu %0,%2")
1025  
1026 ;; -------------------------------------------------------------------------
1027 ;; Unary arithmetic
1028 ;; -------------------------------------------------------------------------
1029
1030 (define_insn "negsi2"
1031   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1032         (neg:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1033   ""
1034   "*
1035 {
1036    return \"rsubi       %0,0\";
1037 }")
1038
1039
1040 (define_insn "abssi2"
1041   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1042         (abs:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1043   ""
1044   "abs  %0")
1045              
1046 (define_insn "negdi2"
1047   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
1048         (neg:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")))
1049    (clobber (reg:CC 17))]
1050   ""
1051   "*
1052 {
1053    if (TARGET_LITTLE_END)
1054      return \"cmpnei    %0,0\\n\\trsubi %0,0\\n\\tnot   %R0\\n\\tincf   %R0\";
1055    return \"cmpnei      %R0,0\\n\\trsubi        %R0,0\\n\\tnot  %0\\n\\tincf    %0\";
1056 }"
1057   [(set_attr "length" "8")])
1058
1059 (define_insn "one_cmplsi2"
1060   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1061         (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1062   ""
1063   "not  %0")
1064
1065 ;; -------------------------------------------------------------------------
1066 ;; Zero extension instructions
1067 ;; -------------------------------------------------------------------------
1068
1069 (define_expand "zero_extendhisi2"
1070   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1071         (zero_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "")))]
1072   ""
1073   "")
1074
1075 (define_insn ""
1076   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
1077         (zero_extend:SI (match_operand:HI 1 "general_operand" "0,m")))]
1078   ""
1079   "@
1080         zexth   %0
1081         ld.h    %0,%1"
1082   [(set_attr "type" "shift,load")])
1083
1084 ;; ldh gives us a free zero-extension. The combiner picks up on this.
1085 (define_insn ""
1086   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1087         (zero_extend:SI (mem:HI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1088   ""
1089   "ld.h %0,(%1)"
1090   [(set_attr "type" "load")])
1091
1092 (define_insn ""
1093   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1094         (zero_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1095                                          (match_operand:SI 2 "const_int_operand" "")))))]
1096   "(INTVAL (operands[2]) >= 0) &&
1097    (INTVAL (operands[2]) < 32) &&
1098    ((INTVAL (operands[2])&1) == 0)"
1099   "ld.h %0,(%1,%2)"
1100   [(set_attr "type" "load")])
1101
1102 (define_expand "zero_extendqisi2"
1103   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1104         (zero_extend:SI (match_operand:QI 1 "general_operand" "")))]
1105   ""
1106   "") 
1107
1108 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1109 (define_insn ""
1110   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b,r")
1111         (zero_extend:SI (match_operand:QI 1 "general_operand" "0,r,m")))]
1112   ""
1113   "@
1114         zextb   %0
1115         xtrb3   %0,%1
1116         ld.b    %0,%1"
1117   [(set_attr "type" "shift,shift,load")])
1118
1119 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1120 (define_insn ""
1121   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1122         (zero_extend:SI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1123   ""
1124   "ld.b %0,(%1)"
1125   [(set_attr "type" "load")])
1126
1127 (define_insn ""
1128   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1129         (zero_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1130                                          (match_operand:SI 2 "const_int_operand" "")))))]
1131   "(INTVAL (operands[2]) >= 0) &&
1132    (INTVAL (operands[2]) < 16)"
1133   "ld.b %0,(%1,%2)"
1134   [(set_attr "type" "load")])
1135
1136 (define_expand "zero_extendqihi2"
1137   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "")
1138         (zero_extend:HI (match_operand:QI 1 "general_operand" "")))]
1139   ""
1140   "") 
1141
1142 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1143 (define_insn ""
1144   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r,b,r")
1145         (zero_extend:HI (match_operand:QI 1 "general_operand" "0,r,m")))]
1146   ""
1147   "@
1148         zextb   %0
1149         xtrb3   %0,%1
1150         ld.b    %0,%1"
1151   [(set_attr "type" "shift,shift,load")])
1152
1153 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1154 ;; this doesn't catch references that are into a structure.
1155 ;; note that normally the compiler uses the above insn, unless it turns
1156 ;; out that we're dealing with a volatile...
1157 (define_insn ""
1158   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1159         (zero_extend:HI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1160   ""
1161   "ld.b %0,(%1)"
1162   [(set_attr "type" "load")])
1163
1164 (define_insn ""
1165   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1166         (zero_extend:HI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1167                                          (match_operand:SI 2 "const_int_operand" "")))))]
1168   "(INTVAL (operands[2]) >= 0) &&
1169    (INTVAL (operands[2]) < 16)"
1170   "ld.b %0,(%1,%2)"
1171   [(set_attr "type" "load")])
1172
1173
1174 ;; -------------------------------------------------------------------------
1175 ;; Sign extension instructions
1176 ;; -------------------------------------------------------------------------
1177
1178 (define_expand "extendsidi2"
1179   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r") 
1180         (match_operand:SI 1 "mcore_arith_reg_operand" "r"))]
1181   ""
1182   "
1183   {
1184     int low, high;
1185
1186     if (TARGET_LITTLE_END)
1187       low = 0, high = 4;
1188     else
1189       low = 4, high = 0;
1190     
1191     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], low),
1192               operands[1]));
1193     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], high),
1194               gen_rtx_ASHIFTRT (SImode,
1195                                gen_rtx_SUBREG (SImode, operands[0], low),
1196                                GEN_INT (31))));
1197     DONE;
1198   }"
1199 )
1200
1201 (define_insn "extendhisi2"
1202   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1203         (sign_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "0")))]
1204   ""
1205   "sexth        %0")
1206
1207 (define_insn "extendqisi2"
1208   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1209         (sign_extend:SI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1210   ""
1211   "sextb        %0")
1212
1213 (define_insn "extendqihi2"
1214   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1215         (sign_extend:HI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1216   ""
1217   "sextb        %0")
1218
1219 ;; -------------------------------------------------------------------------
1220 ;; Move instructions
1221 ;; -------------------------------------------------------------------------
1222
1223 ;; SImode
1224
1225 (define_expand "movsi"
1226   [(set (match_operand:SI 0 "general_operand" "")
1227         (match_operand:SI 1 "general_operand" ""))]
1228   ""
1229   "
1230 {
1231   if (GET_CODE (operands[0]) == MEM)
1232     operands[1] = force_reg (SImode, operands[1]);
1233 }")
1234
1235 (define_insn ""
1236   [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,a,r,a,r,m")
1237         (match_operand:SI 1 "mcore_general_movsrc_operand"  "r,P,i,c,R,m,r"))]
1238   "(register_operand (operands[0], SImode)
1239     || register_operand (operands[1], SImode))"
1240   "* return mcore_output_move (insn, operands, SImode);"
1241   [(set_attr "type" "move,move,move,move,load,load,store")])
1242
1243 ;;
1244 ;; HImode
1245 ;;
1246
1247 (define_expand "movhi"
1248   [(set (match_operand:HI 0 "general_operand" "")
1249         (match_operand:HI 1 "general_operand"  ""))]
1250   ""
1251   "
1252 {
1253   if (GET_CODE (operands[0]) == MEM)
1254     operands[1] = force_reg (HImode, operands[1]);
1255   else if (CONSTANT_P (operands[1])
1256            && (GET_CODE (operands[1]) != CONST_INT
1257                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1258                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1259                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1260            && ! reload_completed && ! reload_in_progress)
1261     {
1262       rtx reg = gen_reg_rtx (SImode);
1263       emit_insn (gen_movsi (reg, operands[1]));
1264       operands[1] = gen_lowpart (HImode, reg);
1265     }
1266 }")
1267   
1268 (define_insn ""
1269   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1270         (match_operand:HI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1271   "(register_operand (operands[0], HImode)
1272     || register_operand (operands[1], HImode))"
1273   "* return mcore_output_move (insn, operands, HImode);"
1274   [(set_attr "type" "move,move,move,move,load,store")])
1275
1276 ;;
1277 ;; QImode
1278 ;;
1279
1280 (define_expand "movqi"
1281   [(set (match_operand:QI 0 "general_operand" "")
1282         (match_operand:QI 1 "general_operand"  ""))]
1283   ""
1284   "
1285 {
1286   if (GET_CODE (operands[0]) == MEM)
1287     operands[1] = force_reg (QImode, operands[1]);
1288   else if (CONSTANT_P (operands[1])
1289            && (GET_CODE (operands[1]) != CONST_INT
1290                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1291                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1292                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1293            && ! reload_completed && ! reload_in_progress)
1294     {
1295       rtx reg = gen_reg_rtx (SImode);
1296       emit_insn (gen_movsi (reg, operands[1]));
1297       operands[1] = gen_lowpart (QImode, reg);
1298     }
1299 }")
1300   
1301 (define_insn ""
1302   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1303         (match_operand:QI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1304   "(register_operand (operands[0], QImode)
1305     || register_operand (operands[1], QImode))"
1306   "* return mcore_output_move (insn, operands, QImode);"
1307    [(set_attr "type" "move,move,move,move,load,store")])
1308
1309
1310 ;; DImode
1311
1312 (define_expand "movdi"
1313   [(set (match_operand:DI 0 "general_operand" "")
1314         (match_operand:DI 1 "general_operand" ""))]
1315   ""
1316   "
1317 {
1318   if (GET_CODE (operands[0]) == MEM)
1319     operands[1] = force_reg (DImode, operands[1]);
1320   else if (GET_CODE (operands[1]) == CONST_INT
1321            && ! CONST_OK_FOR_I (INTVAL (operands[1]))
1322            && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1323            && ! CONST_OK_FOR_N (INTVAL (operands[1])))
1324     {
1325       int i;
1326       for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
1327         emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
1328                         simplify_gen_subreg (SImode, operands[1], DImode, i));
1329       DONE;
1330     }
1331 }")
1332
1333 (define_insn "movdi_i"
1334   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,a,r,m")
1335         (match_operand:DI 1 "mcore_general_movsrc_operand" "I,M,N,r,R,m,r"))]
1336   ""
1337   "* return mcore_output_movedouble (operands, DImode);"
1338   [(set_attr "length" "4") (set_attr "type" "move,move,move,move,load,load,store")])
1339
1340 ;; SFmode
1341
1342 (define_expand "movsf"
1343   [(set (match_operand:SF 0 "general_operand" "")
1344         (match_operand:SF 1 "general_operand" ""))]
1345   ""
1346   "
1347 {
1348   if (GET_CODE (operands[0]) == MEM)
1349     operands[1] = force_reg (SFmode, operands[1]);
1350 }")
1351
1352 (define_insn "movsf_i"
1353   [(set (match_operand:SF 0 "general_operand" "=r,r,m")
1354         (match_operand:SF 1 "general_operand"  "r,m,r"))]
1355   ""
1356   "@
1357         mov     %0,%1
1358         ld.w    %0,%1
1359         st.w    %1,%0"
1360   [(set_attr "type" "move,load,store")])
1361
1362 ;; DFmode
1363
1364 (define_expand "movdf"
1365   [(set (match_operand:DF 0 "general_operand" "")
1366         (match_operand:DF 1 "general_operand" ""))]
1367   ""
1368   "
1369 {
1370   if (GET_CODE (operands[0]) == MEM)
1371     operands[1] = force_reg (DFmode, operands[1]);
1372 }")
1373
1374 (define_insn "movdf_k"
1375   [(set (match_operand:DF 0 "general_operand" "=r,r,m")
1376         (match_operand:DF 1 "general_operand" "r,m,r"))]
1377   ""
1378   "* return mcore_output_movedouble (operands, DFmode);"
1379   [(set_attr "length" "4") (set_attr "type" "move,load,store")])
1380
1381
1382 ;; Load/store multiple
1383
1384 ;; ??? This is not currently used.
1385 (define_insn "ldm"
1386   [(set (match_operand:TI 0 "mcore_arith_reg_operand" "=r")
1387         (mem:TI (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
1388   ""
1389   "ldq  %U0,(%1)")
1390
1391 ;; ??? This is not currently used.
1392 (define_insn "stm"
1393   [(set (mem:TI (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1394         (match_operand:TI 1 "mcore_arith_reg_operand" "r"))]
1395   ""
1396   "stq  %U1,(%0)")
1397
1398 (define_expand "load_multiple"
1399   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1400                           (match_operand:SI 1 "" ""))
1401                      (use (match_operand:SI 2 "" ""))])]
1402   ""
1403   "
1404 {
1405   int regno, count, i;
1406
1407   /* Support only loading a constant number of registers from memory and
1408      only if at least two registers.  The last register must be r15.  */
1409   if (GET_CODE (operands[2]) != CONST_INT
1410       || INTVAL (operands[2]) < 2
1411       || GET_CODE (operands[1]) != MEM
1412       || XEXP (operands[1], 0) != stack_pointer_rtx
1413       || GET_CODE (operands[0]) != REG
1414       || REGNO (operands[0]) + INTVAL (operands[2]) != 16)
1415     FAIL;
1416
1417   count = INTVAL (operands[2]);
1418   regno = REGNO (operands[0]);
1419
1420   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1421
1422   for (i = 0; i < count; i++)
1423     XVECEXP (operands[3], 0, i)
1424       = gen_rtx_SET (VOIDmode,
1425                  gen_rtx_REG (SImode, regno + i),
1426                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1427                                                       i * 4)));
1428 }")
1429
1430 (define_insn ""
1431   [(match_parallel 0 "mcore_load_multiple_operation"
1432                    [(set (match_operand:SI 1 "mcore_arith_reg_operand" "=r")
1433                          (mem:SI (match_operand:SI 2 "register_operand" "r")))])]
1434   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1435   "ldm  %1-r15,(%2)")
1436
1437 (define_expand "store_multiple"
1438   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1439                           (match_operand:SI 1 "" ""))
1440                      (use (match_operand:SI 2 "" ""))])]
1441   ""
1442   "
1443 {
1444   int regno, count, i;
1445
1446   /* Support only storing a constant number of registers to memory and
1447      only if at least two registers.  The last register must be r15.  */
1448   if (GET_CODE (operands[2]) != CONST_INT
1449       || INTVAL (operands[2]) < 2
1450       || GET_CODE (operands[0]) != MEM
1451       || XEXP (operands[0], 0) != stack_pointer_rtx
1452       || GET_CODE (operands[1]) != REG
1453       || REGNO (operands[1]) + INTVAL (operands[2]) != 16)
1454     FAIL;
1455
1456   count = INTVAL (operands[2]);
1457   regno = REGNO (operands[1]);
1458
1459   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1460
1461   for (i = 0; i < count; i++)
1462     XVECEXP (operands[3], 0, i)
1463       = gen_rtx_SET (VOIDmode,
1464                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1465                                                       i * 4)),
1466                  gen_rtx_REG (SImode, regno + i));
1467 }")
1468
1469 (define_insn ""
1470   [(match_parallel 0 "mcore_store_multiple_operation"
1471                    [(set (mem:SI (match_operand:SI 2 "register_operand" "r"))
1472                          (match_operand:SI 1 "mcore_arith_reg_operand" "r"))])]
1473   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1474   "stm  %1-r15,(%2)")
1475
1476 ;; ------------------------------------------------------------------------
1477 ;; Define the real conditional branch instructions.
1478 ;; ------------------------------------------------------------------------
1479
1480 (define_insn "branch_true"
1481   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1482                            (label_ref (match_operand 0 "" ""))
1483                            (pc)))]
1484   ""
1485   "jbt  %l0"
1486   [(set_attr "type" "brcond")])
1487
1488 (define_insn "branch_false"
1489   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1490                            (label_ref (match_operand 0 "" ""))
1491                            (pc)))]
1492   ""
1493   "jbf  %l0"
1494   [(set_attr "type" "brcond")])
1495
1496 (define_insn "inverse_branch_true"
1497   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1498                            (pc)
1499                            (label_ref (match_operand 0 "" ""))))]
1500   ""
1501   "jbf  %l0"
1502   [(set_attr "type" "brcond")])
1503
1504 (define_insn "inverse_branch_false"
1505   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1506                            (pc)
1507                            (label_ref (match_operand 0 "" ""))))]
1508   ""
1509   "jbt  %l0"
1510   [(set_attr "type" "brcond")])
1511
1512 ;; Conditional branch insns
1513
1514 ;; At top-level, condition test are eq/ne, because we
1515 ;; are comparing against the condition register (which
1516 ;; has the result of the true relational test
1517
1518 ; There is no beq compare, so we reverse the branch arms.
1519
1520 (define_expand "beq"
1521   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1522                            (pc)
1523                            (label_ref (match_operand 0 "" ""))))]
1524   ""
1525   "
1526 {
1527   operands[1] = mcore_gen_compare_reg (EQ);
1528 }")
1529
1530 (define_expand "bne"
1531   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1532                            (label_ref (match_operand 0 "" ""))
1533                            (pc)))]
1534   ""
1535   "
1536 {
1537   operands[1] = mcore_gen_compare_reg (NE);
1538 }")
1539
1540 ; check whether (GT A imm) can become (LE A imm) with the branch reversed.  
1541 ; if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
1542
1543 (define_expand "bgt"
1544   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1545                            (label_ref (match_operand 0 "" ""))
1546                            (pc)))]
1547   ""
1548   "
1549 {
1550   if (mcore_modify_comparison (LE))
1551     {
1552       emit_jump_insn (gen_reverse_blt (operands[0]));
1553       DONE;
1554     }
1555   operands[1] = mcore_gen_compare_reg (GT);
1556 }")
1557
1558 ; There is no ble compare, so we reverse the branch arms.
1559 ; reversed the condition and branch arms for ble -- the check_dbra_loop()
1560 ; transformation assumes that ble uses a branch-true with the label as
1561 ; as the target. BRC
1562
1563 ; check whether (LE A imm) can become (LT A imm + 1).
1564
1565 (define_expand "ble"
1566   [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
1567                            (label_ref (match_operand 0 "" ""))
1568                            (pc)))]
1569   ""
1570   "
1571 {
1572   if (mcore_modify_comparison (LE))
1573     {
1574       emit_jump_insn (gen_blt (operands[0]));
1575       DONE;
1576     }
1577   operands[1] = mcore_gen_compare_reg (LE);
1578 }")
1579
1580 ; make generating a reversed blt simple
1581 (define_expand "reverse_blt"
1582   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1583                            (pc)
1584                            (label_ref (match_operand 0 "" ""))))]
1585   ""
1586   "
1587 {
1588   operands[1] = mcore_gen_compare_reg (LT);
1589 }")
1590
1591 (define_expand "blt"
1592   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1593                            (label_ref (match_operand 0 "" ""))
1594                            (pc)))]
1595   ""
1596   "
1597 {
1598   operands[1] = mcore_gen_compare_reg (LT);
1599 }")
1600
1601 ; There is no bge compare, so we reverse the branch arms.
1602
1603 (define_expand "bge"
1604   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1605                            (pc)
1606                            (label_ref (match_operand 0 "" ""))))]
1607   ""
1608   "
1609 {
1610   operands[1] = mcore_gen_compare_reg (GE);
1611 }")
1612
1613 ; There is no gtu compare, so we reverse the branch arms
1614
1615 ;(define_expand "bgtu"
1616 ;  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1617 ;                          (pc)
1618 ;                          (label_ref (match_operand 0 "" ""))))]
1619 ;  ""
1620 ;  "
1621 ;{
1622 ;  if (GET_CODE (arch_compare_op1) == CONST_INT
1623 ;      && INTVAL (arch_compare_op1) == 0)
1624 ;    operands[1] = mcore_gen_compare_reg (NE);
1625 ;  else 
1626 ;    { if (mcore_modify_comparison (GTU))
1627 ;       {
1628 ;         emit_jump_insn (gen_bgeu (operands[0]));
1629 ;         DONE;
1630 ;       }
1631 ;      operands[1] = mcore_gen_compare_reg (LEU);
1632 ;    }
1633 ;}")
1634
1635 (define_expand "bgtu"
1636   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1637                            (pc)
1638                            (label_ref (match_operand 0 "" ""))))]
1639   ""
1640   "
1641 {
1642   if (GET_CODE (arch_compare_op1) == CONST_INT
1643       && INTVAL (arch_compare_op1) == 0)
1644     {
1645       /* The inverse of '> 0' for an unsigned test is
1646          '== 0' but we do not have such an instruction available.
1647          Instead we must reverse the branch (back to the normal
1648          ordering) and test '!= 0'.  */
1649          
1650       operands[1] = mcore_gen_compare_reg (NE);
1651       
1652       emit_jump_insn (gen_rtx_SET (VOIDmode,
1653         pc_rtx,
1654         gen_rtx_IF_THEN_ELSE (VOIDmode,
1655         gen_rtx_NE (VOIDmode,
1656         operands[1],
1657         const0_rtx),
1658         gen_rtx_LABEL_REF (VOIDmode,operands[0]),
1659         pc_rtx)));
1660       DONE;           
1661     }
1662   operands[1] = mcore_gen_compare_reg (GTU);
1663 }")
1664
1665
1666 (define_expand "bleu"
1667   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1668                            (label_ref (match_operand 0 "" ""))
1669                            (pc)))]
1670   ""
1671   "
1672 {
1673   operands[1] = mcore_gen_compare_reg (LEU);
1674 }")
1675
1676 ; There is no bltu compare, so we reverse the branch arms
1677 (define_expand "bltu"
1678   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1679                            (pc)
1680                            (label_ref (match_operand 0 "" ""))))]
1681   ""
1682   "
1683 {
1684   operands[1] = mcore_gen_compare_reg (LTU);
1685 }")
1686
1687 (define_expand "bgeu"
1688   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1689                            (label_ref (match_operand 0 "" ""))
1690                            (pc)))]
1691   ""
1692   "
1693 {
1694
1695   operands[1] = mcore_gen_compare_reg (GEU);
1696 }")
1697
1698 ;; ------------------------------------------------------------------------
1699 ;; Jump and linkage insns
1700 ;; ------------------------------------------------------------------------
1701
1702 (define_insn "jump_real"
1703   [(set (pc)
1704         (label_ref (match_operand 0 "" "")))]
1705   ""
1706   "jbr  %l0"
1707   [(set_attr "type" "branch")])
1708
1709 (define_expand "jump"
1710  [(set (pc) (label_ref (match_operand 0 "" "")))]
1711  ""
1712  "
1713 {
1714   emit_jump_insn (gen_jump_real (operand0));
1715   DONE;
1716 }
1717 ")
1718
1719 (define_insn "indirect_jump"
1720   [(set (pc)
1721         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))]
1722   ""
1723   "jmp  %0"
1724   [(set_attr "type" "jmp")])
1725
1726 (define_expand "call"
1727   [(parallel[(call (match_operand:SI 0 "" "")
1728                    (match_operand 1 "" ""))
1729              (clobber (reg:SI 15))])]
1730   ""
1731   "
1732 {
1733   if (GET_CODE (operands[0]) == MEM
1734       && ! register_operand (XEXP (operands[0], 0), SImode)
1735       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1736     operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1737                            force_reg (Pmode, XEXP (operands[0], 0)));
1738 }")
1739
1740 (define_insn "call_internal"
1741   [(call (mem:SI (match_operand:SI 0 "mcore_call_address_operand" "riR"))
1742          (match_operand 1 "" ""))
1743    (clobber (reg:SI 15))]
1744   ""
1745   "* return mcore_output_call (operands, 0);")
1746
1747 (define_expand "call_value"
1748   [(parallel[(set (match_operand 0 "register_operand" "")
1749                   (call (match_operand:SI 1 "" "")
1750                         (match_operand 2 "" "")))
1751              (clobber (reg:SI 15))])]
1752   ""
1753   "
1754 {
1755   if (GET_CODE (operands[0]) == MEM
1756       && ! register_operand (XEXP (operands[0], 0), SImode)
1757       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1758     operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
1759                            force_reg (Pmode, XEXP (operands[1], 0)));
1760 }")
1761
1762 (define_insn "call_value_internal"
1763   [(set (match_operand 0 "register_operand" "=r")
1764         (call (mem:SI (match_operand:SI 1 "mcore_call_address_operand" "riR"))
1765               (match_operand 2 "" "")))
1766    (clobber (reg:SI 15))]
1767   ""
1768   "* return mcore_output_call (operands, 1);")
1769
1770 (define_insn "call_value_struct"
1771   [(parallel [(set (match_parallel 0 ""
1772                      [(expr_list (match_operand 3 "register_operand" "") (match_operand 4 "immediate_operand" ""))
1773                       (expr_list (match_operand 5 "register_operand" "") (match_operand 6 "immediate_operand" ""))])
1774                   (call (match_operand:SI 1 "" "")
1775                         (match_operand 2 "" "")))
1776              (clobber (reg:SI 15))])]
1777   ""
1778   "* return mcore_output_call (operands, 1);"
1779 )
1780
1781
1782 ;; ------------------------------------------------------------------------
1783 ;; Misc insns
1784 ;; ------------------------------------------------------------------------
1785
1786 (define_insn "nop"
1787   [(const_int 0)]
1788   ""
1789   "or   r0,r0")
1790
1791 (define_insn "tablejump"
1792   [(set (pc)
1793         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1794    (use (label_ref (match_operand 1 "" "")))]
1795   ""
1796   "jmp  %0"
1797   [(set_attr "type" "jmp")])
1798
1799 (define_insn "*return"
1800  [(return)]
1801  "reload_completed && ! mcore_naked_function_p ()"
1802  "jmp   r15"
1803  [(set_attr "type" "jmp")])
1804
1805 (define_insn "*no_return"
1806  [(return)]
1807  "reload_completed && mcore_naked_function_p ()"
1808  ""
1809  [(set_attr "length" "0")]
1810 )
1811
1812 (define_expand "prologue"
1813   [(const_int 0)]
1814   ""
1815   "mcore_expand_prolog (); DONE;")
1816
1817 (define_expand "epilogue"
1818   [(return)]
1819   ""
1820   "mcore_expand_epilog ();")
1821
1822 ;; ------------------------------------------------------------------------
1823 ;; Scc instructions
1824 ;; ------------------------------------------------------------------------
1825
1826 (define_insn "mvc"
1827   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1828         (ne:SI (reg:CC 17) (const_int 0)))]
1829   ""
1830   "mvc  %0"
1831   [(set_attr "type" "move")])
1832
1833 (define_insn "mvcv"
1834   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1835         (eq:SI (reg:CC 17) (const_int 0)))]
1836   ""
1837   "mvcv %0"
1838   [(set_attr "type" "move")])
1839
1840 ; in 0.97 use (LE 0) with (LT 1) and complement c.  BRC
1841 (define_split 
1842   [(parallel[
1843      (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1844           (ne:SI (gt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1845                         (const_int 0))
1846                  (const_int 0)))
1847      (clobber (reg:SI 17))])]
1848   ""
1849   [(set (reg:CC 17)
1850         (lt:CC (match_dup 1) (const_int 1)))
1851    (set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
1852      
1853
1854 (define_expand "seq"
1855   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1856         (eq:SI (match_dup 1) (const_int 0)))]
1857   ""
1858   "
1859 {
1860   operands[1] = mcore_gen_compare_reg (NE);
1861 }")
1862
1863 (define_expand "sne"
1864   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1865         (ne:SI (match_dup 1) (const_int 0)))]
1866   ""
1867   "
1868 {
1869   operands[1] = mcore_gen_compare_reg (NE);
1870 }")
1871
1872 (define_expand "slt"
1873   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1874         (ne:SI (match_dup 1) (const_int 0)))]
1875   ""
1876   "
1877 {
1878   operands[1] = mcore_gen_compare_reg (LT);
1879 }")
1880
1881 ; make generating a LT with the comparison reversed easy.  BRC
1882 (define_expand "reverse_slt"
1883   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1884         (eq:SI (match_dup 1) (const_int 0)))]
1885   ""
1886   "
1887 {
1888   operands[1] = mcore_gen_compare_reg (LT);
1889 }")
1890
1891 (define_expand "sge"
1892   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1893         (eq:SI (match_dup 1) (const_int 0)))]
1894   ""
1895   "
1896 {
1897   operands[1] = mcore_gen_compare_reg (LT);
1898 }")
1899
1900 ; check whether (GT A imm) can become (LE A imm) with the comparison
1901 ; reversed.  if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
1902
1903 (define_expand "sgt"
1904   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1905         (ne:SI (match_dup 1) (const_int 0)))]
1906   ""
1907   "
1908 {
1909   if (mcore_modify_comparison (LE))
1910     {
1911       emit_insn (gen_reverse_slt (operands[0]));
1912       DONE;
1913     }
1914   
1915   operands[1] = mcore_gen_compare_reg (GT);
1916 }")
1917
1918 (define_expand "sle"
1919   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1920         (eq:SI (match_dup 1) (const_int 0)))]
1921   ""
1922   "
1923 {
1924   if (mcore_modify_comparison (LE))
1925     {
1926       emit_insn (gen_slt (operands[0]));
1927       DONE;
1928     }
1929   operands[1] = mcore_gen_compare_reg (GT);
1930 }")
1931
1932 (define_expand "sltu"
1933   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1934         (eq:SI (match_dup 1) (const_int 0)))]
1935   ""
1936   "
1937 {
1938   operands[1] = mcore_gen_compare_reg (GEU);
1939 }")
1940
1941 (define_expand "sgeu"
1942   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1943         (ne:SI (match_dup 1) (const_int 0)))]
1944   ""
1945   "
1946 {
1947   operands[1] = mcore_gen_compare_reg (GEU);
1948 }")
1949
1950 (define_expand "sgtu"
1951   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1952         (eq:SI (match_dup 1) (const_int 0)))]
1953   ""
1954   "
1955 {
1956   operands[1] = mcore_gen_compare_reg (LEU);
1957 }")
1958
1959 (define_expand "sleu"
1960   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1961         (ne:SI (match_dup 1) (const_int 0)))]
1962   ""
1963   "
1964 {
1965   operands[1] = mcore_gen_compare_reg (LEU);
1966 }")
1967
1968 (define_insn "incscc"
1969   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1970         (plus:SI (ne (reg:CC 17) (const_int 0))
1971                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1972   ""
1973   "inct %0")
1974
1975 (define_insn "incscc_false"
1976   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1977         (plus:SI (eq (reg:CC 17) (const_int 0))
1978                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1979   ""
1980   "incf %0")
1981
1982 (define_insn "decscc"
1983   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1984         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1985                   (ne (reg:CC 17) (const_int 0))))]
1986   ""
1987   "dect %0")
1988
1989 (define_insn "decscc_false"
1990   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1991         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1992                   (eq (reg:CC 17) (const_int 0))))]
1993   ""
1994   "decf %0")
1995
1996 ;; ------------------------------------------------------------------------
1997 ;; Conditional move patterns.
1998 ;; ------------------------------------------------------------------------
1999
2000 (define_expand "smaxsi3"
2001   [(set (reg:CC 17)
2002         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2003                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2004    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2005         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2006                          (match_dup 1) (match_dup 2)))]
2007   ""
2008   "")
2009                
2010 (define_split
2011   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2012         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2013                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2014   ""
2015   [(set (reg:CC 17)
2016         (lt:SI (match_dup 1) (match_dup 2)))
2017    (set (match_dup 0)
2018         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2019                          (match_dup 1) (match_dup 2)))]
2020   "")
2021
2022 ; no tstgt in 0.97, so just use cmplti (btsti x,31) and reverse move 
2023 ; condition  BRC
2024 (define_split
2025   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2026         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2027                  (const_int 0)))]
2028   ""
2029   [(set (reg:CC 17)
2030         (lt:CC (match_dup 1) (const_int 0)))
2031    (set (match_dup 0)
2032         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2033                          (match_dup 1) (const_int 0)))]
2034   "")
2035
2036 (define_expand "sminsi3"
2037   [(set (reg:CC 17)
2038         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2039                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2040    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2041         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2042                          (match_dup 1) (match_dup 2)))]
2043   ""
2044   "")
2045
2046 (define_split
2047   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2048         (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2049                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2050   ""
2051   [(set (reg:CC 17)
2052         (lt:SI (match_dup 1) (match_dup 2)))
2053    (set (match_dup 0)
2054         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2055                          (match_dup 1) (match_dup 2)))]
2056   "")
2057
2058 ;(define_split
2059 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2060 ;        (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2061 ;                 (const_int 0)))]
2062 ;  ""
2063 ;  [(set (reg:CC 17)
2064 ;        (gt:CC (match_dup 1) (const_int 0)))
2065 ;   (set (match_dup 0)
2066 ;        (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2067 ;                         (match_dup 1) (const_int 0)))]
2068 ;  "")
2069
2070 ; changed these unsigned patterns to use geu instead of ltu.  it appears
2071 ; that the c-torture & ssrl test suites didn't catch these!  only showed
2072 ; up in friedman's clib work.   BRC 7/7/95
2073
2074 (define_expand "umaxsi3"
2075   [(set (reg:CC 17)
2076         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2077                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2078    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2079         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2080                          (match_dup 2) (match_dup 1)))]
2081   ""
2082   "")
2083                
2084 (define_split
2085   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2086         (umax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2087                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2088   ""
2089   [(set (reg:CC 17)
2090         (geu:SI (match_dup 1) (match_dup 2)))
2091    (set (match_dup 0)
2092         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2093                          (match_dup 2) (match_dup 1)))]
2094   "")
2095
2096 (define_expand "uminsi3"
2097   [(set (reg:CC 17)
2098         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2099                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2100    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2101         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2102                          (match_dup 2) (match_dup 1)))]
2103   ""
2104   "")
2105
2106 (define_split
2107   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2108         (umin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2109                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2110   ""
2111   [(set (reg:CC 17)
2112         (geu:SI (match_dup 1) (match_dup 2)))
2113    (set (match_dup 0)
2114         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2115                          (match_dup 2) (match_dup 1)))]
2116   "")
2117
2118 ;; ------------------------------------------------------------------------
2119 ;; conditional move patterns really start here
2120 ;; ------------------------------------------------------------------------
2121
2122 ;; the "movtK" patterns are experimental.  they are intended to account for
2123 ;; gcc's mucking on code such as:
2124 ;;
2125 ;;            free_ent = ((block_compress) ? 257 : 256 );
2126 ;;
2127 ;; these patterns help to get a tstne/bgeni/inct (or equivalent) sequence
2128 ;; when both arms have constants that are +/- 1 of each other.
2129 ;;
2130 ;; note in the following patterns that the "movtK" ones should be the first
2131 ;; one defined in each sequence.  this is because the general pattern also
2132 ;; matches, so use ordering to determine priority (it's easier this way than
2133 ;; adding conditions to the general patterns).   BRC
2134 ;;
2135 ;; the U and Q constraints are necessary to ensure that reload does the
2136 ;; 'right thing'.  U constrains the operand to 0 and Q to 1 for use in the
2137 ;; clrt & clrf and clrt/inct & clrf/incf patterns.    BRC 6/26
2138 ;;
2139 ;; ??? there appears to be some problems with these movtK patterns for ops
2140 ;; other than eq & ne.  need to fix.  6/30 BRC
2141
2142 ;; ------------------------------------------------------------------------
2143 ;; ne 
2144 ;; ------------------------------------------------------------------------
2145
2146 ; experimental conditional move with two constants +/- 1  BRC
2147
2148 (define_insn "movtK_1"
2149   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2150         (if_then_else:SI
2151             (ne (reg:CC 17) (const_int 0))
2152           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2153           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2154   "  GET_CODE (operands[1]) == CONST_INT
2155   && GET_CODE (operands[2]) == CONST_INT
2156   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
2157       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2158   "* return mcore_output_cmov (operands, 1, NULL);"
2159   [(set_attr "length" "4")])
2160
2161 (define_insn "movt0"
2162   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2163         (if_then_else:SI
2164          (ne (reg:CC 17) (const_int 0))
2165          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2166          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2167   ""
2168   "@
2169     movt        %0,%1
2170     movf        %0,%2
2171     clrt        %0
2172     clrf        %0")
2173
2174 ;; ------------------------------------------------------------------------
2175 ;; eq
2176 ;; ------------------------------------------------------------------------
2177
2178 ; experimental conditional move with two constants +/- 1  BRC
2179 (define_insn "movtK_2"
2180   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2181         (if_then_else:SI
2182             (eq (reg:CC 17) (const_int 0))
2183           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2184           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2185   "  GET_CODE (operands[1]) == CONST_INT
2186   && GET_CODE (operands[2]) == CONST_INT
2187   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
2188       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2189   "* return mcore_output_cmov (operands, 0, NULL);"
2190   [(set_attr "length" "4")])
2191
2192 (define_insn "movf0"
2193   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2194         (if_then_else:SI
2195          (eq (reg:CC 17) (const_int 0))
2196          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2197          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2198   ""
2199   "@
2200     movf        %0,%1
2201     movt        %0,%2
2202     clrf        %0
2203     clrt        %0")
2204
2205 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
2206 ; because the instructions are not adjacent (peepholes are related by posn -
2207 ; not by dataflow).   BRC
2208
2209 (define_insn ""
2210   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2211         (if_then_else:SI (eq (zero_extract:SI 
2212                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2213                               (const_int 1)
2214                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
2215                              (const_int 0))
2216                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
2217                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
2218   ""
2219   "@
2220     btsti       %1,%2\;movf     %0,%3
2221     btsti       %1,%2\;movt     %0,%4
2222     btsti       %1,%2\;clrf     %0
2223     btsti       %1,%2\;clrt     %0"
2224   [(set_attr "length" "4")])
2225
2226 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
2227
2228 (define_insn ""
2229   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2230         (if_then_else:SI (eq (lshiftrt:SI 
2231                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2232                               (const_int 7))
2233                              (const_int 0))
2234                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2235                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2236   "GET_CODE (operands[1]) == SUBREG && 
2237       GET_MODE (SUBREG_REG (operands[1])) == QImode"
2238   "@
2239     btsti       %1,7\;movf      %0,%2
2240     btsti       %1,7\;movt      %0,%3
2241     btsti       %1,7\;clrf      %0
2242     btsti       %1,7\;clrt      %0"
2243   [(set_attr "length" "4")])
2244
2245
2246 ;; ------------------------------------------------------------------------
2247 ;; ne
2248 ;; ------------------------------------------------------------------------
2249
2250 ;; Combine creates this from an andn instruction in a scc sequence.
2251 ;; We must recognize it to get conditional moves generated.
2252
2253 ; experimental conditional move with two constants +/- 1  BRC
2254 (define_insn "movtK_3"
2255   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2256         (if_then_else:SI
2257             (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2258                 (const_int 0))
2259           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2260           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2261   "  GET_CODE (operands[2]) == CONST_INT
2262   && GET_CODE (operands[3]) == CONST_INT
2263   && (   (INTVAL (operands[2]) - INTVAL (operands[3]) == 1)
2264       || (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2265   "*
2266 {
2267   rtx out_operands[4];
2268   out_operands[0] = operands[0];
2269   out_operands[1] = operands[2];
2270   out_operands[2] = operands[3];
2271   out_operands[3] = operands[1];
2272
2273   return mcore_output_cmov (out_operands, 1, \"cmpnei   %3,0\");
2274
2275 }"
2276   [(set_attr "length" "6")])
2277
2278 (define_insn "movt2"
2279   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2280         (if_then_else:SI (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2281                              (const_int 0))
2282                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2283                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2284   ""      
2285   "@
2286     cmpnei      %1,0\;movt      %0,%2
2287     cmpnei      %1,0\;movf      %0,%3
2288     cmpnei      %1,0\;clrt      %0
2289     cmpnei      %1,0\;clrf      %0"
2290   [(set_attr "length" "4")])
2291
2292 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
2293 ; because the instructions are not adjacent (peepholes are related by posn -
2294 ; not by dataflow).   BRC
2295
2296 (define_insn ""
2297  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2298         (if_then_else:SI (ne (zero_extract:SI 
2299                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2300                               (const_int 1)
2301                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
2302                              (const_int 0))
2303                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
2304                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
2305   ""
2306   "@
2307     btsti       %1,%2\;movt     %0,%3
2308     btsti       %1,%2\;movf     %0,%4
2309     btsti       %1,%2\;clrt     %0
2310     btsti       %1,%2\;clrf     %0"
2311   [(set_attr "length" "4")])
2312
2313 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
2314
2315 (define_insn ""
2316   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2317         (if_then_else:SI (ne (lshiftrt:SI 
2318                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2319                               (const_int 7))
2320                              (const_int 0))
2321                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2322                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2323   "GET_CODE (operands[1]) == SUBREG && 
2324       GET_MODE (SUBREG_REG (operands[1])) == QImode"
2325   "@
2326     btsti       %1,7\;movt      %0,%2
2327     btsti       %1,7\;movf      %0,%3
2328     btsti       %1,7\;clrt      %0
2329     btsti       %1,7\;clrf      %0"
2330   [(set_attr "length" "4")])
2331
2332 ;; ------------------------------------------------------------------------
2333 ;; eq/eq
2334 ;; ------------------------------------------------------------------------
2335
2336 ; experimental conditional move with two constants +/- 1  BRC
2337 (define_insn "movtK_4"
2338   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2339         (if_then_else:SI
2340             (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2341           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2342           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2343   "GET_CODE (operands[1]) == CONST_INT &&
2344    GET_CODE (operands[2]) == CONST_INT &&
2345    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2346    (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2347   "* return mcore_output_cmov(operands, 1, NULL);"
2348   [(set_attr "length" "4")])
2349
2350 (define_insn "movt3"
2351   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2352         (if_then_else:SI
2353          (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2354          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2355          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2356   ""
2357   "@
2358     movt        %0,%1
2359     movf        %0,%2
2360     clrt        %0
2361     clrf        %0")
2362
2363 ;; ------------------------------------------------------------------------
2364 ;; eq/ne
2365 ;; ------------------------------------------------------------------------
2366
2367 ; experimental conditional move with two constants +/- 1  BRC
2368 (define_insn "movtK_5"
2369   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2370         (if_then_else:SI
2371             (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2372           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2373           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2374   "GET_CODE (operands[1]) == CONST_INT &&
2375    GET_CODE (operands[2]) == CONST_INT &&
2376    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2377     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2378   "* return mcore_output_cmov (operands, 0, NULL);"
2379   [(set_attr "length" "4")])
2380
2381 (define_insn "movf1"
2382   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2383         (if_then_else:SI
2384          (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2385          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2386          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2387   ""
2388   "@
2389     movf        %0,%1
2390     movt        %0,%2
2391     clrf        %0
2392     clrt        %0")
2393
2394 ;; ------------------------------------------------------------------------
2395 ;; eq
2396 ;; ------------------------------------------------------------------------
2397
2398 ;; Combine creates this from an andn instruction in a scc sequence.
2399 ;; We must recognize it to get conditional moves generated.
2400
2401 ; experimental conditional move with two constants +/- 1  BRC
2402
2403 (define_insn "movtK_6"
2404   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2405         (if_then_else:SI
2406             (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2407                 (const_int 0))
2408           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2409           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2410   "GET_CODE (operands[1]) == CONST_INT &&
2411    GET_CODE (operands[2]) == CONST_INT &&
2412    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2413     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2414   "* 
2415 {
2416    rtx out_operands[4];
2417    out_operands[0] = operands[0];
2418    out_operands[1] = operands[2];
2419    out_operands[2] = operands[3];
2420    out_operands[3] = operands[1];
2421
2422    return mcore_output_cmov (out_operands, 0, \"cmpnei  %3,0\");
2423 }"
2424   [(set_attr "length" "6")])
2425
2426 (define_insn "movf3"
2427   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2428         (if_then_else:SI (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2429                              (const_int 0))
2430                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2431                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2432   ""
2433   "@
2434     cmpnei      %1,0\;movf      %0,%2
2435     cmpnei      %1,0\;movt      %0,%3
2436     cmpnei      %1,0\;clrf      %0
2437     cmpnei      %1,0\;clrt      %0"
2438   [(set_attr "length" "4")])
2439
2440 ;; ------------------------------------------------------------------------
2441 ;; ne/eq
2442 ;; ------------------------------------------------------------------------
2443
2444 ; experimental conditional move with two constants +/- 1  BRC
2445 (define_insn "movtK_7"
2446   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2447         (if_then_else:SI
2448             (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2449           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2450           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2451   "GET_CODE (operands[1]) == CONST_INT &&
2452    GET_CODE (operands[2]) == CONST_INT &&
2453    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2454     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2455   "* return mcore_output_cmov (operands, 0, NULL);"
2456   [(set_attr "length" "4")])
2457
2458 (define_insn "movf4"
2459   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2460         (if_then_else:SI
2461          (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2462          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2463          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2464   ""
2465   "@
2466     movf        %0,%1
2467     movt        %0,%2
2468     clrf        %0
2469     clrt        %0")
2470
2471 ;; ------------------------------------------------------------------------
2472 ;; ne/ne
2473 ;; ------------------------------------------------------------------------
2474
2475 ; experimental conditional move with two constants +/- 1  BRC
2476 (define_insn "movtK_8"
2477   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2478         (if_then_else:SI
2479             (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2480           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2481           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2482   "GET_CODE (operands[1]) == CONST_INT &&
2483    GET_CODE (operands[2]) == CONST_INT &&
2484    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2485     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2486   "* return mcore_output_cmov (operands, 1, NULL);"
2487   [(set_attr "length" "4")])
2488
2489 (define_insn "movt4"
2490   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2491         (if_then_else:SI
2492          (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2493          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2494          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2495   ""
2496   "@
2497     movt        %0,%1
2498     movf        %0,%2
2499     clrt        %0
2500     clrf        %0")
2501
2502 ;; Also need patterns to recognize lt/ge, since otherwise the compiler will
2503 ;; try to output not/asri/tstne/movf.
2504
2505 ;; ------------------------------------------------------------------------
2506 ;; lt
2507 ;; ------------------------------------------------------------------------
2508
2509 ; experimental conditional move with two constants +/- 1  BRC
2510 (define_insn "movtK_9"
2511   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2512         (if_then_else:SI
2513             (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2514                 (const_int 0))
2515           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2516           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2517   "GET_CODE (operands[2]) == CONST_INT &&
2518    GET_CODE (operands[3]) == CONST_INT &&
2519    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2520     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2521   "*
2522 {
2523    rtx out_operands[4];
2524    out_operands[0] = operands[0];
2525    out_operands[1] = operands[2];
2526    out_operands[2] = operands[3];
2527    out_operands[3] = operands[1];
2528
2529    return mcore_output_cmov (out_operands, 1, \"btsti   %3,31\");
2530 }"
2531   [(set_attr "length" "6")])
2532
2533 (define_insn "movt5"
2534   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2535         (if_then_else:SI (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2536                              (const_int 0))
2537                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2538                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2539   ""
2540   "@
2541     btsti       %1,31\;movt     %0,%2
2542     btsti       %1,31\;movf     %0,%3
2543     btsti       %1,31\;clrt     %0
2544     btsti       %1,31\;clrf     %0"
2545   [(set_attr "length" "4")])
2546
2547
2548 ;; ------------------------------------------------------------------------
2549 ;; ge
2550 ;; ------------------------------------------------------------------------
2551
2552 ; experimental conditional move with two constants +/- 1  BRC
2553 (define_insn "movtK_10"
2554   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2555         (if_then_else:SI
2556             (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2557                 (const_int 0))
2558           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2559           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2560   "GET_CODE (operands[2]) == CONST_INT &&
2561    GET_CODE (operands[3]) == CONST_INT &&
2562    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2563     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2564   "*
2565 {
2566   rtx out_operands[4];
2567   out_operands[0] = operands[0];
2568   out_operands[1] = operands[2];
2569   out_operands[2] = operands[3];
2570   out_operands[3] = operands[1];
2571
2572    return mcore_output_cmov (out_operands, 0, \"btsti   %3,31\");
2573 }"
2574   [(set_attr "length" "6")])
2575
2576 (define_insn "movf5"
2577   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2578         (if_then_else:SI (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2579                              (const_int 0))
2580                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2581                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2582   ""
2583   "@
2584     btsti       %1,31\;movf     %0,%2
2585     btsti       %1,31\;movt     %0,%3
2586     btsti       %1,31\;clrf     %0
2587     btsti       %1,31\;clrt     %0"
2588   [(set_attr "length" "4")])
2589
2590 ;; ------------------------------------------------------------------------
2591 ;; Bitfield extract (xtrbN)
2592 ;; ------------------------------------------------------------------------
2593
2594 ; sometimes we're better off using QI/HI mode and letting the machine indep.
2595 ; part expand insv and extv.
2596 ;
2597 ; e.g., sequences like:a        [an insertion]
2598 ;
2599 ;      ldw r8,(r6)
2600 ;      movi r7,0x00ffffff
2601 ;      and r8,r7                 r7 dead
2602 ;      stw r8,(r6)                r8 dead
2603 ;
2604 ; become:
2605 ;
2606 ;      movi r8,0
2607 ;      stb r8,(r6)              r8 dead
2608 ;
2609 ; it looks like always using SI mode is a win except in this type of code 
2610 ; (when adjacent bit fields collapse on a byte or halfword boundary).  when
2611 ; expanding with SI mode, non-adjacent bit field masks fold, but with QI/HI
2612 ; mode, they do not.  one thought is to add some peepholes to cover cases
2613 ; like the above, but this is not a general solution.
2614 ;
2615 ; -mword-bitfields expands/inserts using SI mode.  otherwise, do it with
2616 ; the smallest mode possible (using the machine indep. expansions).  BRC
2617
2618 ;(define_expand "extv"
2619 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2620 ;       (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2621 ;                        (match_operand:SI 2 "const_int_operand" "")
2622 ;                        (match_operand:SI 3 "const_int_operand" "")))
2623 ;   (clobber (reg:CC 17))]
2624 ;  ""
2625 ;  "
2626 ;{
2627 ;  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) % 8 != 0)
2628 ;    {
2629 ;     if (TARGET_W_FIELD)
2630 ;       {
2631 ;        rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2632 ;        rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2633 ;
2634 ;        emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2635 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2636 ;                            gen_rtx_ASHIFT (SImode, operands[0], lshft)));
2637 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2638 ;                            gen_rtx_ASHIFTRT (SImode, operands[0], rshft)));
2639 ;        DONE;
2640 ;     }
2641 ;     else
2642 ;        FAIL;
2643 ;  }
2644 ;}")
2645
2646 (define_expand "extv"
2647   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2648         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2649                          (match_operand:SI 2 "const_int_operand" "")
2650                          (match_operand:SI 3 "const_int_operand" "")))
2651    (clobber (reg:CC 17))]
2652   ""
2653   "
2654 {
2655   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2656     {
2657        /* 8 bit field, aligned properly, use the xtrb[0123]+sext sequence.  */
2658        /* not DONE, not FAIL, but let the RTL get generated....  */
2659     }
2660   else if (TARGET_W_FIELD)
2661     {
2662       /* Arbitrary placement; note that the tree->rtl generator will make
2663          something close to this if we return FAIL  */
2664       rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2665       rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2666       rtx tmp1 = gen_reg_rtx (SImode);
2667       rtx tmp2 = gen_reg_rtx (SImode);
2668
2669       emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2670       emit_insn (gen_rtx_SET (SImode, tmp2,
2671                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2672       emit_insn (gen_rtx_SET (SImode, operands[0],
2673                          gen_rtx_ASHIFTRT (SImode, tmp2, rshft)));
2674       DONE;
2675     }
2676   else
2677     {
2678       /* Let the caller choose an alternate sequence.  */
2679       FAIL;
2680     }
2681 }")
2682
2683 (define_expand "extzv"
2684   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2685         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2686                          (match_operand:SI 2 "const_int_operand" "")
2687                          (match_operand:SI 3 "const_int_operand" "")))
2688    (clobber (reg:CC 17))]
2689   ""
2690   "
2691 {
2692   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2693     {
2694        /* 8 bit field, aligned properly, use the xtrb[0123] sequence.  */
2695        /* Let the template generate some RTL....  */
2696     }
2697   else if (CONST_OK_FOR_K ((1 << INTVAL (operands[2])) - 1))
2698     {
2699       /* A narrow bit-field (<=5 bits) means we can do a shift to put
2700          it in place and then use an andi to extract it.
2701          This is as good as a shiftleft/shiftright.  */
2702
2703       rtx shifted;
2704       rtx mask = GEN_INT ((1 << INTVAL (operands[2])) - 1);
2705
2706       if (INTVAL (operands[3]) == 0)
2707         {
2708           shifted = operands[1];
2709         }
2710       else
2711         {
2712           rtx rshft = GEN_INT (INTVAL (operands[3]));
2713           shifted = gen_reg_rtx (SImode);
2714           emit_insn (gen_rtx_SET (SImode, shifted,
2715                          gen_rtx_LSHIFTRT (SImode, operands[1], rshft)));
2716         }
2717      emit_insn (gen_rtx_SET (SImode, operands[0],
2718                        gen_rtx_AND (SImode, shifted, mask)));
2719      DONE;
2720    }
2721  else if (TARGET_W_FIELD)
2722    {
2723      /* Arbitrary pattern; play shift/shift games to get it. 
2724       * this is pretty much what the caller will do if we say FAIL */
2725      rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2726      rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2727      rtx tmp1 = gen_reg_rtx (SImode);
2728      rtx tmp2 = gen_reg_rtx (SImode);
2729
2730      emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2731      emit_insn (gen_rtx_SET (SImode, tmp2,
2732                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2733      emit_insn (gen_rtx_SET (SImode, operands[0],
2734                        gen_rtx_LSHIFTRT (SImode, tmp2, rshft)));
2735      DONE;
2736    }
2737  else
2738    {
2739      /* Make the compiler figure out some alternative mechanism.  */
2740      FAIL;
2741    }
2742
2743  /* Emit the RTL pattern; something will match it later.  */
2744 }")
2745
2746 (define_expand "insv"
2747   [(set (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "")
2748                          (match_operand:SI 1 "const_int_operand" "")
2749                          (match_operand:SI 2 "const_int_operand" ""))
2750         (match_operand:SI 3 "general_operand" ""))
2751    (clobber (reg:CC 17))]
2752   ""
2753   "
2754 {
2755   if (mcore_expand_insv (operands))
2756     {
2757       DONE;
2758     }
2759   else
2760     {
2761       FAIL;
2762     }
2763 }")
2764
2765 ;;
2766 ;; the xtrb[0123] instructions handily get at 8-bit fields on nice boundaries.
2767 ;; but then, they do force you through r1.
2768 ;;
2769 ;; the combiner will build such patterns for us, so we'll make them available
2770 ;; for its use.
2771 ;;
2772 ;; Note that we have both SIGNED and UNSIGNED versions of these...
2773 ;;
2774
2775 ;;
2776 ;; These no longer worry about the clobbering of CC bit; not sure this is
2777 ;; good...
2778 ;;
2779 ;; the SIGNED versions of these
2780 ;;
2781 (define_insn ""
2782   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2783         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2784   ""
2785   "@
2786         asri    %0,24
2787         xtrb0   %0,%1\;sextb    %0"
2788   [(set_attr "type" "shift")])
2789
2790 (define_insn ""
2791   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2792         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2793   ""
2794   "xtrb1        %0,%1\;sextb    %0"
2795   [(set_attr "type" "shift")])
2796
2797 (define_insn ""
2798   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2799         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2800   ""
2801   "xtrb2        %0,%1\;sextb    %0"
2802   [(set_attr "type" "shift")])
2803
2804 (define_insn ""
2805   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2806         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0") (const_int 8) (const_int 0)))]
2807   ""
2808   "sextb        %0"
2809   [(set_attr "type" "shift")])
2810
2811 ;; the UNSIGNED uses of xtrb[0123]
2812 ;;
2813 (define_insn ""
2814   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2815         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2816   ""
2817   "@
2818         lsri    %0,24
2819         xtrb0   %0,%1"
2820   [(set_attr "type" "shift")])
2821
2822 (define_insn ""
2823   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2824         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2825   ""
2826   "xtrb1        %0,%1"
2827   [(set_attr "type" "shift")])
2828
2829 (define_insn ""
2830   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2831         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2832   ""
2833   "xtrb2        %0,%1"
2834   [(set_attr "type" "shift")])
2835
2836 ;; This can be peepholed if it follows a ldb ...
2837 (define_insn ""
2838   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2839         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 0)))]
2840   ""
2841   "@
2842         zextb   %0
2843         xtrb3   %0,%1\;zextb    %0"
2844   [(set_attr "type" "shift")])
2845
2846
2847 ;; ------------------------------------------------------------------------
2848 ;; Block move - adapted from m88k.md
2849 ;; ------------------------------------------------------------------------
2850
2851 (define_expand "movmemsi"
2852   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2853                    (mem:BLK (match_operand:BLK 1 "" "")))
2854               (use (match_operand:SI 2 "general_operand" ""))
2855               (use (match_operand:SI 3 "immediate_operand" ""))])]
2856   ""
2857   "
2858 {
2859   if (mcore_expand_block_move (operands))
2860     DONE;
2861   else
2862     FAIL;
2863 }")
2864
2865 ;; ;;; ??? These patterns are meant to be generated from expand_block_move,
2866 ;; ;;; but they currently are not.
2867 ;; 
2868 ;; (define_insn ""
2869 ;;   [(set (match_operand:QI 0 "mcore_arith_reg_operand" "=r")
2870 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2871 ;;   ""
2872 ;;   "ld.b      %0,%1"
2873 ;;   [(set_attr "type" "load")])
2874 ;; 
2875 ;; (define_insn ""
2876 ;;   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
2877 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2878 ;;   ""
2879 ;;   "ld.h      %0,%1"
2880 ;;   [(set_attr "type" "load")])
2881 ;; 
2882 ;; (define_insn ""
2883 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2884 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2885 ;;   ""
2886 ;;   "ld.w      %0,%1"
2887 ;;   [(set_attr "type" "load")])
2888 ;; 
2889 ;; (define_insn ""
2890 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2891 ;;      (match_operand:QI 1 "mcore_arith_reg_operand" "r"))]
2892 ;;   ""
2893 ;;   "st.b      %1,%0"
2894 ;;   [(set_attr "type" "store")])
2895 ;; 
2896 ;; (define_insn ""
2897 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2898 ;;      (match_operand:HI 1 "mcore_arith_reg_operand" "r"))]
2899 ;;   ""
2900 ;;   "st.h      %1,%0"
2901 ;;   [(set_attr "type" "store")])
2902 ;; 
2903 ;; (define_insn ""
2904 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2905 ;;      (match_operand:SI 1 "mcore_arith_reg_operand" "r"))]
2906 ;;   ""
2907 ;;   "st.w      %1,%0"
2908 ;;   [(set_attr "type" "store")])
2909 \f
2910 ;; ------------------------------------------------------------------------
2911 ;; Misc Optimizing quirks
2912 ;; ------------------------------------------------------------------------
2913
2914 ;; pair to catch constructs like:  (int *)((p+=4)-4) which happen
2915 ;; in stdarg/varargs traversal. This changes a 3 insn sequence to a 2
2916 ;; insn sequence. -- RBE 11/30/95
2917 (define_insn ""
2918   [(parallel[
2919       (set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2920            (match_operand:SI 1 "mcore_arith_reg_operand" "+r"))
2921       (set (match_dup 1) (plus:SI (match_dup 1) (match_operand 2 "mcore_arith_any_imm_operand" "")))])]
2922   "GET_CODE(operands[2]) == CONST_INT"
2923   "#"
2924   [(set_attr "length" "4")])
2925
2926 (define_split 
2927   [(parallel[
2928       (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2929            (match_operand:SI 1 "mcore_arith_reg_operand" ""))
2930       (set (match_dup 1) (plus:SI (match_dup 1) (match_operand 2 "mcore_arith_any_imm_operand" "")))])]
2931   "GET_CODE(operands[2]) == CONST_INT &&
2932    operands[0] != operands[1]"
2933   [(set (match_dup 0) (match_dup 1))
2934    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))])
2935
2936 \f
2937 ;;; Peepholes
2938
2939 ; note: in the following patterns, use mcore_is_dead() to ensure that the
2940 ; reg we may be trashing really is dead.  reload doesn't always mark
2941 ; deaths, so mcore_is_dead() (see mcore.c) scans forward to find its death.  BRC
2942
2943 ;;; A peephole to convert the 3 instruction sequence generated by reload
2944 ;;; to load a FP-offset address into a 2 instruction sequence.
2945 ;;; ??? This probably never matches anymore.
2946 (define_peephole
2947   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2948         (match_operand:SI 1 "const_int_operand" "J"))
2949    (set (match_dup 0) (neg:SI (match_dup 0)))
2950    (set (match_dup 0)
2951         (plus:SI (match_dup 0)
2952                  (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
2953   "CONST_OK_FOR_J (INTVAL (operands[1]))"
2954   "error\;mov   %0,%2\;subi     %0,%1")
2955
2956 ;; Moves of inlinable constants are done late, so when a 'not' is generated
2957 ;; it is never combined with the following 'and' to generate an 'andn' b/c 
2958 ;; the combiner never sees it.  use a peephole to pick up this case (happens
2959 ;; mostly with bitfields)  BRC
2960
2961 (define_peephole
2962   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2963         (match_operand:SI 1 "const_int_operand" "i"))
2964    (set (match_operand:SI 2 "mcore_arith_reg_operand" "r")
2965         (and:SI (match_dup 2) (match_dup 0)))]
2966   "mcore_const_trick_uses_not (INTVAL (operands[1])) &&
2967         operands[0] != operands[2] &&
2968         mcore_is_dead (insn, operands[0])"
2969   "* return mcore_output_andn (insn, operands);")
2970
2971 ; when setting or clearing just two bits, it's cheapest to use two bseti's 
2972 ; or bclri's.  only happens when relaxing immediates.  BRC
2973
2974 (define_peephole
2975   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2976         (match_operand:SI 1 "const_int_operand" ""))
2977    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2978         (ior:SI (match_dup 2) (match_dup 0)))]
2979   "TARGET_HARDLIT && mcore_num_ones (INTVAL (operands[1])) == 2 &&
2980        mcore_is_dead (insn, operands[0])"
2981   "* return mcore_output_bseti (operands[2], INTVAL (operands[1]));")
2982
2983 (define_peephole
2984   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2985         (match_operand:SI 1 "const_int_operand" ""))
2986    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2987         (and:SI (match_dup 2) (match_dup 0)))]
2988   "TARGET_HARDLIT && mcore_num_zeros (INTVAL (operands[1])) == 2 &&
2989        mcore_is_dead (insn, operands[0])"
2990   "* return mcore_output_bclri (operands[2], INTVAL (operands[1]));")
2991
2992 ; change an and with a mask that has a single cleared bit into a bclri.  this
2993 ; handles QI and HI mode values using the knowledge that the most significant
2994 ; bits don't matter.
2995
2996 (define_peephole
2997   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2998         (match_operand:SI 1 "const_int_operand" ""))
2999    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
3000         (and:SI (match_operand:SI 3 "mcore_arith_reg_operand" "")
3001                 (match_dup 0)))]
3002   "GET_CODE (operands[3]) == SUBREG && 
3003       GET_MODE (SUBREG_REG (operands[3])) == QImode &&
3004       mcore_num_zeros (INTVAL (operands[1]) | 0xffffff00) == 1 &&
3005       mcore_is_dead (insn, operands[0])"
3006 "*
3007   if (! mcore_is_same_reg (operands[2], operands[3]))
3008     output_asm_insn (\"mov\\t%2,%3\", operands);
3009   return mcore_output_bclri (operands[2], INTVAL (operands[1]) | 0xffffff00);")
3010
3011 /* Do not fold these together -- mode is lost at final output phase.  */
3012
3013 (define_peephole
3014   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
3015         (match_operand:SI 1 "const_int_operand" ""))
3016    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
3017         (and:SI (match_operand:SI 3 "mcore_arith_reg_operand" "")
3018                 (match_dup 0)))]
3019   "GET_CODE (operands[3]) == SUBREG && 
3020       GET_MODE (SUBREG_REG (operands[3])) == HImode &&
3021       mcore_num_zeros (INTVAL (operands[1]) | 0xffff0000) == 1 &&
3022       operands[2] == operands[3] &&
3023       mcore_is_dead (insn, operands[0])"
3024 "*
3025   if (! mcore_is_same_reg (operands[2], operands[3]))
3026     output_asm_insn (\"mov\\t%2,%3\", operands);
3027   return mcore_output_bclri (operands[2], INTVAL (operands[1]) | 0xffff0000);")
3028
3029 ; This peephole helps when using -mwide-bitfields to widen fields so they 
3030 ; collapse.   This, however, has the effect that a narrower mode is not used
3031 ; when desirable.  
3032 ;
3033 ; e.g., sequences like:
3034 ;
3035 ;      ldw r8,(r6)
3036 ;      movi r7,0x00ffffff
3037 ;      and r8,r7                 r7 dead
3038 ;      stw r8,(r6)                r8 dead
3039 ;
3040 ; get peepholed to become:
3041 ;
3042 ;      movi r8,0
3043 ;      stb r8,(r6)              r8 dead
3044 ;
3045 ; Do only easy addresses that have no offset.  This peephole is also applied 
3046 ; to halfwords.  We need to check that the load is non-volatile before we get
3047 ; rid of it.
3048
3049 (define_peephole
3050   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
3051         (match_operand:SI 1 "memory_operand" ""))
3052    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
3053         (match_operand:SI 3 "const_int_operand" ""))
3054    (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3055    (set (match_operand:SI 4 "memory_operand" "") (match_dup 0))]
3056   "mcore_is_dead (insn, operands[0]) &&
3057    ! MEM_VOLATILE_P (operands[1]) &&
3058    mcore_is_dead (insn, operands[2]) && 
3059    (mcore_byte_offset (INTVAL (operands[3])) > -1 || 
3060     mcore_halfword_offset (INTVAL (operands[3])) > -1) &&
3061    ! MEM_VOLATILE_P (operands[4]) &&
3062    GET_CODE (XEXP (operands[4], 0)) == REG"
3063 "*
3064 {
3065    int ofs;
3066    enum machine_mode mode;
3067    rtx base_reg = XEXP (operands[4], 0);
3068
3069    if ((ofs = mcore_byte_offset (INTVAL (operands[3]))) > -1)
3070       mode = QImode;
3071    else if ((ofs = mcore_halfword_offset (INTVAL (operands[3]))) > -1)
3072       mode = HImode;
3073    else
3074       gcc_unreachable ();
3075
3076    if (ofs > 0) 
3077       operands[4] = gen_rtx_MEM (mode, 
3078                               gen_rtx_PLUS (SImode, base_reg, GEN_INT(ofs)));
3079    else
3080       operands[4] = gen_rtx_MEM (mode, base_reg);
3081
3082    if (mode == QImode)
3083       return \"movi     %0,0\\n\\tst.b  %0,%4\";
3084
3085    return \"movi        %0,0\\n\\tst.h  %0,%4\";
3086 }")
3087
3088 ; from sop11. get btsti's for (LT A 0) where A is a QI or HI value
3089
3090 (define_peephole
3091   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
3092         (sign_extend:SI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))
3093    (set (reg:CC 17)
3094         (lt:CC (match_dup 0)
3095             (const_int 0)))]
3096   "mcore_is_dead (insn, operands[0])"
3097   "btsti        %0,7")
3098
3099 (define_peephole
3100   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
3101         (sign_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "0")))
3102    (set (reg:CC 17)
3103         (lt:CC (match_dup 0)
3104             (const_int 0)))]
3105   "mcore_is_dead (insn, operands[0])"
3106   "btsti        %0,15")
3107
3108 ; Pick up a tst.  This combination happens because the immediate is not
3109 ; allowed to fold into one of the operands of the tst.  Does not happen
3110 ; when relaxing immediates.  BRC
3111
3112 (define_peephole
3113   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
3114         (match_operand:SI 1 "mcore_arith_reg_operand" ""))
3115    (set (match_dup 0)
3116         (and:SI (match_dup 0)
3117                 (match_operand:SI 2 "mcore_literal_K_operand" "")))
3118    (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))]
3119   "mcore_is_dead (insn, operands[0])"
3120   "movi %0,%2\;tst      %1,%0")
3121
3122 (define_peephole
3123   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
3124         (if_then_else:SI (ne (zero_extract:SI 
3125                                 (match_operand:SI 1 "mcore_arith_reg_operand" "")
3126                                 (const_int 1)
3127                                 (match_operand:SI 2 "mcore_literal_K_operand" ""))
3128                              (const_int 0))
3129            (match_operand:SI 3 "mcore_arith_imm_operand" "")
3130            (match_operand:SI 4 "mcore_arith_imm_operand" "")))
3131     (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))]
3132   ""
3133 "*
3134 {
3135   unsigned int op0 = REGNO (operands[0]);
3136
3137   if (GET_CODE (operands[3]) == REG)
3138     {
3139      if (REGNO (operands[3]) == op0 && GET_CODE (operands[4]) == CONST_INT
3140          && INTVAL (operands[4]) == 0)
3141         return \"btsti  %1,%2\\n\\tclrf %0\";
3142      else if (GET_CODE (operands[4]) == REG)
3143        {
3144         if (REGNO (operands[4]) == op0)
3145            return \"btsti       %1,%2\\n\\tmovf %0,%3\";
3146         else if (REGNO (operands[3]) == op0)
3147            return \"btsti       %1,%2\\n\\tmovt %0,%4\";
3148        }
3149
3150      gcc_unreachable ();
3151     }
3152   else if (GET_CODE (operands[3]) == CONST_INT
3153            && INTVAL (operands[3]) == 0
3154            && GET_CODE (operands[4]) == REG)
3155      return \"btsti     %1,%2\\n\\tclrt %0\";
3156
3157   gcc_unreachable ();
3158 }")
3159
3160 ; experimental - do the constant folding ourselves.  note that this isn't
3161 ;   re-applied like we'd really want.  i.e., four ands collapse into two
3162 ;   instead of one.  this is because peepholes are applied as a sliding
3163 ;   window.  the peephole does not generate new rtl's, but instead slides
3164 ;   across the rtl's generating machine instructions.  it would be nice
3165 ;   if the peephole optimizer is changed to re-apply patterns and to gen
3166 ;   new rtl's.  this is more flexible.  the pattern below helps when we're
3167 ;   not using relaxed immediates.   BRC
3168
3169 ;(define_peephole
3170 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
3171 ;        (match_operand:SI 1 "const_int_operand" ""))
3172 ;   (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
3173 ;          (and:SI (match_dup 2) (match_dup 0)))
3174 ;   (set (match_dup 0)
3175 ;        (match_operand:SI 3 "const_int_operand" ""))
3176 ;   (set (match_dup 2)
3177 ;           (and:SI (match_dup 2) (match_dup 0)))]
3178 ;  "!TARGET_RELAX_IMM && mcore_is_dead (insn, operands[0]) &&
3179 ;       mcore_const_ok_for_inline (INTVAL (operands[1]) & INTVAL (operands[3]))"
3180 ;  "*
3181 ;{
3182 ;  rtx out_operands[2];
3183 ;  out_operands[0] = operands[0];
3184 ;  out_operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[3]));
3185 ;  
3186 ;  output_inline_const (SImode, out_operands);
3187 ;
3188 ;  output_asm_insn (\"and       %2,%0\", operands);
3189 ;
3190 ;  return \"\";   
3191 ;}")
3192
3193 ; BRC: for inlining get rid of extra test - experimental
3194 ;(define_peephole
3195 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
3196 ;          (ne:SI (reg:CC 17) (const_int 0)))
3197 ;   (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))
3198 ;   (set (pc) 
3199 ;       (if_then_else (eq (reg:CC 17) (const_int 0))
3200 ;         (label_ref (match_operand 1 "" ""))
3201 ;         (pc)))]
3202 ;   ""
3203 ;   "*
3204 ;{
3205 ;  if (get_attr_length (insn) == 10)
3206 ;    {
3207 ;      output_asm_insn (\"bt    2f\\n\\tjmpi    [1f]\", operands);
3208 ;      output_asm_insn (\".align        2\\n1:\", operands);
3209 ;      output_asm_insn (\".long %1\\n2:\", operands);
3210 ;      return \"\";
3211 ;    }
3212 ;  return \"bf  %l1\";
3213 ;}")
3214
3215 \f
3216 ;;; Special patterns for dealing with the constant pool.
3217
3218 ;;; 4 byte integer in line.
3219
3220 (define_insn "consttable_4"
3221  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 0)]
3222  ""
3223  "*
3224 {
3225   assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
3226   return \"\";
3227 }"
3228  [(set_attr "length" "4")])
3229
3230 ;;; align to a four byte boundary.
3231
3232 (define_insn "align_4"
3233  [(unspec_volatile [(const_int 0)] 1)]
3234  ""
3235  ".align 2")
3236
3237 ;;; Handle extra constant pool entries created during final pass.
3238
3239 (define_insn "consttable_end"
3240   [(unspec_volatile [(const_int 0)] 2)]
3241   ""
3242   "* return mcore_output_jump_label_table ();")
3243 \f
3244 ;;
3245 ;; Stack allocation -- in particular, for alloca().
3246 ;; this is *not* what we use for entry into functions.
3247 ;;
3248 ;; This is how we allocate stack space.  If we are allocating a
3249 ;; constant amount of space and we know it is less than 4096
3250 ;; bytes, we need do nothing.
3251 ;;
3252 ;; If it is more than 4096 bytes, we need to probe the stack
3253 ;; periodically. 
3254 ;;
3255 ;; operands[1], the distance is a POSITIVE number indicating that we
3256 ;; are allocating stack space
3257 ;;
3258 (define_expand "allocate_stack"
3259   [(set (reg:SI 0)
3260         (plus:SI (reg:SI 0)
3261                  (match_operand:SI 1 "general_operand" "")))
3262    (set (match_operand:SI 0 "register_operand" "=r")
3263         (match_dup 2))]
3264   ""
3265   "
3266 {
3267   /* If he wants no probing, just do it for him.  */
3268   if (mcore_stack_increment == 0)
3269     {
3270       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,operands[1]));
3271 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3272       DONE;
3273     }
3274
3275   /* For small constant growth, we unroll the code.  */
3276   if (GET_CODE (operands[1]) == CONST_INT
3277       && INTVAL (operands[1]) < 8 * STACK_UNITS_MAXSTEP)
3278     {
3279       int left = INTVAL(operands[1]);
3280
3281       /* If it's a long way, get close enough for a last shot.  */
3282       if (left >= STACK_UNITS_MAXSTEP)
3283         {
3284           rtx tmp = gen_reg_rtx (Pmode);
3285           emit_insn (gen_movsi (tmp, GEN_INT (STACK_UNITS_MAXSTEP)));
3286           do
3287             {
3288               rtx memref = gen_rtx_MEM (SImode, stack_pointer_rtx);
3289
3290               MEM_VOLATILE_P (memref) = 1;
3291               emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3292               emit_insn (gen_movsi (memref, stack_pointer_rtx));
3293               left -= STACK_UNITS_MAXSTEP;
3294             }
3295           while (left > STACK_UNITS_MAXSTEP);
3296         }
3297       /* Perform the final adjustment.  */
3298       emit_insn (gen_addsi3 (stack_pointer_rtx,stack_pointer_rtx,GEN_INT(-left)));
3299 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3300       DONE;
3301     }
3302   else
3303     {
3304       rtx out_label = 0;
3305       rtx loop_label = gen_label_rtx ();
3306       rtx step = gen_reg_rtx (Pmode);
3307       rtx tmp = gen_reg_rtx (Pmode);
3308       rtx memref;
3309
3310 #if 1
3311       emit_insn (gen_movsi (tmp, operands[1]));
3312       emit_insn (gen_movsi (step, GEN_INT(STACK_UNITS_MAXSTEP)));
3313
3314       if (GET_CODE (operands[1]) != CONST_INT)
3315         {
3316           out_label = gen_label_rtx ();
3317           emit_insn (gen_cmpsi (step, tmp));            /* quick out */
3318           emit_jump_insn (gen_bgeu (out_label));
3319         }
3320
3321       /* Run a loop that steps it incrementally.  */
3322       emit_label (loop_label);
3323
3324       /* Extend a step, probe, and adjust remaining count.  */
3325       emit_insn(gen_subsi3(stack_pointer_rtx, stack_pointer_rtx, step));
3326       memref = gen_rtx_MEM (SImode, stack_pointer_rtx);
3327       MEM_VOLATILE_P (memref) = 1;
3328       emit_insn(gen_movsi(memref, stack_pointer_rtx));
3329       emit_insn(gen_subsi3(tmp, tmp, step));
3330
3331       /* Loop condition -- going back up.  */
3332       emit_insn (gen_cmpsi (step, tmp));
3333       emit_jump_insn (gen_bltu (loop_label));
3334
3335       if (out_label)
3336         emit_label (out_label);
3337
3338       /* Bump the residual.  */
3339       emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3340 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3341       DONE;
3342 #else
3343       /* simple one-shot -- ensure register and do a subtract.
3344        * This does NOT comply with the ABI.  */
3345       emit_insn (gen_movsi (tmp, operands[1]));
3346       emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3347 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3348       DONE;
3349 #endif
3350     }
3351 }")