Merge from mainline (165734:167278).
[official-gcc/graphite-test-results.git] / gcc / config / mcore / mcore.md
blob532181db0cc66efc892b9afb61e80dde3afbe3af
1 ;;  Machine description the Motorola MCore
2 ;;  Copyright (C) 1993, 1999, 2000, 2004, 2005, 2007, 2009, 2010
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Motorola.
6 ;; This file is part of GCC.
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.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; -------------------------------------------------------------------------
27 ;; Attributes
28 ;; -------------------------------------------------------------------------
30 ; Target CPU.
32 (define_attr "type" "brcond,branch,jmp,load,store,move,alu,shift"
33   (const_string "alu"))
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.
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.
44 ;; All MCORE instructions are two bytes long.
46 (define_attr "length" "" (const_int 2))
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")
56 (include "predicates.md")
58 ;; -------------------------------------------------------------------------
59 ;; Test and bit test
60 ;; -------------------------------------------------------------------------
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")])
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")])
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")])
92 ;; Created by combine from conditional patterns below (see sextb/btsti rx,31)
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")])
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")])
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   "")
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   "")
150 ;; XXX - disabled by nickc because it fails on libiberty/fnmatch.c
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")
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")
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)))])
203 ;; -------------------------------------------------------------------------
204 ;; SImode signed integer comparisons
205 ;; -------------------------------------------------------------------------
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")
217 ;; The combiner seems to prefer the following to the former.
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")
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")
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")
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")
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")
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")
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")
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")
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")
284 ;; -------------------------------------------------------------------------
285 ;; SImode unsigned integer comparisons
286 ;; -------------------------------------------------------------------------
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")
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")
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")
306 ;; -------------------------------------------------------------------------
307 ;; Logical operations
308 ;; -------------------------------------------------------------------------
310 ;; Logical AND clearing a single bit.  andsi3 knows that we have this
311 ;; pattern and allows the constant literal pass through.
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")
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")
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   "
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]);
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     }
353   if (! mcore_arith_K_S_operand (operands[2], SImode))
354     operands[2] = copy_to_mode_reg (SImode, operands[2]);
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   "*
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      }
375 ;; This was the old "S" which was "!(2^n)" */
376 ;; case -1: return \"bclri      %0,%Q2\";        will not happen */
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   "*
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      }
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")
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   "
410    if (! mcore_arith_M_operand (operands[2], SImode))
411       operands[2] = copy_to_mode_reg (SImode, operands[2]);
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   "*
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      }
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   "*
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      }
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")
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]));")
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")
467 ; these patterns give better code then gcc invents if
468 ; left to its own devices
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")])
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")])
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")])
494 ;; -------------------------------------------------------------------------
495 ;; Shifts and rotates
496 ;; -------------------------------------------------------------------------
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   ")
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")])
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")])
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")])
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")])
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")])
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" "")))
562 ;            (clobber (reg:CC 17))])]
563 ;           
564 ;  ""
565 ;  "
567 ;  if (GET_CODE (operands[2]) != CONST_INT
568 ;      || INTVAL (operands[2]) != 1)
569 ;    FAIL;
570 ;}")
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")])
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.
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.
594 ;; indexing longlongs or doubles (8 bytes)
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"
619   [(set_attr "length" "4")])
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")])
634 ;; indexing longs (4 bytes)
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")
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")])
657 ;; indexing shorts (2 bytes)
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")
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")])
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.
689 ;; -------------------------------------------------------------------------
690 ;; Addition, Subtraction instructions
691 ;; -------------------------------------------------------------------------
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   "
700   /* If this is an add to the frame pointer, then accept it as is so
701      that we can later fold in the fp/sp offset from frame pointer
702      elimination.  */
703   if (flag_omit_frame_pointer
704       && GET_CODE (operands[1]) == REG
705       && (REGNO (operands[1]) == VIRTUAL_STACK_VARS_REGNUM
706           || REGNO (operands[1]) == FRAME_POINTER_REGNUM))
707     {
708       emit_insn (gen_addsi3_fp (operands[0], operands[1], operands[2]));
709       DONE;
710     }
712   /* Convert adds to subtracts if this makes loading the constant cheaper.
713      But only if we are allowed to generate new pseudos.  */
714   if (! (reload_in_progress || reload_completed)
715       && GET_CODE (operands[2]) == CONST_INT
716       && INTVAL (operands[2]) < -32)
717     {
718       HOST_WIDE_INT neg_value = - INTVAL (operands[2]);
720       if (   CONST_OK_FOR_I (neg_value)
721           || CONST_OK_FOR_M (neg_value)
722           || CONST_OK_FOR_N (neg_value))
723         {
724           operands[2] = copy_to_mode_reg (SImode, GEN_INT (neg_value));
725           emit_insn (gen_subsi3 (operands[0], operands[1], operands[2]));
726           DONE;
727         }
728     } 
730   if (! mcore_addsub_operand (operands[2], SImode))
731     operands[2] = copy_to_mode_reg (SImode, operands[2]);
734 ;; RBE: for some constants which are not in the range which allows
735 ;; us to do a single operation, we will try a paired addi/addi instead
736 ;; of a movi/addi. This relieves some register pressure at the expense
737 ;; of giving away some potential constant reuse.
739 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
740 ;; for later reference
741 ;; 
742 ;; (define_insn "addsi3_i2"
743 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
744 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
745 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
746 ;;   "GET_CODE(operands[2]) == CONST_INT
747 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
748 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
749 ;;   "*
750 ;; {
751 ;;    HOST_WIDE_INT n = INTVAL(operands[2]);
752 ;;    if (n > 0)
753 ;;      {
754 ;;        operands[2] = GEN_INT(n - 32);
755 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
756 ;;      }
757 ;;    else
758 ;;      {
759 ;;        n = (-n);
760 ;;        operands[2] = GEN_INT(n - 32);
761 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
762 ;;      }
763 ;; }"
764 ;;  [(set_attr "length" "4")])
766 (define_insn "addsi3_i"
767   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
768         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
769                  (match_operand:SI 2 "mcore_addsub_operand" "r,J,L")))]
770   ""
771   "@
772         addu    %0,%2
773         addi    %0,%2
774         subi    %0,%M2")
776 ;; This exists so that address computations based on the frame pointer
777 ;; can be folded in when frame pointer elimination occurs.  Ordinarily
778 ;; this would be bad because it allows insns which would require reloading,
779 ;; but without it, we get multiple adds where one would do.
781 (define_insn "addsi3_fp"
782   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
783         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
784                  (match_operand:SI 2 "immediate_operand" "r,J,L")))]
785   "flag_omit_frame_pointer
786    && (reload_in_progress || reload_completed || REGNO (operands[1]) == FRAME_POINTER_REGNUM)"
787   "@
788         addu    %0,%2
789         addi    %0,%2
790         subi    %0,%M2")
792 ;; RBE: for some constants which are not in the range which allows
793 ;; us to do a single operation, we will try a paired addi/addi instead
794 ;; of a movi/addi. This relieves some register pressure at the expense
795 ;; of giving away some potential constant reuse.
797 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
798 ;; for later reference
799 ;; 
800 ;; (define_insn "subsi3_i2"
801 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
802 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
803 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
804 ;;   "TARGET_RBETEST && GET_CODE(operands[2]) == CONST_INT
805 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
806 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
807 ;;   "*
808 ;; {
809 ;;    HOST_WIDE_INT n = INTVAL(operands[2]);
810 ;;    if ( n > 0)
811 ;;      {
812 ;;        operands[2] = GEN_INT( n - 32);
813 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
814 ;;      }
815 ;;    else
816 ;;      {
817 ;;        n = (-n);
818 ;;        operands[2] = GEN_INT(n - 32);
819 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
820 ;;      }
821 ;; }"
822 ;;   [(set_attr "length" "4")])
824 ;(define_insn "subsi3"
825 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
826 ;       (minus:SI (match_operand:SI 1 "mcore_arith_K_operand" "0,0,r,K")
827 ;                 (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0,0")))]
828 ;  ""
829 ;  "@
830 ;       sub     %0,%2
831 ;       subi    %0,%2
832 ;       rsub    %0,%1
833 ;       rsubi   %0,%1")
835 (define_insn "subsi3"
836   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
837         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r")
838                   (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0")))]
839   ""
840   "@
841         subu    %0,%2
842         subi    %0,%2
843         rsub    %0,%1")
845 (define_insn ""
846   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
847         (minus:SI (match_operand:SI 1 "mcore_literal_K_operand" "K")
848                   (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
849   ""
850   "rsubi        %0,%1")
852 (define_insn "adddi3"
853   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
854         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
855                  (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
856    (clobber (reg:CC 17))]
857   ""
858   "*
859   {
860     if (TARGET_LITTLE_END)
861       return \"cmplt    %0,%0\;addc     %0,%2\;addc     %R0,%R2\";
862     return \"cmplt      %R0,%R0\;addc   %R0,%R2\;addc   %0,%2\";
863   }"
864   [(set_attr "length" "6")])
866 ;; special case for "longlong += 1"
867 (define_insn ""
868   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
869         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
870                  (const_int 1)))
871    (clobber (reg:CC 17))]
872   ""
873   "*
874   {
875    if (TARGET_LITTLE_END)
876       return \"addi     %0,1\;cmpnei %0,0\;incf %R0\";
877     return \"addi       %R0,1\;cmpnei %R0,0\;incf       %0\";
878   }"
879   [(set_attr "length" "6")])
881 ;; special case for "longlong -= 1"
882 (define_insn ""
883   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
884         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
885                  (const_int -1)))
886    (clobber (reg:CC 17))]
887   ""
888   "*
889   {
890     if (TARGET_LITTLE_END)
891        return \"cmpnei %0,0\;decf       %R0\;subi       %0,1\";
892     return \"cmpnei %R0,0\;decf %0\;subi        %R0,1\";
893   }"
894   [(set_attr "length" "6")])
896 ;; special case for "longlong += const_int"
897 ;; we have to use a register for the const_int because we don't
898 ;; have an unsigned compare immediate... only +/- 1 get to
899 ;; play the no-extra register game because they compare with 0.
900 ;; This winds up working out for any literal that is synthesized
901 ;; with a single instruction. The more complicated ones look
902 ;; like the get broken into subreg's to get initialized too soon
903 ;; for us to catch here. -- RBE 4/25/96
904 ;; only allow for-sure positive values.
906 (define_insn ""
907   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
908         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
909                  (match_operand:SI 2 "const_int_operand" "r")))
910    (clobber (reg:CC 17))]
911   "GET_CODE (operands[2]) == CONST_INT
912    && INTVAL (operands[2]) > 0 && ! (INTVAL (operands[2]) & 0x80000000)"
913   "*
915   gcc_assert (GET_MODE (operands[2]) == SImode);
916   if (TARGET_LITTLE_END)
917     return \"addu       %0,%2\;cmphs    %0,%2\;incf     %R0\";
918   return \"addu %R0,%2\;cmphs   %R0,%2\;incf    %0\";
920   [(set_attr "length" "6")])
922 ;; optimize "long long" + "unsigned long"
923 ;; won't trigger because of how the extension is expanded upstream.
924 ;; (define_insn ""
925 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
926 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
927 ;;               (zero_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
928 ;;    (clobber (reg:CC 17))]
929 ;;   "0"
930 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0"
931 ;;   [(set_attr "length" "6")])
933 ;; optimize "long long" + "signed long"
934 ;; won't trigger because of how the extension is expanded upstream.
935 ;; (define_insn ""
936 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
937 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
938 ;;               (sign_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
939 ;;    (clobber (reg:CC 17))]
940 ;;   "0"
941 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0\;btsti       %2,31\;dect     %0"
942 ;;   [(set_attr "length" "6")])
944 (define_insn "subdi3"
945   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
946         (minus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
947                   (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
948    (clobber (reg:CC 17))]
949   ""
950   "*
951   {
952     if (TARGET_LITTLE_END)
953       return \"cmphs    %0,%0\;subc     %0,%2\;subc     %R0,%R2\";
954     return \"cmphs      %R0,%R0\;subc   %R0,%R2\;subc   %0,%2\";
955   }"
956   [(set_attr "length" "6")])
958 ;; -------------------------------------------------------------------------
959 ;; Multiplication instructions
960 ;; -------------------------------------------------------------------------
962 (define_insn "mulsi3"
963   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
964         (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
965                  (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
966   ""
967   "mult %0,%2")
970 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
972 ;; Different constraints based on the architecture revision...
974 (define_expand "divsi3"
975   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
976         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
977                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
978   "TARGET_DIV"
979   "")
981 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
983 (define_insn ""
984   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
985         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
986                 (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
987   "TARGET_DIV"
988   "divs %0,%2")
991 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
993 ;; Different constraints based on the architecture revision...
995 (define_expand "udivsi3"
996   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
997         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
998                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
999   "TARGET_DIV"
1000   "")
1002 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
1003 (define_insn ""
1004   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1005         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1006                  (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
1007   "TARGET_DIV"
1008   "divu %0,%2")
1010 ;; -------------------------------------------------------------------------
1011 ;; Unary arithmetic
1012 ;; -------------------------------------------------------------------------
1014 (define_insn "negsi2"
1015   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1016         (neg:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1017   ""
1018   "*
1020    return \"rsubi       %0,0\";
1024 (define_insn "abssi2"
1025   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1026         (abs:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1027   ""
1028   "abs  %0")
1029              
1030 (define_insn "negdi2"
1031   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
1032         (neg:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")))
1033    (clobber (reg:CC 17))]
1034   ""
1035   "*
1037    if (TARGET_LITTLE_END)
1038      return \"cmpnei    %0,0\\n\\trsubi %0,0\\n\\tnot   %R0\\n\\tincf   %R0\";
1039    return \"cmpnei      %R0,0\\n\\trsubi        %R0,0\\n\\tnot  %0\\n\\tincf    %0\";
1041   [(set_attr "length" "8")])
1043 (define_insn "one_cmplsi2"
1044   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1045         (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1046   ""
1047   "not  %0")
1049 ;; -------------------------------------------------------------------------
1050 ;; Zero extension instructions
1051 ;; -------------------------------------------------------------------------
1053 (define_expand "zero_extendhisi2"
1054   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1055         (zero_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "")))]
1056   ""
1057   "")
1059 (define_insn ""
1060   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
1061         (zero_extend:SI (match_operand:HI 1 "general_operand" "0,m")))]
1062   ""
1063   "@
1064         zexth   %0
1065         ld.h    %0,%1"
1066   [(set_attr "type" "shift,load")])
1068 ;; ldh gives us a free zero-extension. The combiner picks up on this.
1069 (define_insn ""
1070   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1071         (zero_extend:SI (mem:HI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1072   ""
1073   "ld.h %0,(%1)"
1074   [(set_attr "type" "load")])
1076 (define_insn ""
1077   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1078         (zero_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1079                                          (match_operand:SI 2 "const_int_operand" "")))))]
1080   "(INTVAL (operands[2]) >= 0) &&
1081    (INTVAL (operands[2]) < 32) &&
1082    ((INTVAL (operands[2])&1) == 0)"
1083   "ld.h %0,(%1,%2)"
1084   [(set_attr "type" "load")])
1086 (define_expand "zero_extendqisi2"
1087   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1088         (zero_extend:SI (match_operand:QI 1 "general_operand" "")))]
1089   ""
1090   "") 
1092 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1093 (define_insn ""
1094   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b,r")
1095         (zero_extend:SI (match_operand:QI 1 "general_operand" "0,r,m")))]
1096   ""
1097   "@
1098         zextb   %0
1099         xtrb3   %0,%1
1100         ld.b    %0,%1"
1101   [(set_attr "type" "shift,shift,load")])
1103 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1104 (define_insn ""
1105   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1106         (zero_extend:SI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1107   ""
1108   "ld.b %0,(%1)"
1109   [(set_attr "type" "load")])
1111 (define_insn ""
1112   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1113         (zero_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1114                                          (match_operand:SI 2 "const_int_operand" "")))))]
1115   "(INTVAL (operands[2]) >= 0) &&
1116    (INTVAL (operands[2]) < 16)"
1117   "ld.b %0,(%1,%2)"
1118   [(set_attr "type" "load")])
1120 (define_expand "zero_extendqihi2"
1121   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "")
1122         (zero_extend:HI (match_operand:QI 1 "general_operand" "")))]
1123   ""
1124   "") 
1126 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1127 (define_insn ""
1128   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r,b,r")
1129         (zero_extend:HI (match_operand:QI 1 "general_operand" "0,r,m")))]
1130   ""
1131   "@
1132         zextb   %0
1133         xtrb3   %0,%1
1134         ld.b    %0,%1"
1135   [(set_attr "type" "shift,shift,load")])
1137 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1138 ;; this doesn't catch references that are into a structure.
1139 ;; note that normally the compiler uses the above insn, unless it turns
1140 ;; out that we're dealing with a volatile...
1141 (define_insn ""
1142   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1143         (zero_extend:HI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1144   ""
1145   "ld.b %0,(%1)"
1146   [(set_attr "type" "load")])
1148 (define_insn ""
1149   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1150         (zero_extend:HI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1151                                          (match_operand:SI 2 "const_int_operand" "")))))]
1152   "(INTVAL (operands[2]) >= 0) &&
1153    (INTVAL (operands[2]) < 16)"
1154   "ld.b %0,(%1,%2)"
1155   [(set_attr "type" "load")])
1158 ;; -------------------------------------------------------------------------
1159 ;; Sign extension instructions
1160 ;; -------------------------------------------------------------------------
1162 (define_expand "extendsidi2"
1163   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r") 
1164         (match_operand:SI 1 "mcore_arith_reg_operand" "r"))]
1165   ""
1166   "
1167   {
1168     int low, high;
1170     if (TARGET_LITTLE_END)
1171       low = 0, high = 4;
1172     else
1173       low = 4, high = 0;
1174     
1175     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], low),
1176               operands[1]));
1177     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], high),
1178               gen_rtx_ASHIFTRT (SImode,
1179                                gen_rtx_SUBREG (SImode, operands[0], low),
1180                                GEN_INT (31))));
1181     DONE;
1182   }"
1185 (define_insn "extendhisi2"
1186   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1187         (sign_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "0")))]
1188   ""
1189   "sexth        %0")
1191 (define_insn "extendqisi2"
1192   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1193         (sign_extend:SI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1194   ""
1195   "sextb        %0")
1197 (define_insn "extendqihi2"
1198   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1199         (sign_extend:HI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1200   ""
1201   "sextb        %0")
1203 ;; -------------------------------------------------------------------------
1204 ;; Move instructions
1205 ;; -------------------------------------------------------------------------
1207 ;; SImode
1209 (define_expand "movsi"
1210   [(set (match_operand:SI 0 "general_operand" "")
1211         (match_operand:SI 1 "general_operand" ""))]
1212   ""
1213   "
1215   if (GET_CODE (operands[0]) == MEM)
1216     operands[1] = force_reg (SImode, operands[1]);
1219 (define_insn ""
1220   [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,a,r,a,r,m")
1221         (match_operand:SI 1 "mcore_general_movsrc_operand"  "r,P,i,c,R,m,r"))]
1222   "(register_operand (operands[0], SImode)
1223     || register_operand (operands[1], SImode))"
1224   "* return mcore_output_move (insn, operands, SImode);"
1225   [(set_attr "type" "move,move,move,move,load,load,store")])
1228 ;; HImode
1231 (define_expand "movhi"
1232   [(set (match_operand:HI 0 "general_operand" "")
1233         (match_operand:HI 1 "general_operand"  ""))]
1234   ""
1235   "
1237   if (GET_CODE (operands[0]) == MEM)
1238     operands[1] = force_reg (HImode, operands[1]);
1239   else if (CONSTANT_P (operands[1])
1240            && (GET_CODE (operands[1]) != CONST_INT
1241                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1242                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1243                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1244            && ! reload_completed && ! reload_in_progress)
1245     {
1246       rtx reg = gen_reg_rtx (SImode);
1247       emit_insn (gen_movsi (reg, operands[1]));
1248       operands[1] = gen_lowpart (HImode, reg);
1249     }
1251   
1252 (define_insn ""
1253   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1254         (match_operand:HI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1255   "(register_operand (operands[0], HImode)
1256     || register_operand (operands[1], HImode))"
1257   "* return mcore_output_move (insn, operands, HImode);"
1258   [(set_attr "type" "move,move,move,move,load,store")])
1261 ;; QImode
1264 (define_expand "movqi"
1265   [(set (match_operand:QI 0 "general_operand" "")
1266         (match_operand:QI 1 "general_operand"  ""))]
1267   ""
1268   "
1270   if (GET_CODE (operands[0]) == MEM)
1271     operands[1] = force_reg (QImode, operands[1]);
1272   else if (CONSTANT_P (operands[1])
1273            && (GET_CODE (operands[1]) != CONST_INT
1274                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1275                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1276                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1277            && ! reload_completed && ! reload_in_progress)
1278     {
1279       rtx reg = gen_reg_rtx (SImode);
1280       emit_insn (gen_movsi (reg, operands[1]));
1281       operands[1] = gen_lowpart (QImode, reg);
1282     }
1284   
1285 (define_insn ""
1286   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1287         (match_operand:QI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1288   "(register_operand (operands[0], QImode)
1289     || register_operand (operands[1], QImode))"
1290   "* return mcore_output_move (insn, operands, QImode);"
1291    [(set_attr "type" "move,move,move,move,load,store")])
1294 ;; DImode
1296 (define_expand "movdi"
1297   [(set (match_operand:DI 0 "general_operand" "")
1298         (match_operand:DI 1 "general_operand" ""))]
1299   ""
1300   "
1302   if (GET_CODE (operands[0]) == MEM)
1303     operands[1] = force_reg (DImode, operands[1]);
1304   else if (GET_CODE (operands[1]) == CONST_INT
1305            && ! CONST_OK_FOR_I (INTVAL (operands[1]))
1306            && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1307            && ! CONST_OK_FOR_N (INTVAL (operands[1])))
1308     {
1309       int i;
1310       for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
1311         emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
1312                         simplify_gen_subreg (SImode, operands[1], DImode, i));
1313       DONE;
1314     }
1317 (define_insn "movdi_i"
1318   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,a,r,m")
1319         (match_operand:DI 1 "mcore_general_movsrc_operand" "I,M,N,r,R,m,r"))]
1320   ""
1321   "* return mcore_output_movedouble (operands, DImode);"
1322   [(set_attr "length" "4") (set_attr "type" "move,move,move,move,load,load,store")])
1324 ;; SFmode
1326 (define_expand "movsf"
1327   [(set (match_operand:SF 0 "general_operand" "")
1328         (match_operand:SF 1 "general_operand" ""))]
1329   ""
1330   "
1332   if (GET_CODE (operands[0]) == MEM)
1333     operands[1] = force_reg (SFmode, operands[1]);
1336 (define_insn "movsf_i"
1337   [(set (match_operand:SF 0 "general_operand" "=r,r,m")
1338         (match_operand:SF 1 "general_operand"  "r,m,r"))]
1339   ""
1340   "@
1341         mov     %0,%1
1342         ld.w    %0,%1
1343         st.w    %1,%0"
1344   [(set_attr "type" "move,load,store")])
1346 ;; DFmode
1348 (define_expand "movdf"
1349   [(set (match_operand:DF 0 "general_operand" "")
1350         (match_operand:DF 1 "general_operand" ""))]
1351   ""
1352   "
1354   if (GET_CODE (operands[0]) == MEM)
1355     operands[1] = force_reg (DFmode, operands[1]);
1358 (define_insn "movdf_k"
1359   [(set (match_operand:DF 0 "general_operand" "=r,r,m")
1360         (match_operand:DF 1 "general_operand" "r,m,r"))]
1361   ""
1362   "* return mcore_output_movedouble (operands, DFmode);"
1363   [(set_attr "length" "4") (set_attr "type" "move,load,store")])
1366 ;; Load/store multiple
1368 ;; ??? This is not currently used.
1369 (define_insn "ldm"
1370   [(set (match_operand:TI 0 "mcore_arith_reg_operand" "=r")
1371         (mem:TI (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
1372   ""
1373   "ldq  %U0,(%1)")
1375 ;; ??? This is not currently used.
1376 (define_insn "stm"
1377   [(set (mem:TI (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1378         (match_operand:TI 1 "mcore_arith_reg_operand" "r"))]
1379   ""
1380   "stq  %U1,(%0)")
1382 (define_expand "load_multiple"
1383   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1384                           (match_operand:SI 1 "" ""))
1385                      (use (match_operand:SI 2 "" ""))])]
1386   ""
1387   "
1389   int regno, count, i;
1391   /* Support only loading a constant number of registers from memory and
1392      only if at least two registers.  The last register must be r15.  */
1393   if (GET_CODE (operands[2]) != CONST_INT
1394       || INTVAL (operands[2]) < 2
1395       || GET_CODE (operands[1]) != MEM
1396       || XEXP (operands[1], 0) != stack_pointer_rtx
1397       || GET_CODE (operands[0]) != REG
1398       || REGNO (operands[0]) + INTVAL (operands[2]) != 16)
1399     FAIL;
1401   count = INTVAL (operands[2]);
1402   regno = REGNO (operands[0]);
1404   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1406   for (i = 0; i < count; i++)
1407     XVECEXP (operands[3], 0, i)
1408       = gen_rtx_SET (VOIDmode,
1409                  gen_rtx_REG (SImode, regno + i),
1410                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1411                                                       i * 4)));
1414 (define_insn ""
1415   [(match_parallel 0 "mcore_load_multiple_operation"
1416                    [(set (match_operand:SI 1 "mcore_arith_reg_operand" "=r")
1417                          (mem:SI (match_operand:SI 2 "register_operand" "r")))])]
1418   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1419   "ldm  %1-r15,(%2)")
1421 (define_expand "store_multiple"
1422   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1423                           (match_operand:SI 1 "" ""))
1424                      (use (match_operand:SI 2 "" ""))])]
1425   ""
1426   "
1428   int regno, count, i;
1430   /* Support only storing a constant number of registers to memory and
1431      only if at least two registers.  The last register must be r15.  */
1432   if (GET_CODE (operands[2]) != CONST_INT
1433       || INTVAL (operands[2]) < 2
1434       || GET_CODE (operands[0]) != MEM
1435       || XEXP (operands[0], 0) != stack_pointer_rtx
1436       || GET_CODE (operands[1]) != REG
1437       || REGNO (operands[1]) + INTVAL (operands[2]) != 16)
1438     FAIL;
1440   count = INTVAL (operands[2]);
1441   regno = REGNO (operands[1]);
1443   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1445   for (i = 0; i < count; i++)
1446     XVECEXP (operands[3], 0, i)
1447       = gen_rtx_SET (VOIDmode,
1448                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1449                                                       i * 4)),
1450                  gen_rtx_REG (SImode, regno + i));
1453 (define_insn ""
1454   [(match_parallel 0 "mcore_store_multiple_operation"
1455                    [(set (mem:SI (match_operand:SI 2 "register_operand" "r"))
1456                          (match_operand:SI 1 "mcore_arith_reg_operand" "r"))])]
1457   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1458   "stm  %1-r15,(%2)")
1460 ;; ------------------------------------------------------------------------
1461 ;; Define the real conditional branch instructions.
1462 ;; ------------------------------------------------------------------------
1464 ;; At top-level, condition test are eq/ne, because we
1465 ;; are comparing against the condition register (which
1466 ;; has the result of the true relational test
1468 (define_insn "branch_true"
1469   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1470                            (label_ref (match_operand 0 "" ""))
1471                            (pc)))]
1472   ""
1473   "jbt  %l0"
1474   [(set_attr "type" "brcond")])
1476 (define_insn "branch_false"
1477   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1478                            (label_ref (match_operand 0 "" ""))
1479                            (pc)))]
1480   ""
1481   "jbf  %l0"
1482   [(set_attr "type" "brcond")])
1484 (define_insn "inverse_branch_true"
1485   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1486                            (pc)
1487                            (label_ref (match_operand 0 "" ""))))]
1488   ""
1489   "jbf  %l0"
1490   [(set_attr "type" "brcond")])
1492 (define_insn "inverse_branch_false"
1493   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1494                            (pc)
1495                            (label_ref (match_operand 0 "" ""))))]
1496   ""
1497   "jbt  %l0"
1498   [(set_attr "type" "brcond")])
1500 ;; Conditional branch insns
1502 (define_expand "cbranchsi4"
1503   [(set (pc)
1504         (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
1505                        [(match_operand:SI 1 "mcore_compare_operand")
1506                         (match_operand:SI 2 "nonmemory_operand")])
1507                       (label_ref (match_operand 3 ""))
1508                       (pc)))]
1509   ""
1510   "
1512   bool invert;
1513   invert = mcore_gen_compare (GET_CODE (operands[0]),
1514                               operands[1], operands[2]);
1516   if (invert)
1517     emit_jump_insn (gen_branch_false (operands[3]));
1518   else
1519     emit_jump_insn (gen_branch_true (operands[3]));
1520   DONE;
1525 ;; ------------------------------------------------------------------------
1526 ;; Jump and linkage insns
1527 ;; ------------------------------------------------------------------------
1529 (define_insn "jump_real"
1530   [(set (pc)
1531         (label_ref (match_operand 0 "" "")))]
1532   ""
1533   "jbr  %l0"
1534   [(set_attr "type" "branch")])
1536 (define_expand "jump"
1537  [(set (pc) (label_ref (match_operand 0 "" "")))]
1538  ""
1541   emit_jump_insn (gen_jump_real (operand0));
1542   DONE;
1546 (define_insn "indirect_jump"
1547   [(set (pc)
1548         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))]
1549   ""
1550   "jmp  %0"
1551   [(set_attr "type" "jmp")])
1553 (define_expand "call"
1554   [(parallel[(call (match_operand:SI 0 "" "")
1555                    (match_operand 1 "" ""))
1556              (clobber (reg:SI 15))])]
1557   ""
1558   "
1560   if (GET_CODE (operands[0]) == MEM
1561       && ! register_operand (XEXP (operands[0], 0), SImode)
1562       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1563     operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1564                            force_reg (Pmode, XEXP (operands[0], 0)));
1567 (define_insn "call_internal"
1568   [(call (mem:SI (match_operand:SI 0 "mcore_call_address_operand" "riR"))
1569          (match_operand 1 "" ""))
1570    (clobber (reg:SI 15))]
1571   ""
1572   "* return mcore_output_call (operands, 0);")
1574 (define_expand "call_value"
1575   [(parallel[(set (match_operand 0 "register_operand" "")
1576                   (call (match_operand:SI 1 "" "")
1577                         (match_operand 2 "" "")))
1578              (clobber (reg:SI 15))])]
1579   ""
1580   "
1582   if (GET_CODE (operands[0]) == MEM
1583       && ! register_operand (XEXP (operands[0], 0), SImode)
1584       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1585     operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
1586                            force_reg (Pmode, XEXP (operands[1], 0)));
1589 (define_insn "call_value_internal"
1590   [(set (match_operand 0 "register_operand" "=r")
1591         (call (mem:SI (match_operand:SI 1 "mcore_call_address_operand" "riR"))
1592               (match_operand 2 "" "")))
1593    (clobber (reg:SI 15))]
1594   ""
1595   "* return mcore_output_call (operands, 1);")
1597 (define_insn "call_value_struct"
1598   [(parallel [(set (match_parallel 0 ""
1599                      [(expr_list (match_operand 3 "register_operand" "") (match_operand 4 "immediate_operand" ""))
1600                       (expr_list (match_operand 5 "register_operand" "") (match_operand 6 "immediate_operand" ""))])
1601                   (call (match_operand:SI 1 "" "")
1602                         (match_operand 2 "" "")))
1603              (clobber (reg:SI 15))])]
1604   ""
1605   "* return mcore_output_call (operands, 1);"
1609 ;; ------------------------------------------------------------------------
1610 ;; Misc insns
1611 ;; ------------------------------------------------------------------------
1613 (define_insn "nop"
1614   [(const_int 0)]
1615   ""
1616   "or   r0,r0")
1618 (define_insn "tablejump"
1619   [(set (pc)
1620         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1621    (use (label_ref (match_operand 1 "" "")))]
1622   ""
1623   "jmp  %0"
1624   [(set_attr "type" "jmp")])
1626 (define_insn "*return"
1627  [(return)]
1628  "reload_completed && ! mcore_naked_function_p ()"
1629  "jmp   r15"
1630  [(set_attr "type" "jmp")])
1632 (define_insn "*no_return"
1633  [(return)]
1634  "reload_completed && mcore_naked_function_p ()"
1635  ""
1636  [(set_attr "length" "0")]
1639 (define_expand "prologue"
1640   [(const_int 0)]
1641   ""
1642   "mcore_expand_prolog (); DONE;")
1644 (define_expand "epilogue"
1645   [(return)]
1646   ""
1647   "mcore_expand_epilog ();")
1649 ;; ------------------------------------------------------------------------
1650 ;; Scc instructions
1651 ;; ------------------------------------------------------------------------
1653 (define_insn "mvc"
1654   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1655         (ne:SI (reg:CC 17) (const_int 0)))]
1656   ""
1657   "mvc  %0"
1658   [(set_attr "type" "move")])
1660 (define_insn "mvcv"
1661   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1662         (eq:SI (reg:CC 17) (const_int 0)))]
1663   ""
1664   "mvcv %0"
1665   [(set_attr "type" "move")])
1667 ; in 0.97 use (LE 0) with (LT 1) and complement c.  BRC
1668 (define_split 
1669   [(parallel[
1670      (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1671           (ne:SI (gt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1672                         (const_int 0))
1673                  (const_int 0)))
1674      (clobber (reg:SI 17))])]
1675   ""
1676   [(set (reg:CC 17)
1677         (lt:CC (match_dup 1) (const_int 1)))
1678    (set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
1679      
1681 (define_expand "cstoresi4"
1682   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1683         (match_operator:SI 1 "ordered_comparison_operator"
1684          [(match_operand:SI 2 "mcore_compare_operand" "")
1685           (match_operand:SI 3 "nonmemory_operand" "")]))]
1686   ""
1687   "
1689   bool invert;
1690   invert = mcore_gen_compare (GET_CODE (operands[1]),
1691                               operands[2], operands[3]);
1693   if (invert)
1694     emit_insn (gen_mvcv (operands[0]));
1695   else
1696     emit_insn (gen_mvc (operands[0]));
1697   DONE;
1700 (define_insn "incscc"
1701   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1702         (plus:SI (ne (reg:CC 17) (const_int 0))
1703                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1704   ""
1705   "inct %0")
1707 (define_insn "incscc_false"
1708   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1709         (plus:SI (eq (reg:CC 17) (const_int 0))
1710                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1711   ""
1712   "incf %0")
1714 (define_insn "decscc"
1715   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1716         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1717                   (ne (reg:CC 17) (const_int 0))))]
1718   ""
1719   "dect %0")
1721 (define_insn "decscc_false"
1722   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1723         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1724                   (eq (reg:CC 17) (const_int 0))))]
1725   ""
1726   "decf %0")
1728 ;; ------------------------------------------------------------------------
1729 ;; Conditional move patterns.
1730 ;; ------------------------------------------------------------------------
1732 (define_expand "smaxsi3"
1733   [(set (reg:CC 17)
1734         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1735                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
1736    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1737         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1738                          (match_dup 1) (match_dup 2)))]
1739   ""
1740   "")
1741                
1742 (define_split
1743   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1744         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1745                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1746   ""
1747   [(set (reg:CC 17)
1748         (lt:SI (match_dup 1) (match_dup 2)))
1749    (set (match_dup 0)
1750         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1751                          (match_dup 1) (match_dup 2)))]
1752   "")
1754 ; no tstgt in 0.97, so just use cmplti (btsti x,31) and reverse move 
1755 ; condition  BRC
1756 (define_split
1757   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1758         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1759                  (const_int 0)))]
1760   ""
1761   [(set (reg:CC 17)
1762         (lt:CC (match_dup 1) (const_int 0)))
1763    (set (match_dup 0)
1764         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1765                          (match_dup 1) (const_int 0)))]
1766   "")
1768 (define_expand "sminsi3"
1769   [(set (reg:CC 17)
1770         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1771                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
1772    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1773         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
1774                          (match_dup 1) (match_dup 2)))]
1775   ""
1776   "")
1778 (define_split
1779   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1780         (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1781                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1782   ""
1783   [(set (reg:CC 17)
1784         (lt:SI (match_dup 1) (match_dup 2)))
1785    (set (match_dup 0)
1786         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
1787                          (match_dup 1) (match_dup 2)))]
1788   "")
1790 ;(define_split
1791 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1792 ;        (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1793 ;                 (const_int 0)))]
1794 ;  ""
1795 ;  [(set (reg:CC 17)
1796 ;        (gt:CC (match_dup 1) (const_int 0)))
1797 ;   (set (match_dup 0)
1798 ;        (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1799 ;                         (match_dup 1) (const_int 0)))]
1800 ;  "")
1802 ; changed these unsigned patterns to use geu instead of ltu.  it appears
1803 ; that the c-torture & ssrl test suites didn't catch these!  only showed
1804 ; up in friedman's clib work.   BRC 7/7/95
1806 (define_expand "umaxsi3"
1807   [(set (reg:CC 17)
1808         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1809                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
1810    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1811         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1812                          (match_dup 2) (match_dup 1)))]
1813   ""
1814   "")
1815                
1816 (define_split
1817   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1818         (umax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1819                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1820   ""
1821   [(set (reg:CC 17)
1822         (geu:SI (match_dup 1) (match_dup 2)))
1823    (set (match_dup 0)
1824         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
1825                          (match_dup 2) (match_dup 1)))]
1826   "")
1828 (define_expand "uminsi3"
1829   [(set (reg:CC 17)
1830         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1831                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
1832    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1833         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
1834                          (match_dup 2) (match_dup 1)))]
1835   ""
1836   "")
1838 (define_split
1839   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1840         (umin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1841                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1842   ""
1843   [(set (reg:CC 17)
1844         (geu:SI (match_dup 1) (match_dup 2)))
1845    (set (match_dup 0)
1846         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
1847                          (match_dup 2) (match_dup 1)))]
1848   "")
1850 ;; ------------------------------------------------------------------------
1851 ;; conditional move patterns really start here
1852 ;; ------------------------------------------------------------------------
1854 ;; the "movtK" patterns are experimental.  they are intended to account for
1855 ;; gcc's mucking on code such as:
1857 ;;            free_ent = ((block_compress) ? 257 : 256 );
1859 ;; these patterns help to get a tstne/bgeni/inct (or equivalent) sequence
1860 ;; when both arms have constants that are +/- 1 of each other.
1862 ;; note in the following patterns that the "movtK" ones should be the first
1863 ;; one defined in each sequence.  this is because the general pattern also
1864 ;; matches, so use ordering to determine priority (it's easier this way than
1865 ;; adding conditions to the general patterns).   BRC
1867 ;; the U and Q constraints are necessary to ensure that reload does the
1868 ;; 'right thing'.  U constrains the operand to 0 and Q to 1 for use in the
1869 ;; clrt & clrf and clrt/inct & clrf/incf patterns.    BRC 6/26
1871 ;; ??? there appears to be some problems with these movtK patterns for ops
1872 ;; other than eq & ne.  need to fix.  6/30 BRC
1874 ;; ------------------------------------------------------------------------
1875 ;; ne 
1876 ;; ------------------------------------------------------------------------
1878 ; experimental conditional move with two constants +/- 1  BRC
1880 (define_insn "movtK_1"
1881   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1882         (if_then_else:SI
1883             (ne (reg:CC 17) (const_int 0))
1884           (match_operand:SI 1 "mcore_arith_O_operand" "O")
1885           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
1886   "  GET_CODE (operands[1]) == CONST_INT
1887   && GET_CODE (operands[2]) == CONST_INT
1888   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
1889       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
1890   "* return mcore_output_cmov (operands, 1, NULL);"
1891   [(set_attr "length" "4")])
1893 (define_insn "movt0"
1894   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
1895         (if_then_else:SI
1896          (ne (reg:CC 17) (const_int 0))
1897          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
1898          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
1899   ""
1900   "@
1901     movt        %0,%1
1902     movf        %0,%2
1903     clrt        %0
1904     clrf        %0")
1906 ;; ------------------------------------------------------------------------
1907 ;; eq
1908 ;; ------------------------------------------------------------------------
1910 ; experimental conditional move with two constants +/- 1  BRC
1911 (define_insn "movtK_2"
1912   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1913         (if_then_else:SI
1914             (eq (reg:CC 17) (const_int 0))
1915           (match_operand:SI 1 "mcore_arith_O_operand" "O")
1916           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
1917   "  GET_CODE (operands[1]) == CONST_INT
1918   && GET_CODE (operands[2]) == CONST_INT
1919   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
1920       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
1921   "* return mcore_output_cmov (operands, 0, NULL);"
1922   [(set_attr "length" "4")])
1924 (define_insn "movf0"
1925   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
1926         (if_then_else:SI
1927          (eq (reg:CC 17) (const_int 0))
1928          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
1929          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
1930   ""
1931   "@
1932     movf        %0,%1
1933     movt        %0,%2
1934     clrf        %0
1935     clrt        %0")
1937 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
1938 ; because the instructions are not adjacent (peepholes are related by posn -
1939 ; not by dataflow).   BRC
1941 (define_insn ""
1942   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
1943         (if_then_else:SI (eq (zero_extract:SI 
1944                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
1945                               (const_int 1)
1946                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
1947                              (const_int 0))
1948                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
1949                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
1950   ""
1951   "@
1952     btsti       %1,%2\;movf     %0,%3
1953     btsti       %1,%2\;movt     %0,%4
1954     btsti       %1,%2\;clrf     %0
1955     btsti       %1,%2\;clrt     %0"
1956   [(set_attr "length" "4")])
1958 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
1960 (define_insn ""
1961   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
1962         (if_then_else:SI (eq (lshiftrt:SI 
1963                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
1964                               (const_int 7))
1965                              (const_int 0))
1966                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
1967                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
1968   "GET_CODE (operands[1]) == SUBREG && 
1969       GET_MODE (SUBREG_REG (operands[1])) == QImode"
1970   "@
1971     btsti       %1,7\;movf      %0,%2
1972     btsti       %1,7\;movt      %0,%3
1973     btsti       %1,7\;clrf      %0
1974     btsti       %1,7\;clrt      %0"
1975   [(set_attr "length" "4")])
1978 ;; ------------------------------------------------------------------------
1979 ;; ne
1980 ;; ------------------------------------------------------------------------
1982 ;; Combine creates this from an andn instruction in a scc sequence.
1983 ;; We must recognize it to get conditional moves generated.
1985 ; experimental conditional move with two constants +/- 1  BRC
1986 (define_insn "movtK_3"
1987   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1988         (if_then_else:SI
1989             (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
1990                 (const_int 0))
1991           (match_operand:SI 2 "mcore_arith_O_operand" "O")
1992           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
1993   "  GET_CODE (operands[2]) == CONST_INT
1994   && GET_CODE (operands[3]) == CONST_INT
1995   && (   (INTVAL (operands[2]) - INTVAL (operands[3]) == 1)
1996       || (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
1997   "*
1999   rtx out_operands[4];
2000   out_operands[0] = operands[0];
2001   out_operands[1] = operands[2];
2002   out_operands[2] = operands[3];
2003   out_operands[3] = operands[1];
2005   return mcore_output_cmov (out_operands, 1, \"cmpnei   %3,0\");
2008   [(set_attr "length" "6")])
2010 (define_insn "movt2"
2011   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2012         (if_then_else:SI (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2013                              (const_int 0))
2014                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2015                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2016   ""      
2017   "@
2018     cmpnei      %1,0\;movt      %0,%2
2019     cmpnei      %1,0\;movf      %0,%3
2020     cmpnei      %1,0\;clrt      %0
2021     cmpnei      %1,0\;clrf      %0"
2022   [(set_attr "length" "4")])
2024 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
2025 ; because the instructions are not adjacent (peepholes are related by posn -
2026 ; not by dataflow).   BRC
2028 (define_insn ""
2029  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2030         (if_then_else:SI (ne (zero_extract:SI 
2031                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2032                               (const_int 1)
2033                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
2034                              (const_int 0))
2035                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
2036                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
2037   ""
2038   "@
2039     btsti       %1,%2\;movt     %0,%3
2040     btsti       %1,%2\;movf     %0,%4
2041     btsti       %1,%2\;clrt     %0
2042     btsti       %1,%2\;clrf     %0"
2043   [(set_attr "length" "4")])
2045 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
2047 (define_insn ""
2048   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2049         (if_then_else:SI (ne (lshiftrt:SI 
2050                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2051                               (const_int 7))
2052                              (const_int 0))
2053                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2054                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2055   "GET_CODE (operands[1]) == SUBREG && 
2056       GET_MODE (SUBREG_REG (operands[1])) == QImode"
2057   "@
2058     btsti       %1,7\;movt      %0,%2
2059     btsti       %1,7\;movf      %0,%3
2060     btsti       %1,7\;clrt      %0
2061     btsti       %1,7\;clrf      %0"
2062   [(set_attr "length" "4")])
2064 ;; ------------------------------------------------------------------------
2065 ;; eq/eq
2066 ;; ------------------------------------------------------------------------
2068 ; experimental conditional move with two constants +/- 1  BRC
2069 (define_insn "movtK_4"
2070   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2071         (if_then_else:SI
2072             (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2073           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2074           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2075   "GET_CODE (operands[1]) == CONST_INT &&
2076    GET_CODE (operands[2]) == CONST_INT &&
2077    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2078    (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2079   "* return mcore_output_cmov(operands, 1, NULL);"
2080   [(set_attr "length" "4")])
2082 (define_insn "movt3"
2083   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2084         (if_then_else:SI
2085          (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2086          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2087          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2088   ""
2089   "@
2090     movt        %0,%1
2091     movf        %0,%2
2092     clrt        %0
2093     clrf        %0")
2095 ;; ------------------------------------------------------------------------
2096 ;; eq/ne
2097 ;; ------------------------------------------------------------------------
2099 ; experimental conditional move with two constants +/- 1  BRC
2100 (define_insn "movtK_5"
2101   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2102         (if_then_else:SI
2103             (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2104           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2105           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2106   "GET_CODE (operands[1]) == CONST_INT &&
2107    GET_CODE (operands[2]) == CONST_INT &&
2108    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2109     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2110   "* return mcore_output_cmov (operands, 0, NULL);"
2111   [(set_attr "length" "4")])
2113 (define_insn "movf1"
2114   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2115         (if_then_else:SI
2116          (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2117          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2118          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2119   ""
2120   "@
2121     movf        %0,%1
2122     movt        %0,%2
2123     clrf        %0
2124     clrt        %0")
2126 ;; ------------------------------------------------------------------------
2127 ;; eq
2128 ;; ------------------------------------------------------------------------
2130 ;; Combine creates this from an andn instruction in a scc sequence.
2131 ;; We must recognize it to get conditional moves generated.
2133 ; experimental conditional move with two constants +/- 1  BRC
2135 (define_insn "movtK_6"
2136   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2137         (if_then_else:SI
2138             (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2139                 (const_int 0))
2140           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2141           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2142   "GET_CODE (operands[1]) == CONST_INT &&
2143    GET_CODE (operands[2]) == CONST_INT &&
2144    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2145     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2146   "* 
2148    rtx out_operands[4];
2149    out_operands[0] = operands[0];
2150    out_operands[1] = operands[2];
2151    out_operands[2] = operands[3];
2152    out_operands[3] = operands[1];
2154    return mcore_output_cmov (out_operands, 0, \"cmpnei  %3,0\");
2156   [(set_attr "length" "6")])
2158 (define_insn "movf3"
2159   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2160         (if_then_else:SI (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2161                              (const_int 0))
2162                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2163                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2164   ""
2165   "@
2166     cmpnei      %1,0\;movf      %0,%2
2167     cmpnei      %1,0\;movt      %0,%3
2168     cmpnei      %1,0\;clrf      %0
2169     cmpnei      %1,0\;clrt      %0"
2170   [(set_attr "length" "4")])
2172 ;; ------------------------------------------------------------------------
2173 ;; ne/eq
2174 ;; ------------------------------------------------------------------------
2176 ; experimental conditional move with two constants +/- 1  BRC
2177 (define_insn "movtK_7"
2178   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2179         (if_then_else:SI
2180             (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2181           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2182           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2183   "GET_CODE (operands[1]) == CONST_INT &&
2184    GET_CODE (operands[2]) == CONST_INT &&
2185    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2186     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2187   "* return mcore_output_cmov (operands, 0, NULL);"
2188   [(set_attr "length" "4")])
2190 (define_insn "movf4"
2191   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2192         (if_then_else:SI
2193          (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2194          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2195          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2196   ""
2197   "@
2198     movf        %0,%1
2199     movt        %0,%2
2200     clrf        %0
2201     clrt        %0")
2203 ;; ------------------------------------------------------------------------
2204 ;; ne/ne
2205 ;; ------------------------------------------------------------------------
2207 ; experimental conditional move with two constants +/- 1  BRC
2208 (define_insn "movtK_8"
2209   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2210         (if_then_else:SI
2211             (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2212           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2213           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2214   "GET_CODE (operands[1]) == CONST_INT &&
2215    GET_CODE (operands[2]) == CONST_INT &&
2216    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2217     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2218   "* return mcore_output_cmov (operands, 1, NULL);"
2219   [(set_attr "length" "4")])
2221 (define_insn "movt4"
2222   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2223         (if_then_else:SI
2224          (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2225          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2226          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2227   ""
2228   "@
2229     movt        %0,%1
2230     movf        %0,%2
2231     clrt        %0
2232     clrf        %0")
2234 ;; Also need patterns to recognize lt/ge, since otherwise the compiler will
2235 ;; try to output not/asri/tstne/movf.
2237 ;; ------------------------------------------------------------------------
2238 ;; lt
2239 ;; ------------------------------------------------------------------------
2241 ; experimental conditional move with two constants +/- 1  BRC
2242 (define_insn "movtK_9"
2243   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2244         (if_then_else:SI
2245             (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2246                 (const_int 0))
2247           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2248           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2249   "GET_CODE (operands[2]) == CONST_INT &&
2250    GET_CODE (operands[3]) == CONST_INT &&
2251    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2252     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2253   "*
2255    rtx out_operands[4];
2256    out_operands[0] = operands[0];
2257    out_operands[1] = operands[2];
2258    out_operands[2] = operands[3];
2259    out_operands[3] = operands[1];
2261    return mcore_output_cmov (out_operands, 1, \"btsti   %3,31\");
2263   [(set_attr "length" "6")])
2265 (define_insn "movt5"
2266   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2267         (if_then_else:SI (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2268                              (const_int 0))
2269                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2270                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2271   ""
2272   "@
2273     btsti       %1,31\;movt     %0,%2
2274     btsti       %1,31\;movf     %0,%3
2275     btsti       %1,31\;clrt     %0
2276     btsti       %1,31\;clrf     %0"
2277   [(set_attr "length" "4")])
2280 ;; ------------------------------------------------------------------------
2281 ;; ge
2282 ;; ------------------------------------------------------------------------
2284 ; experimental conditional move with two constants +/- 1  BRC
2285 (define_insn "movtK_10"
2286   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2287         (if_then_else:SI
2288             (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2289                 (const_int 0))
2290           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2291           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2292   "GET_CODE (operands[2]) == CONST_INT &&
2293    GET_CODE (operands[3]) == CONST_INT &&
2294    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2295     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2296   "*
2298   rtx out_operands[4];
2299   out_operands[0] = operands[0];
2300   out_operands[1] = operands[2];
2301   out_operands[2] = operands[3];
2302   out_operands[3] = operands[1];
2304    return mcore_output_cmov (out_operands, 0, \"btsti   %3,31\");
2306   [(set_attr "length" "6")])
2308 (define_insn "movf5"
2309   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2310         (if_then_else:SI (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2311                              (const_int 0))
2312                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2313                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2314   ""
2315   "@
2316     btsti       %1,31\;movf     %0,%2
2317     btsti       %1,31\;movt     %0,%3
2318     btsti       %1,31\;clrf     %0
2319     btsti       %1,31\;clrt     %0"
2320   [(set_attr "length" "4")])
2322 ;; ------------------------------------------------------------------------
2323 ;; Bitfield extract (xtrbN)
2324 ;; ------------------------------------------------------------------------
2326 ; sometimes we're better off using QI/HI mode and letting the machine indep.
2327 ; part expand insv and extv.
2329 ; e.g., sequences like:a        [an insertion]
2331 ;      ldw r8,(r6)
2332 ;      movi r7,0x00ffffff
2333 ;      and r8,r7                 r7 dead
2334 ;      stw r8,(r6)                r8 dead
2336 ; become:
2338 ;      movi r8,0
2339 ;      stb r8,(r6)              r8 dead
2341 ; it looks like always using SI mode is a win except in this type of code 
2342 ; (when adjacent bit fields collapse on a byte or halfword boundary).  when
2343 ; expanding with SI mode, non-adjacent bit field masks fold, but with QI/HI
2344 ; mode, they do not.  one thought is to add some peepholes to cover cases
2345 ; like the above, but this is not a general solution.
2347 ; -mword-bitfields expands/inserts using SI mode.  otherwise, do it with
2348 ; the smallest mode possible (using the machine indep. expansions).  BRC
2350 ;(define_expand "extv"
2351 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2352 ;       (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2353 ;                        (match_operand:SI 2 "const_int_operand" "")
2354 ;                        (match_operand:SI 3 "const_int_operand" "")))
2355 ;   (clobber (reg:CC 17))]
2356 ;  ""
2357 ;  "
2359 ;  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) % 8 != 0)
2360 ;    {
2361 ;     if (TARGET_W_FIELD)
2362 ;       {
2363 ;        rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2364 ;        rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2366 ;        emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2367 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2368 ;                            gen_rtx_ASHIFT (SImode, operands[0], lshft)));
2369 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2370 ;                            gen_rtx_ASHIFTRT (SImode, operands[0], rshft)));
2371 ;        DONE;
2372 ;     }
2373 ;     else
2374 ;        FAIL;
2375 ;  }
2376 ;}")
2378 (define_expand "extv"
2379   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2380         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2381                          (match_operand:SI 2 "const_int_operand" "")
2382                          (match_operand:SI 3 "const_int_operand" "")))
2383    (clobber (reg:CC 17))]
2384   ""
2385   "
2387   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2388     {
2389        /* 8-bit field, aligned properly, use the xtrb[0123]+sext sequence.  */
2390        /* not DONE, not FAIL, but let the RTL get generated....  */
2391     }
2392   else if (TARGET_W_FIELD)
2393     {
2394       /* Arbitrary placement; note that the tree->rtl generator will make
2395          something close to this if we return FAIL  */
2396       rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2397       rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2398       rtx tmp1 = gen_reg_rtx (SImode);
2399       rtx tmp2 = gen_reg_rtx (SImode);
2401       emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2402       emit_insn (gen_rtx_SET (SImode, tmp2,
2403                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2404       emit_insn (gen_rtx_SET (SImode, operands[0],
2405                          gen_rtx_ASHIFTRT (SImode, tmp2, rshft)));
2406       DONE;
2407     }
2408   else
2409     {
2410       /* Let the caller choose an alternate sequence.  */
2411       FAIL;
2412     }
2415 (define_expand "extzv"
2416   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2417         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2418                          (match_operand:SI 2 "const_int_operand" "")
2419                          (match_operand:SI 3 "const_int_operand" "")))
2420    (clobber (reg:CC 17))]
2421   ""
2422   "
2424   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2425     {
2426        /* 8-bit field, aligned properly, use the xtrb[0123] sequence.  */
2427        /* Let the template generate some RTL....  */
2428     }
2429   else if (CONST_OK_FOR_K ((1 << INTVAL (operands[2])) - 1))
2430     {
2431       /* A narrow bit-field (<=5 bits) means we can do a shift to put
2432          it in place and then use an andi to extract it.
2433          This is as good as a shiftleft/shiftright.  */
2435       rtx shifted;
2436       rtx mask = GEN_INT ((1 << INTVAL (operands[2])) - 1);
2438       if (INTVAL (operands[3]) == 0)
2439         {
2440           shifted = operands[1];
2441         }
2442       else
2443         {
2444           rtx rshft = GEN_INT (INTVAL (operands[3]));
2445           shifted = gen_reg_rtx (SImode);
2446           emit_insn (gen_rtx_SET (SImode, shifted,
2447                          gen_rtx_LSHIFTRT (SImode, operands[1], rshft)));
2448         }
2449      emit_insn (gen_rtx_SET (SImode, operands[0],
2450                        gen_rtx_AND (SImode, shifted, mask)));
2451      DONE;
2452    }
2453  else if (TARGET_W_FIELD)
2454    {
2455      /* Arbitrary pattern; play shift/shift games to get it. 
2456       * this is pretty much what the caller will do if we say FAIL */
2457      rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2458      rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2459      rtx tmp1 = gen_reg_rtx (SImode);
2460      rtx tmp2 = gen_reg_rtx (SImode);
2462      emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2463      emit_insn (gen_rtx_SET (SImode, tmp2,
2464                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2465      emit_insn (gen_rtx_SET (SImode, operands[0],
2466                        gen_rtx_LSHIFTRT (SImode, tmp2, rshft)));
2467      DONE;
2468    }
2469  else
2470    {
2471      /* Make the compiler figure out some alternative mechanism.  */
2472      FAIL;
2473    }
2475  /* Emit the RTL pattern; something will match it later.  */
2478 (define_expand "insv"
2479   [(set (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "")
2480                          (match_operand:SI 1 "const_int_operand" "")
2481                          (match_operand:SI 2 "const_int_operand" ""))
2482         (match_operand:SI 3 "general_operand" ""))
2483    (clobber (reg:CC 17))]
2484   ""
2485   "
2487   if (mcore_expand_insv (operands))
2488     {
2489       DONE;
2490     }
2491   else
2492     {
2493       FAIL;
2494     }
2498 ;; the xtrb[0123] instructions handily get at 8-bit fields on nice boundaries.
2499 ;; but then, they do force you through r1.
2501 ;; the combiner will build such patterns for us, so we'll make them available
2502 ;; for its use.
2504 ;; Note that we have both SIGNED and UNSIGNED versions of these...
2508 ;; These no longer worry about the clobbering of CC bit; not sure this is
2509 ;; good...
2511 ;; the SIGNED versions of these
2513 (define_insn ""
2514   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2515         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2516   ""
2517   "@
2518         asri    %0,24
2519         xtrb0   %0,%1\;sextb    %0"
2520   [(set_attr "type" "shift")])
2522 (define_insn ""
2523   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2524         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2525   ""
2526   "xtrb1        %0,%1\;sextb    %0"
2527   [(set_attr "type" "shift")])
2529 (define_insn ""
2530   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2531         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2532   ""
2533   "xtrb2        %0,%1\;sextb    %0"
2534   [(set_attr "type" "shift")])
2536 (define_insn ""
2537   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2538         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0") (const_int 8) (const_int 0)))]
2539   ""
2540   "sextb        %0"
2541   [(set_attr "type" "shift")])
2543 ;; the UNSIGNED uses of xtrb[0123]
2545 (define_insn ""
2546   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2547         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2548   ""
2549   "@
2550         lsri    %0,24
2551         xtrb0   %0,%1"
2552   [(set_attr "type" "shift")])
2554 (define_insn ""
2555   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2556         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2557   ""
2558   "xtrb1        %0,%1"
2559   [(set_attr "type" "shift")])
2561 (define_insn ""
2562   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2563         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2564   ""
2565   "xtrb2        %0,%1"
2566   [(set_attr "type" "shift")])
2568 ;; This can be peepholed if it follows a ldb ...
2569 (define_insn ""
2570   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2571         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 0)))]
2572   ""
2573   "@
2574         zextb   %0
2575         xtrb3   %0,%1\;zextb    %0"
2576   [(set_attr "type" "shift")])
2579 ;; ------------------------------------------------------------------------
2580 ;; Block move - adapted from m88k.md
2581 ;; ------------------------------------------------------------------------
2583 (define_expand "movmemsi"
2584   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2585                    (mem:BLK (match_operand:BLK 1 "" "")))
2586               (use (match_operand:SI 2 "general_operand" ""))
2587               (use (match_operand:SI 3 "immediate_operand" ""))])]
2588   ""
2589   "
2591   if (mcore_expand_block_move (operands))
2592     DONE;
2593   else
2594     FAIL;
2597 ;; ;;; ??? These patterns are meant to be generated from expand_block_move,
2598 ;; ;;; but they currently are not.
2599 ;; 
2600 ;; (define_insn ""
2601 ;;   [(set (match_operand:QI 0 "mcore_arith_reg_operand" "=r")
2602 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2603 ;;   ""
2604 ;;   "ld.b      %0,%1"
2605 ;;   [(set_attr "type" "load")])
2606 ;; 
2607 ;; (define_insn ""
2608 ;;   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
2609 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2610 ;;   ""
2611 ;;   "ld.h      %0,%1"
2612 ;;   [(set_attr "type" "load")])
2613 ;; 
2614 ;; (define_insn ""
2615 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2616 ;;      (match_operand:BLK 1 "mcore_general_movsrc_operand" "m"))]
2617 ;;   ""
2618 ;;   "ld.w      %0,%1"
2619 ;;   [(set_attr "type" "load")])
2620 ;; 
2621 ;; (define_insn ""
2622 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2623 ;;      (match_operand:QI 1 "mcore_arith_reg_operand" "r"))]
2624 ;;   ""
2625 ;;   "st.b      %1,%0"
2626 ;;   [(set_attr "type" "store")])
2627 ;; 
2628 ;; (define_insn ""
2629 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2630 ;;      (match_operand:HI 1 "mcore_arith_reg_operand" "r"))]
2631 ;;   ""
2632 ;;   "st.h      %1,%0"
2633 ;;   [(set_attr "type" "store")])
2634 ;; 
2635 ;; (define_insn ""
2636 ;;   [(set (match_operand:BLK 0 "mcore_general_movdst_operand" "=m")
2637 ;;      (match_operand:SI 1 "mcore_arith_reg_operand" "r"))]
2638 ;;   ""
2639 ;;   "st.w      %1,%0"
2640 ;;   [(set_attr "type" "store")])
2642 ;; ------------------------------------------------------------------------
2643 ;; Misc Optimizing quirks
2644 ;; ------------------------------------------------------------------------
2646 ;; pair to catch constructs like:  (int *)((p+=4)-4) which happen
2647 ;; in stdarg/varargs traversal. This changes a 3 insn sequence to a 2
2648 ;; insn sequence. -- RBE 11/30/95
2649 (define_insn ""
2650   [(parallel[
2651       (set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2652            (match_operand:SI 1 "mcore_arith_reg_operand" "+r"))
2653       (set (match_dup 1) (plus:SI (match_dup 1) (match_operand 2 "mcore_arith_any_imm_operand" "")))])]
2654   "GET_CODE(operands[2]) == CONST_INT"
2655   "#"
2656   [(set_attr "length" "4")])
2658 (define_split 
2659   [(parallel[
2660       (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2661            (match_operand:SI 1 "mcore_arith_reg_operand" ""))
2662       (set (match_dup 1) (plus:SI (match_dup 1) (match_operand 2 "mcore_arith_any_imm_operand" "")))])]
2663   "GET_CODE(operands[2]) == CONST_INT &&
2664    operands[0] != operands[1]"
2665   [(set (match_dup 0) (match_dup 1))
2666    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))])
2669 ;;; Peepholes
2671 ; note: in the following patterns, use mcore_is_dead() to ensure that the
2672 ; reg we may be trashing really is dead.  reload doesn't always mark
2673 ; deaths, so mcore_is_dead() (see mcore.c) scans forward to find its death.  BRC
2675 ;;; A peephole to convert the 3 instruction sequence generated by reload
2676 ;;; to load a FP-offset address into a 2 instruction sequence.
2677 ;;; ??? This probably never matches anymore.
2678 (define_peephole
2679   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2680         (match_operand:SI 1 "const_int_operand" "J"))
2681    (set (match_dup 0) (neg:SI (match_dup 0)))
2682    (set (match_dup 0)
2683         (plus:SI (match_dup 0)
2684                  (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
2685   "CONST_OK_FOR_J (INTVAL (operands[1]))"
2686   "error\;mov   %0,%2\;subi     %0,%1")
2688 ;; Moves of inlinable constants are done late, so when a 'not' is generated
2689 ;; it is never combined with the following 'and' to generate an 'andn' b/c 
2690 ;; the combiner never sees it.  use a peephole to pick up this case (happens
2691 ;; mostly with bitfields)  BRC
2693 (define_peephole
2694   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2695         (match_operand:SI 1 "const_int_operand" "i"))
2696    (set (match_operand:SI 2 "mcore_arith_reg_operand" "r")
2697         (and:SI (match_dup 2) (match_dup 0)))]
2698   "mcore_const_trick_uses_not (INTVAL (operands[1])) &&
2699         operands[0] != operands[2] &&
2700         mcore_is_dead (insn, operands[0])"
2701   "* return mcore_output_andn (insn, operands);")
2703 ; when setting or clearing just two bits, it's cheapest to use two bseti's 
2704 ; or bclri's.  only happens when relaxing immediates.  BRC
2706 (define_peephole
2707   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2708         (match_operand:SI 1 "const_int_operand" ""))
2709    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2710         (ior:SI (match_dup 2) (match_dup 0)))]
2711   "TARGET_HARDLIT
2712    && mcore_num_ones (INTVAL (operands[1])) == 2
2713    && mcore_is_dead (insn, operands[0])"
2714   "* return mcore_output_bseti (operands[2], INTVAL (operands[1]));")
2716 (define_peephole
2717   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2718         (match_operand:SI 1 "const_int_operand" ""))
2719    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2720         (and:SI (match_dup 2) (match_dup 0)))]
2721   "TARGET_HARDLIT && mcore_num_zeros (INTVAL (operands[1])) == 2 &&
2722        mcore_is_dead (insn, operands[0])"
2723   "* return mcore_output_bclri (operands[2], INTVAL (operands[1]));")
2725 ; change an and with a mask that has a single cleared bit into a bclri.  this
2726 ; handles QI and HI mode values using the knowledge that the most significant
2727 ; bits don't matter.
2729 (define_peephole
2730   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2731         (match_operand:SI 1 "const_int_operand" ""))
2732    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2733         (and:SI (match_operand:SI 3 "mcore_arith_reg_operand" "")
2734                 (match_dup 0)))]
2735   "GET_CODE (operands[3]) == SUBREG && 
2736       GET_MODE (SUBREG_REG (operands[3])) == QImode &&
2737       mcore_num_zeros (INTVAL (operands[1]) | 0xffffff00) == 1 &&
2738       mcore_is_dead (insn, operands[0])"
2740   if (! mcore_is_same_reg (operands[2], operands[3]))
2741     output_asm_insn (\"mov\\t%2,%3\", operands);
2742   return mcore_output_bclri (operands[2], INTVAL (operands[1]) | 0xffffff00);")
2744 /* Do not fold these together -- mode is lost at final output phase.  */
2746 (define_peephole
2747   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2748         (match_operand:SI 1 "const_int_operand" ""))
2749    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2750         (and:SI (match_operand:SI 3 "mcore_arith_reg_operand" "")
2751                 (match_dup 0)))]
2752   "GET_CODE (operands[3]) == SUBREG && 
2753       GET_MODE (SUBREG_REG (operands[3])) == HImode &&
2754       mcore_num_zeros (INTVAL (operands[1]) | 0xffff0000) == 1 &&
2755       operands[2] == operands[3] &&
2756       mcore_is_dead (insn, operands[0])"
2758   if (! mcore_is_same_reg (operands[2], operands[3]))
2759     output_asm_insn (\"mov\\t%2,%3\", operands);
2760   return mcore_output_bclri (operands[2], INTVAL (operands[1]) | 0xffff0000);")
2762 ; This peephole helps when using -mwide-bitfields to widen fields so they 
2763 ; collapse.   This, however, has the effect that a narrower mode is not used
2764 ; when desirable.  
2766 ; e.g., sequences like:
2768 ;      ldw r8,(r6)
2769 ;      movi r7,0x00ffffff
2770 ;      and r8,r7                 r7 dead
2771 ;      stw r8,(r6)                r8 dead
2773 ; get peepholed to become:
2775 ;      movi r8,0
2776 ;      stb r8,(r6)              r8 dead
2778 ; Do only easy addresses that have no offset.  This peephole is also applied 
2779 ; to halfwords.  We need to check that the load is non-volatile before we get
2780 ; rid of it.
2782 (define_peephole
2783   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2784         (match_operand:SI 1 "memory_operand" ""))
2785    (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2786         (match_operand:SI 3 "const_int_operand" ""))
2787    (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
2788    (set (match_operand:SI 4 "memory_operand" "") (match_dup 0))]
2789   "mcore_is_dead (insn, operands[0]) &&
2790    ! MEM_VOLATILE_P (operands[1]) &&
2791    mcore_is_dead (insn, operands[2]) && 
2792    (mcore_byte_offset (INTVAL (operands[3])) > -1 || 
2793     mcore_halfword_offset (INTVAL (operands[3])) > -1) &&
2794    ! MEM_VOLATILE_P (operands[4]) &&
2795    GET_CODE (XEXP (operands[4], 0)) == REG"
2798    int ofs;
2799    enum machine_mode mode;
2800    rtx base_reg = XEXP (operands[4], 0);
2802    if ((ofs = mcore_byte_offset (INTVAL (operands[3]))) > -1)
2803       mode = QImode;
2804    else if ((ofs = mcore_halfword_offset (INTVAL (operands[3]))) > -1)
2805       mode = HImode;
2806    else
2807       gcc_unreachable ();
2809    if (ofs > 0) 
2810       operands[4] = gen_rtx_MEM (mode, 
2811                               gen_rtx_PLUS (SImode, base_reg, GEN_INT(ofs)));
2812    else
2813       operands[4] = gen_rtx_MEM (mode, base_reg);
2815    if (mode == QImode)
2816       return \"movi     %0,0\\n\\tst.b  %0,%4\";
2818    return \"movi        %0,0\\n\\tst.h  %0,%4\";
2821 ; from sop11. get btsti's for (LT A 0) where A is a QI or HI value
2823 (define_peephole
2824   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2825         (sign_extend:SI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))
2826    (set (reg:CC 17)
2827         (lt:CC (match_dup 0)
2828             (const_int 0)))]
2829   "mcore_is_dead (insn, operands[0])"
2830   "btsti        %0,7")
2832 (define_peephole
2833   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2834         (sign_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "0")))
2835    (set (reg:CC 17)
2836         (lt:CC (match_dup 0)
2837             (const_int 0)))]
2838   "mcore_is_dead (insn, operands[0])"
2839   "btsti        %0,15")
2841 ; Pick up a tst.  This combination happens because the immediate is not
2842 ; allowed to fold into one of the operands of the tst.  Does not happen
2843 ; when relaxing immediates.  BRC
2845 (define_peephole
2846   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2847         (match_operand:SI 1 "mcore_arith_reg_operand" ""))
2848    (set (match_dup 0)
2849         (and:SI (match_dup 0)
2850                 (match_operand:SI 2 "mcore_literal_K_operand" "")))
2851    (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))]
2852   "mcore_is_dead (insn, operands[0])"
2853   "movi %0,%2\;tst      %1,%0")
2855 (define_peephole
2856   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2857         (if_then_else:SI (ne (zero_extract:SI 
2858                                 (match_operand:SI 1 "mcore_arith_reg_operand" "")
2859                                 (const_int 1)
2860                                 (match_operand:SI 2 "mcore_literal_K_operand" ""))
2861                              (const_int 0))
2862            (match_operand:SI 3 "mcore_arith_imm_operand" "")
2863            (match_operand:SI 4 "mcore_arith_imm_operand" "")))
2864     (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))]
2865   ""
2868   unsigned int op0 = REGNO (operands[0]);
2870   if (GET_CODE (operands[3]) == REG)
2871     {
2872      if (REGNO (operands[3]) == op0 && GET_CODE (operands[4]) == CONST_INT
2873          && INTVAL (operands[4]) == 0)
2874         return \"btsti  %1,%2\\n\\tclrf %0\";
2875      else if (GET_CODE (operands[4]) == REG)
2876        {
2877         if (REGNO (operands[4]) == op0)
2878            return \"btsti       %1,%2\\n\\tmovf %0,%3\";
2879         else if (REGNO (operands[3]) == op0)
2880            return \"btsti       %1,%2\\n\\tmovt %0,%4\";
2881        }
2883      gcc_unreachable ();
2884     }
2885   else if (GET_CODE (operands[3]) == CONST_INT
2886            && INTVAL (operands[3]) == 0
2887            && GET_CODE (operands[4]) == REG)
2888      return \"btsti     %1,%2\\n\\tclrt %0\";
2890   gcc_unreachable ();
2893 ; experimental - do the constant folding ourselves.  note that this isn't
2894 ;   re-applied like we'd really want.  i.e., four ands collapse into two
2895 ;   instead of one.  this is because peepholes are applied as a sliding
2896 ;   window.  the peephole does not generate new rtl's, but instead slides
2897 ;   across the rtl's generating machine instructions.  it would be nice
2898 ;   if the peephole optimizer is changed to re-apply patterns and to gen
2899 ;   new rtl's.  this is more flexible.  the pattern below helps when we're
2900 ;   not using relaxed immediates.   BRC
2902 ;(define_peephole
2903 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2904 ;        (match_operand:SI 1 "const_int_operand" ""))
2905 ;   (set (match_operand:SI 2 "mcore_arith_reg_operand" "")
2906 ;          (and:SI (match_dup 2) (match_dup 0)))
2907 ;   (set (match_dup 0)
2908 ;        (match_operand:SI 3 "const_int_operand" ""))
2909 ;   (set (match_dup 2)
2910 ;           (and:SI (match_dup 2) (match_dup 0)))]
2911 ;  "!TARGET_RELAX_IMM && mcore_is_dead (insn, operands[0]) &&
2912 ;       mcore_const_ok_for_inline (INTVAL (operands[1]) & INTVAL (operands[3]))"
2913 ;  "*
2915 ;  rtx out_operands[2];
2916 ;  out_operands[0] = operands[0];
2917 ;  out_operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[3]));
2918 ;  
2919 ;  output_inline_const (SImode, out_operands);
2921 ;  output_asm_insn (\"and       %2,%0\", operands);
2923 ;  return \"\";   
2924 ;}")
2926 ; BRC: for inlining get rid of extra test - experimental
2927 ;(define_peephole
2928 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "r")
2929 ;          (ne:SI (reg:CC 17) (const_int 0)))
2930 ;   (set (reg:CC 17) (ne:CC (match_dup 0) (const_int 0)))
2931 ;   (set (pc) 
2932 ;       (if_then_else (eq (reg:CC 17) (const_int 0))
2933 ;         (label_ref (match_operand 1 "" ""))
2934 ;         (pc)))]
2935 ;   ""
2936 ;   "*
2938 ;  if (get_attr_length (insn) == 10)
2939 ;    {
2940 ;      output_asm_insn (\"bt    2f\\n\\tjmpi    [1f]\", operands);
2941 ;      output_asm_insn (\".align        2\\n1:\", operands);
2942 ;      output_asm_insn (\".long %1\\n2:\", operands);
2943 ;      return \"\";
2944 ;    }
2945 ;  return \"bf  %l1\";
2946 ;}")
2949 ;;; Special patterns for dealing with the constant pool.
2951 ;;; 4 byte integer in line.
2953 (define_insn "consttable_4"
2954  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 0)]
2955  ""
2956  "*
2958   assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
2959   return \"\";
2961  [(set_attr "length" "4")])
2963 ;;; align to a four byte boundary.
2965 (define_insn "align_4"
2966  [(unspec_volatile [(const_int 0)] 1)]
2967  ""
2968  ".align 2")
2970 ;;; Handle extra constant pool entries created during final pass.
2972 (define_insn "consttable_end"
2973   [(unspec_volatile [(const_int 0)] 2)]
2974   ""
2975   "* return mcore_output_jump_label_table ();")
2978 ;; Stack allocation -- in particular, for alloca().
2979 ;; this is *not* what we use for entry into functions.
2981 ;; This is how we allocate stack space.  If we are allocating a
2982 ;; constant amount of space and we know it is less than 4096
2983 ;; bytes, we need do nothing.
2985 ;; If it is more than 4096 bytes, we need to probe the stack
2986 ;; periodically. 
2988 ;; operands[1], the distance is a POSITIVE number indicating that we
2989 ;; are allocating stack space
2991 (define_expand "allocate_stack"
2992   [(set (reg:SI 0)
2993         (plus:SI (reg:SI 0)
2994                  (match_operand:SI 1 "general_operand" "")))
2995    (set (match_operand:SI 0 "register_operand" "=r")
2996         (match_dup 2))]
2997   ""
2998   "
3000   /* If he wants no probing, just do it for him.  */
3001   if (mcore_stack_increment == 0)
3002     {
3003       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,operands[1]));
3004 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3005       DONE;
3006     }
3008   /* For small constant growth, we unroll the code.  */
3009   if (GET_CODE (operands[1]) == CONST_INT
3010       && INTVAL (operands[1]) < 8 * STACK_UNITS_MAXSTEP)
3011     {
3012       HOST_WIDE_INT left = INTVAL(operands[1]);
3014       /* If it's a long way, get close enough for a last shot.  */
3015       if (left >= STACK_UNITS_MAXSTEP)
3016         {
3017           rtx tmp = gen_reg_rtx (Pmode);
3018           emit_insn (gen_movsi (tmp, GEN_INT (STACK_UNITS_MAXSTEP)));
3019           do
3020             {
3021               rtx memref = gen_rtx_MEM (SImode, stack_pointer_rtx);
3023               MEM_VOLATILE_P (memref) = 1;
3024               emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3025               emit_insn (gen_movsi (memref, stack_pointer_rtx));
3026               left -= STACK_UNITS_MAXSTEP;
3027             }
3028           while (left > STACK_UNITS_MAXSTEP);
3029         }
3030       /* Perform the final adjustment.  */
3031       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-left)));
3032 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3033       DONE;
3034     }
3035   else
3036     {
3037       rtx out_label = 0;
3038       rtx loop_label = gen_label_rtx ();
3039       rtx step = gen_reg_rtx (Pmode);
3040       rtx tmp = gen_reg_rtx (Pmode);
3041       rtx test, memref;
3043 #if 1
3044       emit_insn (gen_movsi (tmp, operands[1]));
3045       emit_insn (gen_movsi (step, GEN_INT (STACK_UNITS_MAXSTEP)));
3047       if (GET_CODE (operands[1]) != CONST_INT)
3048         {
3049           out_label = gen_label_rtx ();
3050           test = gen_rtx_GEU (VOIDmode, step, tmp);             /* quick out */
3051           emit_jump_insn (gen_cbranchsi4 (test, step, tmp, out_label));
3052         }
3054       /* Run a loop that steps it incrementally.  */
3055       emit_label (loop_label);
3057       /* Extend a step, probe, and adjust remaining count.  */
3058       emit_insn(gen_subsi3(stack_pointer_rtx, stack_pointer_rtx, step));
3059       memref = gen_rtx_MEM (SImode, stack_pointer_rtx);
3060       MEM_VOLATILE_P (memref) = 1;
3061       emit_insn(gen_movsi(memref, stack_pointer_rtx));
3062       emit_insn(gen_subsi3(tmp, tmp, step));
3064       /* Loop condition -- going back up.  */
3065       test = gen_rtx_LTU (VOIDmode, step, tmp);
3066       emit_jump_insn (gen_cbranchsi4 (test, step, tmp, loop_label));
3068       if (out_label)
3069         emit_label (out_label);
3071       /* Bump the residual.  */
3072       emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3073 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3074       DONE;
3075 #else
3076       /* simple one-shot -- ensure register and do a subtract.
3077        * This does NOT comply with the ABI.  */
3078       emit_insn (gen_movsi (tmp, operands[1]));
3079       emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
3080 ;;      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
3081       DONE;
3082 #endif
3083     }