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