OSDN Git Service

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