PR target/16201
[official-gcc.git] / gcc / config / mcore / mcore.md
blobab3ce8aff689043539a986937b1914ab0695e1eb
1 ;;  Machine description the Motorola MCore
2 ;;  Copyright (C) 1993, 1999, 2000, 2004 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 ;; Scheduling.  We only model a simple load latency.
49 (define_insn_reservation "any_insn" 1
50                          (eq_attr "type" "!load")
51                          "nothing")
52 (define_insn_reservation "memory" 2
53                          (eq_attr "type" "load")
54                          "nothing")
56 ;; -------------------------------------------------------------------------
57 ;; Test and bit test
58 ;; -------------------------------------------------------------------------
60 (define_insn ""
61   [(set (reg:SI 17) 
62         (sign_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
63                          (const_int 1)
64                          (match_operand:SI 1 "mcore_literal_K_operand" "K")))]
65   ""
66   "btsti        %0,%1"
67   [(set_attr "type" "shift")])
69 (define_insn ""
70   [(set (reg:SI 17) 
71         (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
72                          (const_int 1)
73                          (match_operand:SI 1 "mcore_literal_K_operand" "K")))]
74   ""
75   "btsti        %0,%1"
76   [(set_attr "type" "shift")])
78 ;;; This is created by combine.
79 (define_insn ""
80   [(set (reg:CC 17)
81         (ne:CC (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
82                                 (const_int 1)
83                                 (match_operand:SI 1 "mcore_literal_K_operand" "K"))
84                (const_int 0)))]
85   ""
86   "btsti        %0,%1"
87   [(set_attr "type" "shift")])
90 ;; Created by combine from conditional patterns below (see sextb/btsti rx,31)
92 (define_insn ""
93   [(set (reg:CC 17)
94         (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
95                             (const_int 7))
96                (const_int 0)))]
97   "GET_CODE(operands[0]) == SUBREG && 
98       GET_MODE(SUBREG_REG(operands[0])) == QImode"
99   "btsti        %0,7"
100   [(set_attr "type" "shift")])
102 (define_insn ""
103   [(set (reg:CC 17)
104         (ne:CC (lshiftrt:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
105                             (const_int 15))
106                (const_int 0)))]
107   "GET_CODE(operands[0]) == SUBREG && 
108       GET_MODE(SUBREG_REG(operands[0])) == HImode"
109   "btsti        %0,15"
110   [(set_attr "type" "shift")])
112 (define_split
113   [(set (pc)
114         (if_then_else (ne (eq:CC (zero_extract:SI
115                                   (match_operand:SI 0 "mcore_arith_reg_operand" "")
116                                   (const_int 1)
117                                   (match_operand:SI 1 "mcore_literal_K_operand" ""))
118                                  (const_int 0))
119                           (const_int 0))
120                       (label_ref (match_operand 2 "" ""))
121                       (pc)))]
122   ""
123   [(set (reg:CC 17)
124         (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))
125    (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
126                            (label_ref (match_dup 2))
127                            (pc)))]
128   "")
130 (define_split
131   [(set (pc)
132         (if_then_else (eq (ne:CC (zero_extract:SI
133                                   (match_operand:SI 0 "mcore_arith_reg_operand" "")
134                                   (const_int 1)
135                                   (match_operand:SI 1 "mcore_literal_K_operand" ""))
136                                  (const_int 0))
137                           (const_int 0))
138                       (label_ref (match_operand 2 "" ""))
139                       (pc)))]
140   ""
141   [(set (reg:CC 17)
142         (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))
143    (set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
144                            (label_ref (match_dup 2))
145                            (pc)))]
146   "")
148 ;; XXX - disabled by nickc because it fails on libiberty/fnmatch.c
150 ;; ; Experimental - relax immediates for and, andn, or, and tst to allow
151 ;; ;    any immediate value (or an immediate at all -- or, andn, & tst).  
152 ;; ;    This is done to allow bit field masks to fold together in combine.
153 ;; ;    The reload phase will force the immediate into a register at the
154 ;; ;    very end.  This helps in some cases, but hurts in others: we'd
155 ;; ;    really like to cse these immediates.  However, there is a phase
156 ;; ;    ordering problem here.  cse picks up individual masks and cse's
157 ;; ;    those, but not folded masks (cse happens before combine).  It's
158 ;; ;    not clear what the best solution is because we really want cse
159 ;; ;    before combine (leaving the bit field masks alone).   To pick up
160 ;; ;    relaxed immediates use -mrelax-immediates.  It might take some
161 ;; ;    experimenting to see which does better (i.e. regular imms vs.
162 ;; ;    arbitrary imms) for a particular code.   BRC
163 ;; 
164 ;; (define_insn ""
165 ;;   [(set (reg:CC 17)
166 ;;      (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
167 ;;                     (match_operand:SI 1 "mcore_arith_any_imm_operand" "rI"))
168 ;;             (const_int 0)))]
169 ;;   "TARGET_RELAX_IMM"
170 ;;   "tst       %0,%1")
171 ;; 
172 ;; (define_insn ""
173 ;;   [(set (reg:CC 17)
174 ;;      (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
175 ;;                     (match_operand:SI 1 "mcore_arith_M_operand" "r"))
176 ;;             (const_int 0)))]
177 ;;   "!TARGET_RELAX_IMM"
178 ;;   "tst       %0,%1")
180 (define_insn ""
181   [(set (reg:CC 17)
182         (ne:CC (and:SI (match_operand:SI 0 "mcore_arith_reg_operand" "r")
183                        (match_operand:SI 1 "mcore_arith_M_operand" "r"))
184                (const_int 0)))]
185   ""
186   "tst  %0,%1")
189 (define_split 
190   [(parallel[
191       (set (reg:CC 17)
192            (ne:CC (ne:SI (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
193                                  (match_operand:SI 1 "mcore_arith_reg_operand" "r"))
194                          (const_int 0))
195                   (const_int 0)))
196       (clobber (match_operand:CC 2 "mcore_arith_reg_operand" "=r"))])]
197   ""
198   [(set (reg:CC 17) (ne:SI (match_dup 0) (const_int 0)))
199    (set (reg:CC 17) (leu:CC (match_dup 0) (match_dup 1)))])
201 ;; -------------------------------------------------------------------------
202 ;; SImode signed integer comparisons
203 ;; -------------------------------------------------------------------------
205 (define_insn "decne_t"
206   [(set (reg:CC 17) (ne:CC (plus:SI (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
207                                     (const_int -1))               
208                            (const_int 0)))
209    (set (match_dup 0)
210         (plus:SI (match_dup 0)
211                  (const_int -1)))]
212   ""
213   "decne        %0")
215 ;; The combiner seems to prefer the following to the former.
217 (define_insn ""
218   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
219                            (const_int 1)))
220    (set (match_dup 0)
221         (plus:SI (match_dup 0)
222                  (const_int -1)))]
223   ""
224   "decne        %0")
226 (define_insn "cmpnesi_t"
227   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
228                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
229   ""
230   "cmpne        %0,%1")
232 (define_insn "cmpneisi_t"
233   [(set (reg:CC 17) (ne:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
234                            (match_operand:SI 1 "mcore_arith_K_operand" "K")))]
235   ""
236   "cmpnei       %0,%1")
238 (define_insn "cmpgtsi_t"
239   [(set (reg:CC 17) (gt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
240                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
241   ""
242   "cmplt        %1,%0")
244 (define_insn ""
245   [(set (reg:CC 17) (gt:CC (plus:SI
246                             (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
247                             (const_int -1))
248                            (const_int 0)))
249    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
250   ""
251   "decgt        %0")
253 (define_insn "cmpltsi_t"
254   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
255                            (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
256   ""
257   "cmplt        %0,%1")
259 ; cmplti is 1-32
260 (define_insn "cmpltisi_t"
261   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
262                            (match_operand:SI 1 "mcore_arith_J_operand" "J")))]
263   ""
264   "cmplti       %0,%1")
266 ; covers cmplti x,0
267 (define_insn ""
268   [(set (reg:CC 17) (lt:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
269                          (const_int 0)))]
270   ""
271   "btsti        %0,31")
273 (define_insn ""
274   [(set (reg:CC 17) (lt:CC (plus:SI
275                             (match_operand:SI 0 "mcore_arith_reg_operand" "+r")
276                             (const_int -1))
277                            (const_int 0)))
278    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
279   ""
280   "declt        %0")
282 ;; -------------------------------------------------------------------------
283 ;; SImode unsigned integer comparisons
284 ;; -------------------------------------------------------------------------
286 (define_insn "cmpgeusi_t"
287   [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
288                             (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
289   ""
290   "cmphs        %0,%1")
292 (define_insn "cmpgeusi_0"
293   [(set (reg:CC 17) (geu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
294                             (const_int 0)))]
295   ""
296   "cmpnei       %0, 0")
298 (define_insn "cmpleusi_t"
299   [(set (reg:CC 17) (leu:CC (match_operand:SI 0 "mcore_arith_reg_operand" "r")
300                             (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
301   ""
302   "cmphs        %1,%0")
304 ;; We save the compare operands in the cmpxx patterns and use them when
305 ;; we generate the branch.
307 ;; We accept constants here, in case we can modify them to ones which
308 ;; are more efficient to load.  E.g. change 'x <= 62' to 'x < 63'.
310 (define_expand "cmpsi"
311   [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "")
312                                 (match_operand:SI 1 "nonmemory_operand" "")))]
313   ""
314   "
315 { arch_compare_op0 = operands[0];
316   arch_compare_op1 = operands[1];
317   DONE;
320 ;; -------------------------------------------------------------------------
321 ;; Logical operations
322 ;; -------------------------------------------------------------------------
324 ;; Logical AND clearing a single bit.  andsi3 knows that we have this
325 ;; pattern and allows the constant literal pass through.
328 ;; RBE 2/97: don't need this pattern any longer...
329 ;; RBE: I don't think we need both "S" and exact_log2() clauses.
330 ;;(define_insn ""
331 ;;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
332 ;;      (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
333 ;;              (match_operand:SI 2 "const_int_operand" "S")))]
334 ;;  "mcore_arith_S_operand (operands[2])"
335 ;;  "bclri      %0,%Q2")
338 (define_insn "andnsi3"
339   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
340         (and:SI (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))
341                 (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
342   ""
343   "andn %0,%1")
345 (define_expand "andsi3"
346   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
347         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
348                 (match_operand:SI 2 "nonmemory_operand" "")))]
349   ""
350   "
352   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0
353       && ! mcore_arith_S_operand (operands[2]))
354     {
355       int not_value = ~ INTVAL (operands[2]);
356       if (   CONST_OK_FOR_I (not_value)
357           || CONST_OK_FOR_M (not_value)
358           || CONST_OK_FOR_N (not_value))
359         {
360           operands[2] = copy_to_mode_reg (SImode, GEN_INT (not_value));
361           emit_insn (gen_andnsi3 (operands[0], operands[2], operands[1]));
362           DONE;
363         }
364     }
366   if (! mcore_arith_K_S_operand (operands[2], SImode))
367     operands[2] = copy_to_mode_reg (SImode, operands[2]);
370 (define_insn ""
371   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
372         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0")
373                 (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,K,0,S")))]
374   "TARGET_RELAX_IMM"
375   "*
377    switch (which_alternative)
378      {
379      case 0: return \"and       %0,%2\";
380      case 1: return \"andi      %0,%2\";
381      case 2: return \"and       %0,%1\";
382      /* case -1: return \"bclri %0,%Q2\";        will not happen */
383      case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2]));
384      default: abort ();
385      }
388 ;; This was the old "S" which was "!(2^n)" */
389 ;; case -1: return \"bclri      %0,%Q2\";        will not happen */
391 (define_insn ""
392   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
393         (and:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r,0")
394                 (match_operand:SI 2 "mcore_arith_K_S_operand" "r,K,0,S")))]
395   "!TARGET_RELAX_IMM"
396   "*
398    switch (which_alternative)
399      {
400      case 0: return \"and       %0,%2\";
401      case 1: return \"andi      %0,%2\";
402      case 2: return \"and       %0,%1\";
403      case 3: return mcore_output_bclri (operands[0], INTVAL (operands[2]));
404      default: abort ();
405      }
408 ;(define_insn "iorsi3"
409 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
410 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
411 ;               (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
412 ;  ""
413 ;  "or  %0,%2")
415 ; need an expand to resolve ambiguity betw. the two iors below.
416 (define_expand "iorsi3"
417   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
418         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
419                 (match_operand:SI 2 "nonmemory_operand" "")))]
420   ""
421   "
423    if (! mcore_arith_M_operand (operands[2], SImode))
424       operands[2] = copy_to_mode_reg (SImode, operands[2]);
427 (define_insn ""
428   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
429         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
430                 (match_operand:SI 2 "mcore_arith_any_imm_operand" "r,M,T")))]
431   "TARGET_RELAX_IMM"
432   "*
434    switch (which_alternative)
435      {
436      case 0: return \"or        %0,%2\";
437      case 1: return \"bseti     %0,%P2\";
438      case 2: return mcore_output_bseti (operands[0], INTVAL (operands[2]));
439      default: abort ();
440      }
443 (define_insn ""
444   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
445         (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
446                 (match_operand:SI 2 "mcore_arith_M_operand" "r,M,T")))]
447   "!TARGET_RELAX_IMM"
448   "*
450    switch (which_alternative)
451      {
452      case 0: return \"or        %0,%2\";
453      case 1: return \"bseti     %0,%P2\";
454      case 2: return mcore_output_bseti (operands[0], INTVAL (operands[2]));
455      default: abort ();
456      }
459 ;(define_insn ""
460 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
461 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
462 ;               (match_operand:SI 2 "const_int_operand" "M")))]
463 ;  "exact_log2 (INTVAL (operands[2])) >= 0"
464 ;  "bseti       %0,%P2")
466 ;(define_insn ""
467 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
468 ;       (ior:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
469 ;               (match_operand:SI 2 "const_int_operand" "i")))]
470 ;  "mcore_num_ones (INTVAL (operands[2])) < 3"
471 ;  "* return mcore_output_bseti (operands[0], INTVAL (operands[2]));")
473 (define_insn "xorsi3"
474   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
475         (xor:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
476                 (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
477   ""
478   "xor  %0,%2")
480 ; these patterns give better code then gcc invents if
481 ; left to its own devices
483 (define_insn "anddi3"
484   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
485         (and:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
486                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
487   ""
488   "and  %0,%2\;and      %R0,%R2"
489   [(set_attr "length" "4")])
491 (define_insn "iordi3"
492   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
493         (ior:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
494                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
495   ""
496   "or   %0,%2\;or       %R0,%R2"
497   [(set_attr "length" "4")])
499 (define_insn "xordi3"
500   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
501         (xor:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
502                 (match_operand:DI 2 "mcore_arith_reg_operand" "r")))]
503   ""
504   "xor  %0,%2\;xor      %R0,%R2"
505   [(set_attr "length" "4")])
507 ;; -------------------------------------------------------------------------
508 ;; Shifts and rotates
509 ;; -------------------------------------------------------------------------
511 ;; Only allow these if the shift count is a convenient constant.
512 (define_expand "rotlsi3"
513   [(set (match_operand:SI            0 "mcore_arith_reg_operand" "")
514         (rotate:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
515                    (match_operand:SI 2 "nonmemory_operand" "")))]
516   ""
517   "if (! mcore_literal_K_operand (operands[2], SImode))
518          FAIL;
519   ")
521 ;; We can only do constant rotates, which is what this pattern provides.
522 ;; The combiner will put it together for us when we do:
523 ;;      (x << N) | (x >> (32 - N))
524 (define_insn ""
525   [(set (match_operand:SI              0 "mcore_arith_reg_operand" "=r")
526         (rotate:SI (match_operand:SI   1 "mcore_arith_reg_operand"  "0")
527                      (match_operand:SI 2 "mcore_literal_K_operand"  "K")))]
528   ""
529   "rotli        %0,%2"
530   [(set_attr "type" "shift")])
532 (define_insn "ashlsi3"
533   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
534         (ashift:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
535                    (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
536   ""
537   "@
538         lsl     %0,%2
539         lsli    %0,%2"
540   [(set_attr "type" "shift")])
542 (define_insn ""
543   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
544         (ashift:SI (const_int 1)
545                    (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
546   ""
547   "bgenr        %0,%1"
548   [(set_attr "type" "shift")])
550 (define_insn "ashrsi3"
551   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
552         (ashiftrt:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
553                      (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
554   ""
555   "@
556         asr     %0,%2
557         asri    %0,%2"
558   [(set_attr "type" "shift")])
560 (define_insn "lshrsi3"
561   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
562         (lshiftrt:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0")
563                      (match_operand:SI 2 "mcore_arith_K_operand_not_0" "r,K")))]
564   ""
565   "@
566         lsr     %0,%2
567         lsri    %0,%2"
568   [(set_attr "type" "shift")])
570 ;(define_expand "ashldi3"
571 ;  [(parallel[(set (match_operand:DI 0 "mcore_arith_reg_operand" "")
572 ;                 (ashift:DI (match_operand:DI 1 "mcore_arith_reg_operand" "")
573 ;                            (match_operand:DI 2 "immediate_operand" "")))
575 ;            (clobber (reg:CC 17))])]
576 ;           
577 ;  ""
578 ;  "
580 ;  if (GET_CODE (operands[2]) != CONST_INT
581 ;      || INTVAL (operands[2]) != 1)
582 ;    FAIL;
583 ;}")
585 ;(define_insn ""
586 ;  [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r")
587 ;       (ashift:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
588 ;                    (const_int 1)))
589 ;   (clobber (reg:CC 17))]
590 ;  ""
591 ;  "lsli        %R0,0\;rotli    %0,0"
592 ;  [(set_attr "length" "4") (set_attr "type" "shift")])
594 ;; -------------------------------------------------------------------------
595 ;; Index instructions
596 ;; -------------------------------------------------------------------------
597 ;; The second of each set of patterns is borrowed from the alpha.md file.
598 ;; These variants of the above insns can occur if the second operand
599 ;; is the frame pointer.  This is a kludge, but there doesn't
600 ;; seem to be a way around it.  Only recognize them while reloading.
602 ;; We must use reload_operand for some operands in case frame pointer
603 ;; elimination put a MEM with invalid address there.  Otherwise,
604 ;; the result of the substitution will not match this pattern, and reload
605 ;; will not be able to correctly fix the result.
607 ;; indexing longlongs or doubles (8 bytes)
609 (define_insn "indexdi_t"
610   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
611         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
612                           (const_int 8))
613                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
614   ""
615   "*
616     if (! mcore_is_same_reg (operands[1], operands[2]))
617       {
618         output_asm_insn (\"ixw\\t%0,%1\", operands);
619         output_asm_insn (\"ixw\\t%0,%1\", operands);
620       }
621     else
622       {
623         output_asm_insn (\"ixh\\t%0,%1\", operands);
624         output_asm_insn (\"ixh\\t%0,%1\", operands);
625       }
626     return \"\";
627   "
628 ;; if operands[1] == operands[2], the first option above is wrong! -- dac
629 ;; was this... -- dac
630 ;; ixw  %0,%1\;ixw      %0,%1"
632   [(set_attr "length" "4")])
634 (define_insn ""
635   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
636         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
637                                    (const_int 8))
638                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
639                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
640   "reload_in_progress"
641   "@
642         ixw     %0,%1\;ixw      %0,%1\;addu     %0,%3
643         ixw     %0,%1\;ixw      %0,%1\;addi     %0,%3
644         ixw     %0,%1\;ixw      %0,%1\;subi     %0,%M3"
645   [(set_attr "length" "6")])
647 ;; indexing longs (4 bytes)
649 (define_insn "indexsi_t"
650   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
651         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
652                           (const_int 4))
653                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
654   ""
655   "ixw  %0,%1")
657 (define_insn ""
658   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
659         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
660                                    (const_int 4))
661                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
662                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
663   "reload_in_progress"
664   "@
665         ixw     %0,%1\;addu     %0,%3
666         ixw     %0,%1\;addi     %0,%3
667         ixw     %0,%1\;subi     %0,%M3"
668   [(set_attr "length" "4")])
670 ;; indexing shorts (2 bytes)
672 (define_insn "indexhi_t"
673   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
674         (plus:SI (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
675                           (const_int 2))
676                  (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
677   ""
678   "ixh  %0,%1")
680 (define_insn ""
681   [(set (match_operand:SI 0 "mcore_reload_operand" "=r,r,r")
682         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "mcore_reload_operand" "r,r,r")
683                                    (const_int 2))
684                           (match_operand:SI 2 "mcore_arith_reg_operand" "0,0,0"))
685                  (match_operand:SI 3 "mcore_addsub_operand" "r,J,L")))]
686   "reload_in_progress"
687   "@
688         ixh     %0,%1\;addu     %0,%3
689         ixh     %0,%1\;addi     %0,%3
690         ixh     %0,%1\;subi     %0,%M3"
691   [(set_attr "length" "4")])
694 ;; Other sizes may be handy for indexing. 
695 ;; the tradeoffs to consider when adding these are
696 ;;      code size, execution time [vs. mul it is easy to win],
697 ;;      and register pressure -- these patterns don't use an extra
698 ;;      register to build the offset from the base
699 ;;      and whether the compiler will not come up with some other idiom.
702 ;; -------------------------------------------------------------------------
703 ;; Addition, Subtraction instructions
704 ;; -------------------------------------------------------------------------
706 (define_expand "addsi3"
707   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
708         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
709                  (match_operand:SI 2 "nonmemory_operand" "")))]
710   ""
711   "
713   extern int flag_omit_frame_pointer;
715   /* If this is an add to the frame pointer, then accept it as is so
716      that we can later fold in the fp/sp offset from frame pointer
717      elimination.  */
718   if (flag_omit_frame_pointer
719       && GET_CODE (operands[1]) == REG
720       && (REGNO (operands[1]) == VIRTUAL_STACK_VARS_REGNUM
721           || REGNO (operands[1]) == FRAME_POINTER_REGNUM))
722     {
723       emit_insn (gen_addsi3_fp (operands[0], operands[1], operands[2]));
724       DONE;
725     }
727   /* Convert adds to subtracts if this makes loading the constant cheaper.
728      But only if we are allowed to generate new pseudos.  */
729   if (! (reload_in_progress || reload_completed)
730       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < -32)
731     {
732       int neg_value = - INTVAL (operands[2]);
733       if (   CONST_OK_FOR_I (neg_value)
734           || CONST_OK_FOR_M (neg_value)
735           || CONST_OK_FOR_N (neg_value))
736         {
737           operands[2] = copy_to_mode_reg (SImode, GEN_INT (neg_value));
738           emit_insn (gen_subsi3 (operands[0], operands[1], operands[2]));
739           DONE;
740         }
741     } 
743   if (! mcore_addsub_operand (operands[2], SImode))
744     operands[2] = copy_to_mode_reg (SImode, operands[2]);
747 ;; RBE: for some constants which are not in the range which allows
748 ;; us to do a single operation, we will try a paired addi/addi instead
749 ;; of a movi/addi. This relieves some register pressure at the expense
750 ;; of giving away some potential constant reuse.
752 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
753 ;; for later reference
754 ;; 
755 ;; (define_insn "addsi3_i2"
756 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
757 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
758 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
759 ;;   "GET_CODE(operands[2]) == CONST_INT
760 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
761 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
762 ;;   "*
763 ;; {
764 ;;    int n = INTVAL(operands[2]);
765 ;;    if (n > 0)
766 ;;      {
767 ;;        operands[2] = GEN_INT(n - 32);
768 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
769 ;;      }
770 ;;    else
771 ;;      {
772 ;;        n = (-n);
773 ;;        operands[2] = GEN_INT(n - 32);
774 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
775 ;;      }
776 ;; }"
777 ;;  [(set_attr "length" "4")])
779 (define_insn "addsi3_i"
780   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
781         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
782                  (match_operand:SI 2 "mcore_addsub_operand" "r,J,L")))]
783   ""
784   "@
785         addu    %0,%2
786         addi    %0,%2
787         subi    %0,%M2")
789 ;; This exists so that address computations based on the frame pointer
790 ;; can be folded in when frame pointer elimination occurs.  Ordinarily
791 ;; this would be bad because it allows insns which would require reloading,
792 ;; but without it, we get multiple adds where one would do.
794 (define_insn "addsi3_fp"
795   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
796         (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0,0,0")
797                  (match_operand:SI 2 "immediate_operand" "r,J,L")))]
798   "flag_omit_frame_pointer
799    && (reload_in_progress || reload_completed || REGNO (operands[1]) == FRAME_POINTER_REGNUM)"
800   "@
801         addu    %0,%2
802         addi    %0,%2
803         subi    %0,%M2")
805 ;; RBE: for some constants which are not in the range which allows
806 ;; us to do a single operation, we will try a paired addi/addi instead
807 ;; of a movi/addi. This relieves some register pressure at the expense
808 ;; of giving away some potential constant reuse.
810 ;; RBE 6/17/97: this didn't buy us anything, but I keep the pattern
811 ;; for later reference
812 ;; 
813 ;; (define_insn "subsi3_i2"
814 ;;   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
815 ;;      (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
816 ;;               (match_operand:SI 2 "const_int_operand" "g")))]
817 ;;   "TARGET_RBETEST && GET_CODE(operands[2]) == CONST_INT
818 ;;    && ((INTVAL (operands[2]) > 32 && INTVAL(operands[2]) <= 64)
819 ;;        || (INTVAL (operands[2]) < -32 && INTVAL(operands[2]) >= -64))"
820 ;;   "*
821 ;; {
822 ;;    int n = INTVAL(operands[2]);
823 ;;    if ( n > 0)
824 ;;      {
825 ;;        operands[2] = GEN_INT( n - 32);
826 ;;        return \"subi\\t%0,32\;subi\\t%0,%2\";
827 ;;      }
828 ;;    else
829 ;;      {
830 ;;        n = (-n);
831 ;;        operands[2] = GEN_INT(n - 32);
832 ;;        return \"addi\\t%0,32\;addi\\t%0,%2\";
833 ;;      }
834 ;; }"
835 ;;   [(set_attr "length" "4")])
837 ;(define_insn "subsi3"
838 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
839 ;       (minus:SI (match_operand:SI 1 "mcore_arith_K_operand" "0,0,r,K")
840 ;                 (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0,0")))]
841 ;  ""
842 ;  "@
843 ;       sub     %0,%2
844 ;       subi    %0,%2
845 ;       rsub    %0,%1
846 ;       rsubi   %0,%1")
848 (define_insn "subsi3"
849   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r")
850         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,0,r")
851                   (match_operand:SI 2 "mcore_arith_J_operand" "r,J,0")))]
852   ""
853   "@
854         subu    %0,%2
855         subi    %0,%2
856         rsub    %0,%1")
858 (define_insn ""
859   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
860         (minus:SI (match_operand:SI 1 "mcore_literal_K_operand" "K")
861                   (match_operand:SI 2 "mcore_arith_reg_operand" "0")))]
862   ""
863   "rsubi        %0,%1")
865 (define_insn "adddi3"
866   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
867         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
868                  (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
869    (clobber (reg:CC 17))]
870   ""
871   "*
872   {
873     if (TARGET_LITTLE_END)
874       return \"cmplt    %0,%0\;addc     %0,%2\;addc     %R0,%R2\";
875     return \"cmplt      %R0,%R0\;addc   %R0,%R2\;addc   %0,%2\";
876   }"
877   [(set_attr "length" "6")])
879 ;; special case for "longlong += 1"
880 (define_insn ""
881   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
882         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
883                  (const_int 1)))
884    (clobber (reg:CC 17))]
885   ""
886   "*
887   {
888    if (TARGET_LITTLE_END)
889       return \"addi     %0,1\;cmpnei %0,0\;incf %R0\";
890     return \"addi       %R0,1\;cmpnei %R0,0\;incf       %0\";
891   }"
892   [(set_attr "length" "6")])
894 ;; special case for "longlong -= 1"
895 (define_insn ""
896   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
897         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
898                  (const_int -1)))
899    (clobber (reg:CC 17))]
900   ""
901   "*
902   {
903     if (TARGET_LITTLE_END)
904        return \"cmpnei %0,0\;decf       %R0\;subi       %0,1\";
905     return \"cmpnei %R0,0\;decf %0\;subi        %R0,1\";
906   }"
907   [(set_attr "length" "6")])
909 ;; special case for "longlong += const_int"
910 ;; we have to use a register for the const_int because we don't
911 ;; have an unsigned compare immediate... only +/- 1 get to
912 ;; play the no-extra register game because they compare with 0.
913 ;; This winds up working out for any literal that is synthesized
914 ;; with a single instruction. The more complicated ones look
915 ;; like the get broken into subreg's to get initialized too soon
916 ;; for us to catch here. -- RBE 4/25/96
917 ;; only allow for-sure positive values.
919 (define_insn ""
920   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
921         (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
922                  (match_operand:SI 2 "const_int_operand" "r")))
923    (clobber (reg:CC 17))]
924   "GET_CODE (operands[2]) == CONST_INT
925    && INTVAL (operands[2]) > 0 && ! (INTVAL (operands[2]) & 0x80000000)"
926   "*
928   if (GET_MODE (operands[2]) != SImode)
929      abort ();
930   if (TARGET_LITTLE_END)
931     return \"addu       %0,%2\;cmphs    %0,%2\;incf     %R0\";
932   return \"addu %R0,%2\;cmphs   %R0,%2\;incf    %0\";
934   [(set_attr "length" "6")])
936 ;; optimize "long long" + "unsigned long"
937 ;; won't trigger because of how the extension is expanded upstream.
938 ;; (define_insn ""
939 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
940 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
941 ;;               (zero_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
942 ;;    (clobber (reg:CC 17))]
943 ;;   "0"
944 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0"
945 ;;   [(set_attr "length" "6")])
947 ;; optimize "long long" + "signed long"
948 ;; won't trigger because of how the extension is expanded upstream.
949 ;; (define_insn ""
950 ;;   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
951 ;;      (plus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "%0")
952 ;;               (sign_extend:DI (match_operand:SI 2 "mcore_arith_reg_operand" "r"))))
953 ;;    (clobber (reg:CC 17))]
954 ;;   "0"
955 ;;   "cmplt     %R0,%R0\;addc   %R0,%2\;inct    %0\;btsti       %2,31\;dect     %0"
956 ;;   [(set_attr "length" "6")])
958 (define_insn "subdi3"
959   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
960         (minus:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")
961                   (match_operand:DI 2 "mcore_arith_reg_operand" "r")))
962    (clobber (reg:CC 17))]
963   ""
964   "*
965   {
966     if (TARGET_LITTLE_END)
967       return \"cmphs    %0,%0\;subc     %0,%2\;subc     %R0,%R2\";
968     return \"cmphs      %R0,%R0\;subc   %R0,%R2\;subc   %0,%2\";
969   }"
970   [(set_attr "length" "6")])
972 ;; -------------------------------------------------------------------------
973 ;; Multiplication instructions
974 ;; -------------------------------------------------------------------------
976 (define_insn "mulsi3"
977   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
978         (mult:SI (match_operand:SI 1 "mcore_arith_reg_operand" "%0")
979                  (match_operand:SI 2 "mcore_arith_reg_operand" "r")))]
980   ""
981   "mult %0,%2")
984 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
986 ;; Different constraints based on the architecture revision...
988 (define_expand "divsi3"
989   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
990         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
991                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
992   "TARGET_DIV"
993   "")
995 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
997 (define_insn ""
998   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
999         (div:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1000                 (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
1001   "TARGET_DIV"
1002   "divs %0,%2")
1005 ;; 32/32 signed division -- added to the MCORE instruction set spring 1997
1007 ;; Different constraints based on the architecture revision...
1009 (define_expand "udivsi3"
1010   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1011         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
1012                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
1013   "TARGET_DIV"
1014   "")
1016 ;; MCORE Revision 1.50: restricts the divisor to be in r1. (6/97)
1017 (define_insn ""
1018   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1019         (udiv:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1020                  (match_operand:SI 2 "mcore_arith_reg_operand" "b")))]
1021   "TARGET_DIV"
1022   "divu %0,%2")
1024 ;; -------------------------------------------------------------------------
1025 ;; Unary arithmetic
1026 ;; -------------------------------------------------------------------------
1028 (define_insn "negsi2"
1029   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1030         (neg:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1031   ""
1032   "*
1034    return \"rsubi       %0,0\";
1038 (define_insn "abssi2"
1039   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1040         (abs:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1041   ""
1042   "abs  %0")
1043              
1044 (define_insn "negdi2"
1045   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=&r")
1046         (neg:DI (match_operand:DI 1 "mcore_arith_reg_operand" "0")))
1047    (clobber (reg:CC 17))]
1048   ""
1049   "*
1051    if (TARGET_LITTLE_END)
1052      return \"cmpnei    %0,0\\n\\trsubi %0,0\\n\\tnot   %R0\\n\\tincf   %R0\";
1053    return \"cmpnei      %R0,0\\n\\trsubi        %R0,0\\n\\tnot  %0\\n\\tincf    %0\";
1055   [(set_attr "length" "8")])
1057 (define_insn "one_cmplsi2"
1058   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1059         (not:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1060   ""
1061   "not  %0")
1063 ;; -------------------------------------------------------------------------
1064 ;; Zero extension instructions
1065 ;; -------------------------------------------------------------------------
1067 (define_expand "zero_extendhisi2"
1068   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1069         (zero_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "")))]
1070   ""
1071   "")
1073 (define_insn ""
1074   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r")
1075         (zero_extend:SI (match_operand:HI 1 "general_operand" "0,m")))]
1076   ""
1077   "@
1078         zexth   %0
1079         ld.h    %0,%1"
1080   [(set_attr "type" "shift,load")])
1082 ;; ldh gives us a free zero-extension. The combiner picks up on this.
1083 (define_insn ""
1084   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1085         (zero_extend:SI (mem:HI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1086   ""
1087   "ld.h %0,(%1)"
1088   [(set_attr "type" "load")])
1090 (define_insn ""
1091   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1092         (zero_extend:SI (mem:HI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1093                                          (match_operand:SI 2 "const_int_operand" "")))))]
1094   "(INTVAL (operands[2]) >= 0) &&
1095    (INTVAL (operands[2]) < 32) &&
1096    ((INTVAL (operands[2])&1) == 0)"
1097   "ld.h %0,(%1,%2)"
1098   [(set_attr "type" "load")])
1100 (define_expand "zero_extendqisi2"
1101   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1102         (zero_extend:SI (match_operand:QI 1 "general_operand" "")))]
1103   ""
1104   "") 
1106 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1107 (define_insn ""
1108   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b,r")
1109         (zero_extend:SI (match_operand:QI 1 "general_operand" "0,r,m")))]
1110   ""
1111   "@
1112         zextb   %0
1113         xtrb3   %0,%1
1114         ld.b    %0,%1"
1115   [(set_attr "type" "shift,shift,load")])
1117 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1118 (define_insn ""
1119   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1120         (zero_extend:SI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1121   ""
1122   "ld.b %0,(%1)"
1123   [(set_attr "type" "load")])
1125 (define_insn ""
1126   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1127         (zero_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1128                                          (match_operand:SI 2 "const_int_operand" "")))))]
1129   "(INTVAL (operands[2]) >= 0) &&
1130    (INTVAL (operands[2]) < 16)"
1131   "ld.b %0,(%1,%2)"
1132   [(set_attr "type" "load")])
1134 (define_expand "zero_extendqihi2"
1135   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "")
1136         (zero_extend:HI (match_operand:QI 1 "general_operand" "")))]
1137   ""
1138   "") 
1140 ;; RBE: XXX: we don't recognize that the xtrb3 kills the CC register.
1141 (define_insn ""
1142   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r,b,r")
1143         (zero_extend:HI (match_operand:QI 1 "general_operand" "0,r,m")))]
1144   ""
1145   "@
1146         zextb   %0
1147         xtrb3   %0,%1
1148         ld.b    %0,%1"
1149   [(set_attr "type" "shift,shift,load")])
1151 ;; ldb gives us a free zero-extension. The combiner picks up on this.
1152 ;; this doesn't catch references that are into a structure.
1153 ;; note that normally the compiler uses the above insn, unless it turns
1154 ;; out that we're dealing with a volatile...
1155 (define_insn ""
1156   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1157         (zero_extend:HI (mem:QI (match_operand:SI 1 "mcore_arith_reg_operand" "r"))))]
1158   ""
1159   "ld.b %0,(%1)"
1160   [(set_attr "type" "load")])
1162 (define_insn ""
1163   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1164         (zero_extend:HI (mem:QI (plus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r")
1165                                          (match_operand:SI 2 "const_int_operand" "")))))]
1166   "(INTVAL (operands[2]) >= 0) &&
1167    (INTVAL (operands[2]) < 16)"
1168   "ld.b %0,(%1,%2)"
1169   [(set_attr "type" "load")])
1172 ;; -------------------------------------------------------------------------
1173 ;; Sign extension instructions
1174 ;; -------------------------------------------------------------------------
1176 (define_expand "extendsidi2"
1177   [(set (match_operand:DI 0 "mcore_arith_reg_operand" "=r") 
1178         (match_operand:SI 1 "mcore_arith_reg_operand" "r"))]
1179   ""
1180   "
1181   {
1182     int low, high;
1184     if (TARGET_LITTLE_END)
1185       low = 0, high = 4;
1186     else
1187       low = 4, high = 0;
1188     
1189     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], low),
1190               operands[1]));
1191     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], high),
1192               gen_rtx_ASHIFTRT (SImode,
1193                                gen_rtx_SUBREG (SImode, operands[0], low),
1194                                GEN_INT (31))));
1195     DONE;
1196   }"
1199 (define_insn "extendhisi2"
1200   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1201         (sign_extend:SI (match_operand:HI 1 "mcore_arith_reg_operand" "0")))]
1202   ""
1203   "sexth        %0")
1205 (define_insn "extendqisi2"
1206   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1207         (sign_extend:SI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1208   ""
1209   "sextb        %0")
1211 (define_insn "extendqihi2"
1212   [(set (match_operand:HI 0 "mcore_arith_reg_operand" "=r")
1213         (sign_extend:HI (match_operand:QI 1 "mcore_arith_reg_operand" "0")))]
1214   ""
1215   "sextb        %0")
1217 ;; -------------------------------------------------------------------------
1218 ;; Move instructions
1219 ;; -------------------------------------------------------------------------
1221 ;; SImode
1223 (define_expand "movsi"
1224   [(set (match_operand:SI 0 "general_operand" "")
1225         (match_operand:SI 1 "general_operand" ""))]
1226   ""
1227   "
1229   if (GET_CODE (operands[0]) == MEM)
1230     operands[1] = force_reg (SImode, operands[1]);
1233 (define_insn ""
1234   [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,a,r,a,r,m")
1235         (match_operand:SI 1 "mcore_general_movsrc_operand"  "r,P,i,c,R,m,r"))]
1236   "(register_operand (operands[0], SImode)
1237     || register_operand (operands[1], SImode))"
1238   "* return mcore_output_move (insn, operands, SImode);"
1239   [(set_attr "type" "move,move,move,move,load,load,store")])
1242 ;; HImode
1245 (define_expand "movhi"
1246   [(set (match_operand:HI 0 "general_operand" "")
1247         (match_operand:HI 1 "general_operand"  ""))]
1248   ""
1249   "
1251   if (GET_CODE (operands[0]) == MEM)
1252     operands[1] = force_reg (HImode, operands[1]);
1253   else if (CONSTANT_P (operands[1])
1254            && (GET_CODE (operands[1]) != CONST_INT
1255                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1256                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1257                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1258            && ! reload_completed && ! reload_in_progress)
1259     {
1260       rtx reg = gen_reg_rtx (SImode);
1261       emit_insn (gen_movsi (reg, operands[1]));
1262       operands[1] = gen_lowpart (HImode, reg);
1263     }
1265   
1266 (define_insn ""
1267   [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1268         (match_operand:HI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1269   "(register_operand (operands[0], HImode)
1270     || register_operand (operands[1], HImode))"
1271   "* return mcore_output_move (insn, operands, HImode);"
1272   [(set_attr "type" "move,move,move,move,load,store")])
1275 ;; QImode
1278 (define_expand "movqi"
1279   [(set (match_operand:QI 0 "general_operand" "")
1280         (match_operand:QI 1 "general_operand"  ""))]
1281   ""
1282   "
1284   if (GET_CODE (operands[0]) == MEM)
1285     operands[1] = force_reg (QImode, operands[1]);
1286   else if (CONSTANT_P (operands[1])
1287            && (GET_CODE (operands[1]) != CONST_INT
1288                || (! CONST_OK_FOR_I (INTVAL (operands[1]))
1289                    && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1290                    && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
1291            && ! reload_completed && ! reload_in_progress)
1292     {
1293       rtx reg = gen_reg_rtx (SImode);
1294       emit_insn (gen_movsi (reg, operands[1]));
1295       operands[1] = gen_lowpart (QImode, reg);
1296     }
1298   
1299 (define_insn ""
1300   [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
1301         (match_operand:QI 1 "mcore_general_movsrc_operand"  "r,P,i,c,m,r"))]
1302   "(register_operand (operands[0], QImode)
1303     || register_operand (operands[1], QImode))"
1304   "* return mcore_output_move (insn, operands, QImode);"
1305    [(set_attr "type" "move,move,move,move,load,store")])
1308 ;; DImode
1310 (define_expand "movdi"
1311   [(set (match_operand:DI 0 "general_operand" "")
1312         (match_operand:DI 1 "general_operand" ""))]
1313   ""
1314   "
1316   if (GET_CODE (operands[0]) == MEM)
1317     operands[1] = force_reg (DImode, operands[1]);
1318   else if (GET_CODE (operands[1]) == CONST_INT
1319            && ! CONST_OK_FOR_I (INTVAL (operands[1]))
1320            && ! CONST_OK_FOR_M (INTVAL (operands[1]))
1321            && ! CONST_OK_FOR_N (INTVAL (operands[1])))
1322     {
1323       int i;
1324       for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
1325         emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
1326                         simplify_gen_subreg (SImode, operands[1], DImode, i));
1327       DONE;
1328     }
1331 (define_insn "movdi_i"
1332   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,a,r,m")
1333         (match_operand:DI 1 "mcore_general_movsrc_operand" "I,M,N,r,R,m,r"))]
1334   ""
1335   "* return mcore_output_movedouble (operands, DImode);"
1336   [(set_attr "length" "4") (set_attr "type" "move,move,move,move,load,load,store")])
1338 ;; SFmode
1340 (define_expand "movsf"
1341   [(set (match_operand:SF 0 "general_operand" "")
1342         (match_operand:SF 1 "general_operand" ""))]
1343   ""
1344   "
1346   if (GET_CODE (operands[0]) == MEM)
1347     operands[1] = force_reg (SFmode, operands[1]);
1350 (define_insn "movsf_i"
1351   [(set (match_operand:SF 0 "general_operand" "=r,r,m")
1352         (match_operand:SF 1 "general_operand"  "r,m,r"))]
1353   ""
1354   "@
1355         mov     %0,%1
1356         ld.w    %0,%1
1357         st.w    %1,%0"
1358   [(set_attr "type" "move,load,store")])
1360 ;; DFmode
1362 (define_expand "movdf"
1363   [(set (match_operand:DF 0 "general_operand" "")
1364         (match_operand:DF 1 "general_operand" ""))]
1365   ""
1366   "
1368   if (GET_CODE (operands[0]) == MEM)
1369     operands[1] = force_reg (DFmode, operands[1]);
1372 (define_insn "movdf_k"
1373   [(set (match_operand:DF 0 "general_operand" "=r,r,m")
1374         (match_operand:DF 1 "general_operand" "r,m,r"))]
1375   ""
1376   "* return mcore_output_movedouble (operands, DFmode);"
1377   [(set_attr "length" "4") (set_attr "type" "move,load,store")])
1380 ;; Load/store multiple
1382 ;; ??? This is not currently used.
1383 (define_insn "ldm"
1384   [(set (match_operand:TI 0 "mcore_arith_reg_operand" "=r")
1385         (mem:TI (match_operand:SI 1 "mcore_arith_reg_operand" "r")))]
1386   ""
1387   "ldq  %U0,(%1)")
1389 ;; ??? This is not currently used.
1390 (define_insn "stm"
1391   [(set (mem:TI (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1392         (match_operand:TI 1 "mcore_arith_reg_operand" "r"))]
1393   ""
1394   "stq  %U1,(%0)")
1396 (define_expand "load_multiple"
1397   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1398                           (match_operand:SI 1 "" ""))
1399                      (use (match_operand:SI 2 "" ""))])]
1400   ""
1401   "
1403   int regno, count, i;
1405   /* Support only loading a constant number of registers from memory and
1406      only if at least two registers.  The last register must be r15.  */
1407   if (GET_CODE (operands[2]) != CONST_INT
1408       || INTVAL (operands[2]) < 2
1409       || GET_CODE (operands[1]) != MEM
1410       || XEXP (operands[1], 0) != stack_pointer_rtx
1411       || GET_CODE (operands[0]) != REG
1412       || REGNO (operands[0]) + INTVAL (operands[2]) != 16)
1413     FAIL;
1415   count = INTVAL (operands[2]);
1416   regno = REGNO (operands[0]);
1418   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1420   for (i = 0; i < count; i++)
1421     XVECEXP (operands[3], 0, i)
1422       = gen_rtx_SET (VOIDmode,
1423                  gen_rtx_REG (SImode, regno + i),
1424                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1425                                                       i * 4)));
1428 (define_insn ""
1429   [(match_parallel 0 "mcore_load_multiple_operation"
1430                    [(set (match_operand:SI 1 "mcore_arith_reg_operand" "=r")
1431                          (mem:SI (match_operand:SI 2 "register_operand" "r")))])]
1432   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1433   "ldm  %1-r15,(%2)")
1435 (define_expand "store_multiple"
1436   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1437                           (match_operand:SI 1 "" ""))
1438                      (use (match_operand:SI 2 "" ""))])]
1439   ""
1440   "
1442   int regno, count, i;
1444   /* Support only storing a constant number of registers to memory and
1445      only if at least two registers.  The last register must be r15.  */
1446   if (GET_CODE (operands[2]) != CONST_INT
1447       || INTVAL (operands[2]) < 2
1448       || GET_CODE (operands[0]) != MEM
1449       || XEXP (operands[0], 0) != stack_pointer_rtx
1450       || GET_CODE (operands[1]) != REG
1451       || REGNO (operands[1]) + INTVAL (operands[2]) != 16)
1452     FAIL;
1454   count = INTVAL (operands[2]);
1455   regno = REGNO (operands[1]);
1457   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1459   for (i = 0; i < count; i++)
1460     XVECEXP (operands[3], 0, i)
1461       = gen_rtx_SET (VOIDmode,
1462                  gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx,
1463                                                       i * 4)),
1464                  gen_rtx_REG (SImode, regno + i));
1467 (define_insn ""
1468   [(match_parallel 0 "mcore_store_multiple_operation"
1469                    [(set (mem:SI (match_operand:SI 2 "register_operand" "r"))
1470                          (match_operand:SI 1 "mcore_arith_reg_operand" "r"))])]
1471   "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM"
1472   "stm  %1-r15,(%2)")
1474 ;; ------------------------------------------------------------------------
1475 ;; Define the real conditional branch instructions.
1476 ;; ------------------------------------------------------------------------
1478 (define_insn "branch_true"
1479   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1480                            (label_ref (match_operand 0 "" ""))
1481                            (pc)))]
1482   ""
1483   "jbt  %l0"
1484   [(set_attr "type" "brcond")])
1486 (define_insn "branch_false"
1487   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1488                            (label_ref (match_operand 0 "" ""))
1489                            (pc)))]
1490   ""
1491   "jbf  %l0"
1492   [(set_attr "type" "brcond")])
1494 (define_insn "inverse_branch_true"
1495   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
1496                            (pc)
1497                            (label_ref (match_operand 0 "" ""))))]
1498   ""
1499   "jbf  %l0"
1500   [(set_attr "type" "brcond")])
1502 (define_insn "inverse_branch_false"
1503   [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0))
1504                            (pc)
1505                            (label_ref (match_operand 0 "" ""))))]
1506   ""
1507   "jbt  %l0"
1508   [(set_attr "type" "brcond")])
1510 ;; Conditional branch insns
1512 ;; At top-level, condition test are eq/ne, because we
1513 ;; are comparing against the condition register (which
1514 ;; has the result of the true relational test
1516 ; There is no beq compare, so we reverse the branch arms.
1518 (define_expand "beq"
1519   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1520                            (pc)
1521                            (label_ref (match_operand 0 "" ""))))]
1522   ""
1523   "
1525   operands[1] = mcore_gen_compare_reg (EQ);
1528 (define_expand "bne"
1529   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1530                            (label_ref (match_operand 0 "" ""))
1531                            (pc)))]
1532   ""
1533   "
1535   operands[1] = mcore_gen_compare_reg (NE);
1538 ; check whether (GT A imm) can become (LE A imm) with the branch reversed.  
1539 ; if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
1541 (define_expand "bgt"
1542   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1543                            (label_ref (match_operand 0 "" ""))
1544                            (pc)))]
1545   ""
1546   "
1548   if (mcore_modify_comparison (LE))
1549     {
1550       emit_jump_insn (gen_reverse_blt (operands[0]));
1551       DONE;
1552     }
1553   operands[1] = mcore_gen_compare_reg (GT);
1556 ; There is no ble compare, so we reverse the branch arms.
1557 ; reversed the condition and branch arms for ble -- the check_dbra_loop()
1558 ; transformation assumes that ble uses a branch-true with the label as
1559 ; as the target. BRC
1561 ; check whether (LE A imm) can become (LT A imm + 1).
1563 (define_expand "ble"
1564   [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
1565                            (label_ref (match_operand 0 "" ""))
1566                            (pc)))]
1567   ""
1568   "
1570   if (mcore_modify_comparison (LE))
1571     {
1572       emit_jump_insn (gen_blt (operands[0]));
1573       DONE;
1574     }
1575   operands[1] = mcore_gen_compare_reg (LE);
1578 ; make generating a reversed blt simple
1579 (define_expand "reverse_blt"
1580   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1581                            (pc)
1582                            (label_ref (match_operand 0 "" ""))))]
1583   ""
1584   "
1586   operands[1] = mcore_gen_compare_reg (LT);
1589 (define_expand "blt"
1590   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1591                            (label_ref (match_operand 0 "" ""))
1592                            (pc)))]
1593   ""
1594   "
1596   operands[1] = mcore_gen_compare_reg (LT);
1599 ; There is no bge compare, so we reverse the branch arms.
1601 (define_expand "bge"
1602   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1603                            (pc)
1604                            (label_ref (match_operand 0 "" ""))))]
1605   ""
1606   "
1608   operands[1] = mcore_gen_compare_reg (GE);
1611 ; There is no gtu compare, so we reverse the branch arms
1613 ;(define_expand "bgtu"
1614 ;  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1615 ;                          (pc)
1616 ;                          (label_ref (match_operand 0 "" ""))))]
1617 ;  ""
1618 ;  "
1620 ;  if (GET_CODE (arch_compare_op1) == CONST_INT
1621 ;      && INTVAL (arch_compare_op1) == 0)
1622 ;    operands[1] = mcore_gen_compare_reg (NE);
1623 ;  else 
1624 ;    { if (mcore_modify_comparison (GTU))
1625 ;       {
1626 ;         emit_jump_insn (gen_bgeu (operands[0]));
1627 ;         DONE;
1628 ;       }
1629 ;      operands[1] = mcore_gen_compare_reg (LEU);
1630 ;    }
1631 ;}")
1633 (define_expand "bgtu"
1634   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1635                            (pc)
1636                            (label_ref (match_operand 0 "" ""))))]
1637   ""
1638   "
1640   if (GET_CODE (arch_compare_op1) == CONST_INT
1641       && INTVAL (arch_compare_op1) == 0)
1642     {
1643       /* The inverse of '> 0' for an unsigned test is
1644          '== 0' but we do not have such an instruction available.
1645          Instead we must reverse the branch (back to the normal
1646          ordering) and test '!= 0'.  */
1647          
1648       operands[1] = mcore_gen_compare_reg (NE);
1649       
1650       emit_jump_insn (gen_rtx_SET (VOIDmode,
1651         pc_rtx,
1652         gen_rtx_IF_THEN_ELSE (VOIDmode,
1653         gen_rtx_NE (VOIDmode,
1654         operands[1],
1655         const0_rtx),
1656         gen_rtx_LABEL_REF (VOIDmode,operands[0]),
1657         pc_rtx)));
1658       DONE;           
1659     }
1660   operands[1] = mcore_gen_compare_reg (GTU);
1664 (define_expand "bleu"
1665   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1666                            (label_ref (match_operand 0 "" ""))
1667                            (pc)))]
1668   ""
1669   "
1671   operands[1] = mcore_gen_compare_reg (LEU);
1674 ; There is no bltu compare, so we reverse the branch arms
1675 (define_expand "bltu"
1676   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1677                            (pc)
1678                            (label_ref (match_operand 0 "" ""))))]
1679   ""
1680   "
1682   operands[1] = mcore_gen_compare_reg (LTU);
1685 (define_expand "bgeu"
1686   [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
1687                            (label_ref (match_operand 0 "" ""))
1688                            (pc)))]
1689   ""
1690   "
1693   operands[1] = mcore_gen_compare_reg (GEU);
1696 ;; ------------------------------------------------------------------------
1697 ;; Jump and linkage insns
1698 ;; ------------------------------------------------------------------------
1700 (define_insn "jump_real"
1701   [(set (pc)
1702         (label_ref (match_operand 0 "" "")))]
1703   ""
1704   "jbr  %l0"
1705   [(set_attr "type" "branch")])
1707 (define_expand "jump"
1708  [(set (pc) (label_ref (match_operand 0 "" "")))]
1709  ""
1712   emit_jump_insn (gen_jump_real (operand0));
1713   DONE;
1717 (define_insn "indirect_jump"
1718   [(set (pc)
1719         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))]
1720   ""
1721   "jmp  %0"
1722   [(set_attr "type" "jmp")])
1724 (define_expand "call"
1725   [(parallel[(call (match_operand:SI 0 "" "")
1726                    (match_operand 1 "" ""))
1727              (clobber (reg:SI 15))])]
1728   ""
1729   "
1731   if (GET_CODE (operands[0]) == MEM
1732       && ! register_operand (XEXP (operands[0], 0), SImode)
1733       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1734     operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
1735                            force_reg (Pmode, XEXP (operands[0], 0)));
1738 (define_insn "call_internal"
1739   [(call (mem:SI (match_operand:SI 0 "mcore_call_address_operand" "riR"))
1740          (match_operand 1 "" ""))
1741    (clobber (reg:SI 15))]
1742   ""
1743   "* return mcore_output_call (operands, 0);")
1745 (define_expand "call_value"
1746   [(parallel[(set (match_operand 0 "register_operand" "")
1747                   (call (match_operand:SI 1 "" "")
1748                         (match_operand 2 "" "")))
1749              (clobber (reg:SI 15))])]
1750   ""
1751   "
1753   if (GET_CODE (operands[0]) == MEM
1754       && ! register_operand (XEXP (operands[0], 0), SImode)
1755       && ! mcore_symbolic_address_p (XEXP (operands[0], 0)))
1756     operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
1757                            force_reg (Pmode, XEXP (operands[1], 0)));
1760 (define_insn "call_value_internal"
1761   [(set (match_operand 0 "register_operand" "=r")
1762         (call (mem:SI (match_operand:SI 1 "mcore_call_address_operand" "riR"))
1763               (match_operand 2 "" "")))
1764    (clobber (reg:SI 15))]
1765   ""
1766   "* return mcore_output_call (operands, 1);")
1768 (define_insn "call_value_struct"
1769   [(parallel [(set (match_parallel 0 ""
1770                      [(expr_list (match_operand 3 "register_operand" "") (match_operand 4 "immediate_operand" ""))
1771                       (expr_list (match_operand 5 "register_operand" "") (match_operand 6 "immediate_operand" ""))])
1772                   (call (match_operand:SI 1 "" "")
1773                         (match_operand 2 "" "")))
1774              (clobber (reg:SI 15))])]
1775   ""
1776   "* return mcore_output_call (operands, 1);"
1780 ;; ------------------------------------------------------------------------
1781 ;; Misc insns
1782 ;; ------------------------------------------------------------------------
1784 (define_insn "nop"
1785   [(const_int 0)]
1786   ""
1787   "or   r0,r0")
1789 (define_insn "tablejump"
1790   [(set (pc)
1791         (match_operand:SI 0 "mcore_arith_reg_operand" "r"))
1792    (use (label_ref (match_operand 1 "" "")))]
1793   ""
1794   "jmp  %0"
1795   [(set_attr "type" "jmp")])
1797 (define_insn "*return"
1798  [(return)]
1799  "reload_completed && ! mcore_naked_function_p ()"
1800  "jmp   r15"
1801  [(set_attr "type" "jmp")])
1803 (define_insn "*no_return"
1804  [(return)]
1805  "reload_completed && mcore_naked_function_p ()"
1806  ""
1807  [(set_attr "length" "0")]
1810 (define_expand "prologue"
1811   [(const_int 0)]
1812   ""
1813   "mcore_expand_prolog (); DONE;")
1815 (define_expand "epilogue"
1816   [(return)]
1817   ""
1818   "mcore_expand_epilog ();")
1820 ;; ------------------------------------------------------------------------
1821 ;; Scc instructions
1822 ;; ------------------------------------------------------------------------
1824 (define_insn "mvc"
1825   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1826         (ne:SI (reg:CC 17) (const_int 0)))]
1827   ""
1828   "mvc  %0"
1829   [(set_attr "type" "move")])
1831 (define_insn "mvcv"
1832   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1833         (eq:SI (reg:CC 17) (const_int 0)))]
1834   ""
1835   "mvcv %0"
1836   [(set_attr "type" "move")])
1838 ; in 0.97 use (LE 0) with (LT 1) and complement c.  BRC
1839 (define_split 
1840   [(parallel[
1841      (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1842           (ne:SI (gt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
1843                         (const_int 0))
1844                  (const_int 0)))
1845      (clobber (reg:SI 17))])]
1846   ""
1847   [(set (reg:CC 17)
1848         (lt:CC (match_dup 1) (const_int 1)))
1849    (set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
1850      
1852 (define_expand "seq"
1853   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1854         (eq:SI (match_dup 1) (const_int 0)))]
1855   ""
1856   "
1858   operands[1] = mcore_gen_compare_reg (NE);
1861 (define_expand "sne"
1862   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1863         (ne:SI (match_dup 1) (const_int 0)))]
1864   ""
1865   "
1867   operands[1] = mcore_gen_compare_reg (NE);
1870 (define_expand "slt"
1871   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1872         (ne:SI (match_dup 1) (const_int 0)))]
1873   ""
1874   "
1876   operands[1] = mcore_gen_compare_reg (LT);
1879 ; make generating a LT with the comparison reversed easy.  BRC
1880 (define_expand "reverse_slt"
1881   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1882         (eq:SI (match_dup 1) (const_int 0)))]
1883   ""
1884   "
1886   operands[1] = mcore_gen_compare_reg (LT);
1889 (define_expand "sge"
1890   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1891         (eq:SI (match_dup 1) (const_int 0)))]
1892   ""
1893   "
1895   operands[1] = mcore_gen_compare_reg (LT);
1898 ; check whether (GT A imm) can become (LE A imm) with the comparison
1899 ; reversed.  if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
1901 (define_expand "sgt"
1902   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1903         (ne:SI (match_dup 1) (const_int 0)))]
1904   ""
1905   "
1907   if (mcore_modify_comparison (LE))
1908     {
1909       emit_insn (gen_reverse_slt (operands[0]));
1910       DONE;
1911     }
1912   
1913   operands[1] = mcore_gen_compare_reg (GT);
1916 (define_expand "sle"
1917   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1918         (eq:SI (match_dup 1) (const_int 0)))]
1919   ""
1920   "
1922   if (mcore_modify_comparison (LE))
1923     {
1924       emit_insn (gen_slt (operands[0]));
1925       DONE;
1926     }
1927   operands[1] = mcore_gen_compare_reg (GT);
1930 (define_expand "sltu"
1931   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1932         (eq:SI (match_dup 1) (const_int 0)))]
1933   ""
1934   "
1936   operands[1] = mcore_gen_compare_reg (GEU);
1939 (define_expand "sgeu"
1940   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1941         (ne:SI (match_dup 1) (const_int 0)))]
1942   ""
1943   "
1945   operands[1] = mcore_gen_compare_reg (GEU);
1948 (define_expand "sgtu"
1949   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1950         (eq:SI (match_dup 1) (const_int 0)))]
1951   ""
1952   "
1954   operands[1] = mcore_gen_compare_reg (LEU);
1957 (define_expand "sleu"
1958   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
1959         (ne:SI (match_dup 1) (const_int 0)))]
1960   ""
1961   "
1963   operands[1] = mcore_gen_compare_reg (LEU);
1966 (define_insn "incscc"
1967   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1968         (plus:SI (ne (reg:CC 17) (const_int 0))
1969                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1970   ""
1971   "inct %0")
1973 (define_insn "incscc_false"
1974   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1975         (plus:SI (eq (reg:CC 17) (const_int 0))
1976                  (match_operand:SI 1 "mcore_arith_reg_operand" "0")))]
1977   ""
1978   "incf %0")
1980 (define_insn "decscc"
1981   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1982         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1983                   (ne (reg:CC 17) (const_int 0))))]
1984   ""
1985   "dect %0")
1987 (define_insn "decscc_false"
1988   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
1989         (minus:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0")
1990                   (eq (reg:CC 17) (const_int 0))))]
1991   ""
1992   "decf %0")
1994 ;; ------------------------------------------------------------------------
1995 ;; Conditional move patterns.
1996 ;; ------------------------------------------------------------------------
1998 (define_expand "smaxsi3"
1999   [(set (reg:CC 17)
2000         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2001                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2002    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2003         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2004                          (match_dup 1) (match_dup 2)))]
2005   ""
2006   "")
2007                
2008 (define_split
2009   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2010         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2011                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2012   ""
2013   [(set (reg:CC 17)
2014         (lt:SI (match_dup 1) (match_dup 2)))
2015    (set (match_dup 0)
2016         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2017                          (match_dup 1) (match_dup 2)))]
2018   "")
2020 ; no tstgt in 0.97, so just use cmplti (btsti x,31) and reverse move 
2021 ; condition  BRC
2022 (define_split
2023   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2024         (smax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2025                  (const_int 0)))]
2026   ""
2027   [(set (reg:CC 17)
2028         (lt:CC (match_dup 1) (const_int 0)))
2029    (set (match_dup 0)
2030         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2031                          (match_dup 1) (const_int 0)))]
2032   "")
2034 (define_expand "sminsi3"
2035   [(set (reg:CC 17)
2036         (lt:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2037                (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2038    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2039         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2040                          (match_dup 1) (match_dup 2)))]
2041   ""
2042   "")
2044 (define_split
2045   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2046         (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2047                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2048   ""
2049   [(set (reg:CC 17)
2050         (lt:SI (match_dup 1) (match_dup 2)))
2051    (set (match_dup 0)
2052         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2053                          (match_dup 1) (match_dup 2)))]
2054   "")
2056 ;(define_split
2057 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2058 ;        (smin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2059 ;                 (const_int 0)))]
2060 ;  ""
2061 ;  [(set (reg:CC 17)
2062 ;        (gt:CC (match_dup 1) (const_int 0)))
2063 ;   (set (match_dup 0)
2064 ;        (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2065 ;                         (match_dup 1) (const_int 0)))]
2066 ;  "")
2068 ; changed these unsigned patterns to use geu instead of ltu.  it appears
2069 ; that the c-torture & ssrl test suites didn't catch these!  only showed
2070 ; up in friedman's clib work.   BRC 7/7/95
2072 (define_expand "umaxsi3"
2073   [(set (reg:CC 17)
2074         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2075                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2076    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2077         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2078                          (match_dup 2) (match_dup 1)))]
2079   ""
2080   "")
2081                
2082 (define_split
2083   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2084         (umax:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2085                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2086   ""
2087   [(set (reg:CC 17)
2088         (geu:SI (match_dup 1) (match_dup 2)))
2089    (set (match_dup 0)
2090         (if_then_else:SI (eq (reg:CC 17) (const_int 0))
2091                          (match_dup 2) (match_dup 1)))]
2092   "")
2094 (define_expand "uminsi3"
2095   [(set (reg:CC 17)
2096         (geu:CC (match_operand:SI 1 "mcore_arith_reg_operand" "")
2097                 (match_operand:SI 2 "mcore_arith_reg_operand" "")))
2098    (set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2099         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2100                          (match_dup 2) (match_dup 1)))]
2101   ""
2102   "")
2104 (define_split
2105   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2106         (umin:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2107                  (match_operand:SI 2 "mcore_arith_reg_operand" "")))]
2108   ""
2109   [(set (reg:CC 17)
2110         (geu:SI (match_dup 1) (match_dup 2)))
2111    (set (match_dup 0)
2112         (if_then_else:SI (ne (reg:CC 17) (const_int 0))
2113                          (match_dup 2) (match_dup 1)))]
2114   "")
2116 ;; ------------------------------------------------------------------------
2117 ;; conditional move patterns really start here
2118 ;; ------------------------------------------------------------------------
2120 ;; the "movtK" patterns are experimental.  they are intended to account for
2121 ;; gcc's mucking on code such as:
2123 ;;            free_ent = ((block_compress) ? 257 : 256 );
2125 ;; these patterns help to get a tstne/bgeni/inct (or equivalent) sequence
2126 ;; when both arms have constants that are +/- 1 of each other.
2128 ;; note in the following patterns that the "movtK" ones should be the first
2129 ;; one defined in each sequence.  this is because the general pattern also
2130 ;; matches, so use ordering to determine priority (it's easier this way than
2131 ;; adding conditions to the general patterns).   BRC
2133 ;; the U and Q constraints are necessary to ensure that reload does the
2134 ;; 'right thing'.  U constrains the operand to 0 and Q to 1 for use in the
2135 ;; clrt & clrf and clrt/inct & clrf/incf patterns.    BRC 6/26
2137 ;; ??? there appears to be some problems with these movtK patterns for ops
2138 ;; other than eq & ne.  need to fix.  6/30 BRC
2140 ;; ------------------------------------------------------------------------
2141 ;; ne 
2142 ;; ------------------------------------------------------------------------
2144 ; experimental conditional move with two constants +/- 1  BRC
2146 (define_insn "movtK_1"
2147   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2148         (if_then_else:SI
2149             (ne (reg:CC 17) (const_int 0))
2150           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2151           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2152   "  GET_CODE (operands[1]) == CONST_INT
2153   && GET_CODE (operands[2]) == CONST_INT
2154   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
2155       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2156   "* return mcore_output_cmov (operands, 1, NULL);"
2157   [(set_attr "length" "4")])
2159 (define_insn "movt0"
2160   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2161         (if_then_else:SI
2162          (ne (reg:CC 17) (const_int 0))
2163          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2164          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2165   ""
2166   "@
2167     movt        %0,%1
2168     movf        %0,%2
2169     clrt        %0
2170     clrf        %0")
2172 ;; ------------------------------------------------------------------------
2173 ;; eq
2174 ;; ------------------------------------------------------------------------
2176 ; experimental conditional move with two constants +/- 1  BRC
2177 (define_insn "movtK_2"
2178   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2179         (if_then_else:SI
2180             (eq (reg:CC 17) (const_int 0))
2181           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2182           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2183   "  GET_CODE (operands[1]) == CONST_INT
2184   && GET_CODE (operands[2]) == CONST_INT
2185   && (   (INTVAL (operands[1]) - INTVAL (operands[2]) == 1)
2186       || (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2187   "* return mcore_output_cmov (operands, 0, NULL);"
2188   [(set_attr "length" "4")])
2190 (define_insn "movf0"
2191   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2192         (if_then_else:SI
2193          (eq (reg:CC 17) (const_int 0))
2194          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2195          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2196   ""
2197   "@
2198     movf        %0,%1
2199     movt        %0,%2
2200     clrf        %0
2201     clrt        %0")
2203 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
2204 ; because the instructions are not adjacent (peepholes are related by posn -
2205 ; not by dataflow).   BRC
2207 (define_insn ""
2208   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2209         (if_then_else:SI (eq (zero_extract:SI 
2210                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2211                               (const_int 1)
2212                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
2213                              (const_int 0))
2214                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
2215                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
2216   ""
2217   "@
2218     btsti       %1,%2\;movf     %0,%3
2219     btsti       %1,%2\;movt     %0,%4
2220     btsti       %1,%2\;clrf     %0
2221     btsti       %1,%2\;clrt     %0"
2222   [(set_attr "length" "4")])
2224 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
2226 (define_insn ""
2227   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2228         (if_then_else:SI (eq (lshiftrt:SI 
2229                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2230                               (const_int 7))
2231                              (const_int 0))
2232                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2233                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2234   "GET_CODE (operands[1]) == SUBREG && 
2235       GET_MODE (SUBREG_REG (operands[1])) == QImode"
2236   "@
2237     btsti       %1,7\;movf      %0,%2
2238     btsti       %1,7\;movt      %0,%3
2239     btsti       %1,7\;clrf      %0
2240     btsti       %1,7\;clrt      %0"
2241   [(set_attr "length" "4")])
2244 ;; ------------------------------------------------------------------------
2245 ;; ne
2246 ;; ------------------------------------------------------------------------
2248 ;; Combine creates this from an andn instruction in a scc sequence.
2249 ;; We must recognize it to get conditional moves generated.
2251 ; experimental conditional move with two constants +/- 1  BRC
2252 (define_insn "movtK_3"
2253   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2254         (if_then_else:SI
2255             (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2256                 (const_int 0))
2257           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2258           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2259   "  GET_CODE (operands[2]) == CONST_INT
2260   && GET_CODE (operands[3]) == CONST_INT
2261   && (   (INTVAL (operands[2]) - INTVAL (operands[3]) == 1)
2262       || (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2263   "*
2265   rtx out_operands[4];
2266   out_operands[0] = operands[0];
2267   out_operands[1] = operands[2];
2268   out_operands[2] = operands[3];
2269   out_operands[3] = operands[1];
2271   return mcore_output_cmov (out_operands, 1, \"cmpnei   %3,0\");
2274   [(set_attr "length" "6")])
2276 (define_insn "movt2"
2277   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2278         (if_then_else:SI (ne (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2279                              (const_int 0))
2280                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2281                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2282   ""      
2283   "@
2284     cmpnei      %1,0\;movt      %0,%2
2285     cmpnei      %1,0\;movf      %0,%3
2286     cmpnei      %1,0\;clrt      %0
2287     cmpnei      %1,0\;clrf      %0"
2288   [(set_attr "length" "4")])
2290 ; turns lsli rx,imm/btsti rx,31 into btsti rx,imm.  not done by a peephole
2291 ; because the instructions are not adjacent (peepholes are related by posn -
2292 ; not by dataflow).   BRC
2294 (define_insn ""
2295  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2296         (if_then_else:SI (ne (zero_extract:SI 
2297                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2298                               (const_int 1)
2299                               (match_operand:SI 2 "mcore_literal_K_operand" "K,K,K,K"))
2300                              (const_int 0))
2301                          (match_operand:SI 3 "mcore_arith_imm_operand" "r,0,U,0")
2302                          (match_operand:SI 4 "mcore_arith_imm_operand" "0,r,0,U")))]
2303   ""
2304   "@
2305     btsti       %1,%2\;movt     %0,%3
2306     btsti       %1,%2\;movf     %0,%4
2307     btsti       %1,%2\;clrt     %0
2308     btsti       %1,%2\;clrf     %0"
2309   [(set_attr "length" "4")])
2311 ; turns sextb rx/btsti rx,31 into btsti rx,7.  must be QImode to be safe.  BRC
2313 (define_insn ""
2314   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2315         (if_then_else:SI (ne (lshiftrt:SI 
2316                               (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2317                               (const_int 7))
2318                              (const_int 0))
2319                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2320                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2321   "GET_CODE (operands[1]) == SUBREG && 
2322       GET_MODE (SUBREG_REG (operands[1])) == QImode"
2323   "@
2324     btsti       %1,7\;movt      %0,%2
2325     btsti       %1,7\;movf      %0,%3
2326     btsti       %1,7\;clrt      %0
2327     btsti       %1,7\;clrf      %0"
2328   [(set_attr "length" "4")])
2330 ;; ------------------------------------------------------------------------
2331 ;; eq/eq
2332 ;; ------------------------------------------------------------------------
2334 ; experimental conditional move with two constants +/- 1  BRC
2335 (define_insn "movtK_4"
2336   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2337         (if_then_else:SI
2338             (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2339           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2340           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2341   "GET_CODE (operands[1]) == CONST_INT &&
2342    GET_CODE (operands[2]) == CONST_INT &&
2343    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2344    (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2345   "* return mcore_output_cmov(operands, 1, NULL);"
2346   [(set_attr "length" "4")])
2348 (define_insn "movt3"
2349   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2350         (if_then_else:SI
2351          (eq (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2352          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2353          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2354   ""
2355   "@
2356     movt        %0,%1
2357     movf        %0,%2
2358     clrt        %0
2359     clrf        %0")
2361 ;; ------------------------------------------------------------------------
2362 ;; eq/ne
2363 ;; ------------------------------------------------------------------------
2365 ; experimental conditional move with two constants +/- 1  BRC
2366 (define_insn "movtK_5"
2367   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2368         (if_then_else:SI
2369             (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2370           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2371           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2372   "GET_CODE (operands[1]) == CONST_INT &&
2373    GET_CODE (operands[2]) == CONST_INT &&
2374    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2375     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2376   "* return mcore_output_cmov (operands, 0, NULL);"
2377   [(set_attr "length" "4")])
2379 (define_insn "movf1"
2380   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2381         (if_then_else:SI
2382          (eq (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2383          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2384          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2385   ""
2386   "@
2387     movf        %0,%1
2388     movt        %0,%2
2389     clrf        %0
2390     clrt        %0")
2392 ;; ------------------------------------------------------------------------
2393 ;; eq
2394 ;; ------------------------------------------------------------------------
2396 ;; Combine creates this from an andn instruction in a scc sequence.
2397 ;; We must recognize it to get conditional moves generated.
2399 ; experimental conditional move with two constants +/- 1  BRC
2401 (define_insn "movtK_6"
2402   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2403         (if_then_else:SI
2404             (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2405                 (const_int 0))
2406           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2407           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2408   "GET_CODE (operands[1]) == CONST_INT &&
2409    GET_CODE (operands[2]) == CONST_INT &&
2410    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2411     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2412   "* 
2414    rtx out_operands[4];
2415    out_operands[0] = operands[0];
2416    out_operands[1] = operands[2];
2417    out_operands[2] = operands[3];
2418    out_operands[3] = operands[1];
2420    return mcore_output_cmov (out_operands, 0, \"cmpnei  %3,0\");
2422   [(set_attr "length" "6")])
2424 (define_insn "movf3"
2425   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2426         (if_then_else:SI (eq (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2427                              (const_int 0))
2428                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2429                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2430   ""
2431   "@
2432     cmpnei      %1,0\;movf      %0,%2
2433     cmpnei      %1,0\;movt      %0,%3
2434     cmpnei      %1,0\;clrf      %0
2435     cmpnei      %1,0\;clrt      %0"
2436   [(set_attr "length" "4")])
2438 ;; ------------------------------------------------------------------------
2439 ;; ne/eq
2440 ;; ------------------------------------------------------------------------
2442 ; experimental conditional move with two constants +/- 1  BRC
2443 (define_insn "movtK_7"
2444   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2445         (if_then_else:SI
2446             (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2447           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2448           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2449   "GET_CODE (operands[1]) == CONST_INT &&
2450    GET_CODE (operands[2]) == CONST_INT &&
2451    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2452     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2453   "* return mcore_output_cmov (operands, 0, NULL);"
2454   [(set_attr "length" "4")])
2456 (define_insn "movf4"
2457   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2458         (if_then_else:SI
2459          (ne (eq:SI (reg:CC 17) (const_int 0)) (const_int 0))
2460          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2461          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2462   ""
2463   "@
2464     movf        %0,%1
2465     movt        %0,%2
2466     clrf        %0
2467     clrt        %0")
2469 ;; ------------------------------------------------------------------------
2470 ;; ne/ne
2471 ;; ------------------------------------------------------------------------
2473 ; experimental conditional move with two constants +/- 1  BRC
2474 (define_insn "movtK_8"
2475   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2476         (if_then_else:SI
2477             (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2478           (match_operand:SI 1 "mcore_arith_O_operand" "O")
2479           (match_operand:SI 2 "mcore_arith_O_operand" "O")))]
2480   "GET_CODE (operands[1]) == CONST_INT &&
2481    GET_CODE (operands[2]) == CONST_INT &&
2482    ((INTVAL (operands[1]) - INTVAL (operands[2]) == 1) ||
2483     (INTVAL (operands[2]) - INTVAL (operands[1]) == 1))"
2484   "* return mcore_output_cmov (operands, 1, NULL);"
2485   [(set_attr "length" "4")])
2487 (define_insn "movt4"
2488   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2489         (if_then_else:SI
2490          (ne (ne:SI (reg:CC 17) (const_int 0)) (const_int 0))
2491          (match_operand:SI 1 "mcore_arith_imm_operand" "r,0,U,0")
2492          (match_operand:SI 2 "mcore_arith_imm_operand" "0,r,0,U")))]
2493   ""
2494   "@
2495     movt        %0,%1
2496     movf        %0,%2
2497     clrt        %0
2498     clrf        %0")
2500 ;; Also need patterns to recognize lt/ge, since otherwise the compiler will
2501 ;; try to output not/asri/tstne/movf.
2503 ;; ------------------------------------------------------------------------
2504 ;; lt
2505 ;; ------------------------------------------------------------------------
2507 ; experimental conditional move with two constants +/- 1  BRC
2508 (define_insn "movtK_9"
2509   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2510         (if_then_else:SI
2511             (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2512                 (const_int 0))
2513           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2514           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2515   "GET_CODE (operands[2]) == CONST_INT &&
2516    GET_CODE (operands[3]) == CONST_INT &&
2517    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2518     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2519   "*
2521    rtx out_operands[4];
2522    out_operands[0] = operands[0];
2523    out_operands[1] = operands[2];
2524    out_operands[2] = operands[3];
2525    out_operands[3] = operands[1];
2527    return mcore_output_cmov (out_operands, 1, \"btsti   %3,31\");
2529   [(set_attr "length" "6")])
2531 (define_insn "movt5"
2532   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2533         (if_then_else:SI (lt (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2534                              (const_int 0))
2535                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2536                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2537   ""
2538   "@
2539     btsti       %1,31\;movt     %0,%2
2540     btsti       %1,31\;movf     %0,%3
2541     btsti       %1,31\;clrt     %0
2542     btsti       %1,31\;clrf     %0"
2543   [(set_attr "length" "4")])
2546 ;; ------------------------------------------------------------------------
2547 ;; ge
2548 ;; ------------------------------------------------------------------------
2550 ; experimental conditional move with two constants +/- 1  BRC
2551 (define_insn "movtK_10"
2552   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2553         (if_then_else:SI
2554             (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r") 
2555                 (const_int 0))
2556           (match_operand:SI 2 "mcore_arith_O_operand" "O")
2557           (match_operand:SI 3 "mcore_arith_O_operand" "O")))]
2558   "GET_CODE (operands[2]) == CONST_INT &&
2559    GET_CODE (operands[3]) == CONST_INT &&
2560    ((INTVAL (operands[2]) - INTVAL (operands[3]) == 1) ||
2561     (INTVAL (operands[3]) - INTVAL (operands[2]) == 1))"
2562   "*
2564   rtx out_operands[4];
2565   out_operands[0] = operands[0];
2566   out_operands[1] = operands[2];
2567   out_operands[2] = operands[3];
2568   out_operands[3] = operands[1];
2570    return mcore_output_cmov (out_operands, 0, \"btsti   %3,31\");
2572   [(set_attr "length" "6")])
2574 (define_insn "movf5"
2575   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,r,r,r")
2576         (if_then_else:SI (ge (match_operand:SI 1 "mcore_arith_reg_operand" "r,r,r,r")
2577                              (const_int 0))
2578                          (match_operand:SI 2 "mcore_arith_imm_operand" "r,0,U,0")
2579                          (match_operand:SI 3 "mcore_arith_imm_operand" "0,r,0,U")))]
2580   ""
2581   "@
2582     btsti       %1,31\;movf     %0,%2
2583     btsti       %1,31\;movt     %0,%3
2584     btsti       %1,31\;clrf     %0
2585     btsti       %1,31\;clrt     %0"
2586   [(set_attr "length" "4")])
2588 ;; ------------------------------------------------------------------------
2589 ;; Bitfield extract (xtrbN)
2590 ;; ------------------------------------------------------------------------
2592 ; sometimes we're better off using QI/HI mode and letting the machine indep.
2593 ; part expand insv and extv.
2595 ; e.g., sequences like:a        [an insertion]
2597 ;      ldw r8,(r6)
2598 ;      movi r7,0x00ffffff
2599 ;      and r8,r7                 r7 dead
2600 ;      stw r8,(r6)                r8 dead
2602 ; become:
2604 ;      movi r8,0
2605 ;      stb r8,(r6)              r8 dead
2607 ; it looks like always using SI mode is a win except in this type of code 
2608 ; (when adjacent bit fields collapse on a byte or halfword boundary).  when
2609 ; expanding with SI mode, non-adjacent bit field masks fold, but with QI/HI
2610 ; mode, they do not.  one thought is to add some peepholes to cover cases
2611 ; like the above, but this is not a general solution.
2613 ; -mword-bitfields expands/inserts using SI mode.  otherwise, do it with
2614 ; the smallest mode possible (using the machine indep. expansions).  BRC
2616 ;(define_expand "extv"
2617 ;  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2618 ;       (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2619 ;                        (match_operand:SI 2 "const_int_operand" "")
2620 ;                        (match_operand:SI 3 "const_int_operand" "")))
2621 ;   (clobber (reg:CC 17))]
2622 ;  ""
2623 ;  "
2625 ;  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) % 8 != 0)
2626 ;    {
2627 ;     if (TARGET_W_FIELD)
2628 ;       {
2629 ;        rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2630 ;        rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2632 ;        emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2633 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2634 ;                            gen_rtx_ASHIFT (SImode, operands[0], lshft)));
2635 ;        emit_insn (gen_rtx_SET (SImode, operands[0],
2636 ;                            gen_rtx_ASHIFTRT (SImode, operands[0], rshft)));
2637 ;        DONE;
2638 ;     }
2639 ;     else
2640 ;        FAIL;
2641 ;  }
2642 ;}")
2644 (define_expand "extv"
2645   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2646         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2647                          (match_operand:SI 2 "const_int_operand" "")
2648                          (match_operand:SI 3 "const_int_operand" "")))
2649    (clobber (reg:CC 17))]
2650   ""
2651   "
2653   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2654     {
2655        /* 8 bit field, aligned properly, use the xtrb[0123]+sext sequence.  */
2656        /* not DONE, not FAIL, but let the RTL get generated....  */
2657     }
2658   else if (TARGET_W_FIELD)
2659     {
2660       /* Arbitrary placement; note that the tree->rtl generator will make
2661          something close to this if we return FAIL  */
2662       rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2663       rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2664       rtx tmp1 = gen_reg_rtx (SImode);
2665       rtx tmp2 = gen_reg_rtx (SImode);
2667       emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2668       emit_insn (gen_rtx_SET (SImode, tmp2,
2669                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2670       emit_insn (gen_rtx_SET (SImode, operands[0],
2671                          gen_rtx_ASHIFTRT (SImode, tmp2, rshft)));
2672       DONE;
2673     }
2674   else
2675     {
2676       /* Let the caller choose an alternate sequence.  */
2677       FAIL;
2678     }
2681 (define_expand "extzv"
2682   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
2683         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "")
2684                          (match_operand:SI 2 "const_int_operand" "")
2685                          (match_operand:SI 3 "const_int_operand" "")))
2686    (clobber (reg:CC 17))]
2687   ""
2688   "
2690   if (INTVAL (operands[2]) == 8 && INTVAL (operands[3]) % 8 == 0)
2691     {
2692        /* 8 bit field, aligned properly, use the xtrb[0123] sequence.  */
2693        /* Let the template generate some RTL....  */
2694     }
2695   else if (CONST_OK_FOR_K ((1 << INTVAL (operands[2])) - 1))
2696     {
2697       /* A narrow bit-field (<=5 bits) means we can do a shift to put
2698          it in place and then use an andi to extract it.
2699          This is as good as a shiftleft/shiftright.  */
2701       rtx shifted;
2702       rtx mask = GEN_INT ((1 << INTVAL (operands[2])) - 1);
2704       if (INTVAL (operands[3]) == 0)
2705         {
2706           shifted = operands[1];
2707         }
2708       else
2709         {
2710           rtx rshft = GEN_INT (INTVAL (operands[3]));
2711           shifted = gen_reg_rtx (SImode);
2712           emit_insn (gen_rtx_SET (SImode, shifted,
2713                          gen_rtx_LSHIFTRT (SImode, operands[1], rshft)));
2714         }
2715      emit_insn (gen_rtx_SET (SImode, operands[0],
2716                        gen_rtx_AND (SImode, shifted, mask)));
2717      DONE;
2718    }
2719  else if (TARGET_W_FIELD)
2720    {
2721      /* Arbitrary pattern; play shift/shift games to get it. 
2722       * this is pretty much what the caller will do if we say FAIL */
2723      rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) + INTVAL (operands[3])));
2724      rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
2725      rtx tmp1 = gen_reg_rtx (SImode);
2726      rtx tmp2 = gen_reg_rtx (SImode);
2728      emit_insn (gen_rtx_SET (SImode, tmp1, operands[1]));
2729      emit_insn (gen_rtx_SET (SImode, tmp2,
2730                          gen_rtx_ASHIFT (SImode, tmp1, lshft)));
2731      emit_insn (gen_rtx_SET (SImode, operands[0],
2732                        gen_rtx_LSHIFTRT (SImode, tmp2, rshft)));
2733      DONE;
2734    }
2735  else
2736    {
2737      /* Make the compiler figure out some alternative mechanism.  */
2738      FAIL;
2739    }
2741  /* Emit the RTL pattern; something will match it later.  */
2744 (define_expand "insv"
2745   [(set (zero_extract:SI (match_operand:SI 0 "mcore_arith_reg_operand" "")
2746                          (match_operand:SI 1 "const_int_operand" "")
2747                          (match_operand:SI 2 "const_int_operand" ""))
2748         (match_operand:SI 3 "general_operand" ""))
2749    (clobber (reg:CC 17))]
2750   ""
2751   "
2753   if (mcore_expand_insv (operands))
2754     {
2755       DONE;
2756     }
2757   else
2758     {
2759       FAIL;
2760     }
2764 ;; the xtrb[0123] instructions handily get at 8-bit fields on nice boundaries.
2765 ;; but then, they do force you through r1.
2767 ;; the combiner will build such patterns for us, so we'll make them available
2768 ;; for its use.
2770 ;; Note that we have both SIGNED and UNSIGNED versions of these...
2774 ;; These no longer worry about the clobbering of CC bit; not sure this is
2775 ;; good...
2777 ;; the SIGNED versions of these
2779 (define_insn ""
2780   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2781         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2782   ""
2783   "@
2784         asri    %0,24
2785         xtrb0   %0,%1\;sextb    %0"
2786   [(set_attr "type" "shift")])
2788 (define_insn ""
2789   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2790         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2791   ""
2792   "xtrb1        %0,%1\;sextb    %0"
2793   [(set_attr "type" "shift")])
2795 (define_insn ""
2796   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2797         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2798   ""
2799   "xtrb2        %0,%1\;sextb    %0"
2800   [(set_attr "type" "shift")])
2802 (define_insn ""
2803   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r")
2804         (sign_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0") (const_int 8) (const_int 0)))]
2805   ""
2806   "sextb        %0"
2807   [(set_attr "type" "shift")])
2809 ;; the UNSIGNED uses of xtrb[0123]
2811 (define_insn ""
2812   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2813         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 24)))]
2814   ""
2815   "@
2816         lsri    %0,24
2817         xtrb0   %0,%1"
2818   [(set_attr "type" "shift")])
2820 (define_insn ""
2821   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2822         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 16)))]
2823   ""
2824   "xtrb1        %0,%1"
2825   [(set_attr "type" "shift")])
2827 (define_insn ""
2828   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=b")
2829         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "r") (const_int 8) (const_int 8)))]
2830   ""
2831   "xtrb2        %0,%1"
2832   [(set_attr "type" "shift")])
2834 ;; This can be peepholed if it follows a ldb ...
2835 (define_insn ""
2836   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "=r,b")
2837         (zero_extract:SI (match_operand:SI 1 "mcore_arith_reg_operand" "0,r") (const_int 8) (const_int 0)))]
2838   ""
2839   "@
2840         zextb   %0
2841         xtrb3   %0,%1\;zextb    %0"
2842   [(set_attr "type" "shift")])
2845 ;; ------------------------------------------------------------------------
2846 ;; Block move - adapted from m88k.md
2847 ;; ------------------------------------------------------------------------
2849 (define_expand "movmemsi"
2850   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2851                    (mem:BLK (match_operand:BLK 1 "" "")))
2852               (use (match_operand:SI 2 "general_operand" ""))
2853               (use (match_operand:SI 3 "immediate_operand" ""))])]
2854   ""
2855   "
2857   if (mcore_expand_block_move (operands))
2858     DONE;
2859   else
2860     FAIL;
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.  i.e., 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       /* Perform 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     }