* varasm.c (bss_initializer_p): Remove static.
[official-gcc.git] / gcc / config / epiphany / epiphany.md
blobfb55e3846fd128ee3fa00397fcd7d687023a2ad7
1 ;; Machine description of the Adaptiva epiphany cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007, 2009, 2010,
3 ;; 2011, 2012 Free Software Foundation, Inc.
4 ;; Contributed by Embecosm on behalf of Adapteva, Inc.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 (define_constants
25   [(GPR_0                        0)
26    (GPR_FP                      11)
27    (GPR_IP                      12)
28    (GPR_SP                      13)
29    (GPR_LR                      14)
30    (GPR_16                      16)
31    (GPR_18                      18)
32    (GPR_20                      20)
33    (ARG_POINTER_REGNUM          64)
34    (FRAME_POINTER_REGNUM        65)
35    (CC_REGNUM                   66)   ;; 66 or 17
36    (CCFP_REGNUM                 67)   ;; 67 or 18
37    (CONFIG_REGNUM               68)
38    (STATUS_REGNUM               69)
39    (LC_REGNUM                   70)
40    (LS_REGNUM                   71)
41    (LE_REGNUM                   72)
42    (IRET_REGNUM                 73)
43    (FP_NEAREST_REGNUM           74)
44    (FP_TRUNCATE_REGNUM          75)
45    (FP_ANYFP_REGNUM             76)
46    (UNKNOWN_REGNUM              77) ; used for addsi3_r and friends
47    ; We represent the return address as an unspec rather than a reg.
48    ; If we used a reg, we could use register elimination, but eliminating
49    ; to GPR_LR would make the latter visible to dataflow, thus making it
50    ; harder to determine when it must be saved.
51    (UNSPEC_RETURN_ADDR           0)
52    (UNSPEC_FP_MODE               1)
54    (UNSPECV_GID                  0)
55    (UNSPECV_GIE                  1)])
57 ;; Insn type.  Used to default other attribute values.
59 (define_attr "type"
60   "move,load,store,cmove,unary,compare,shift,mul,uncond_branch,branch,call,fp,fp_int,v2fp,misc,sfunc,fp_sfunc,flow"
61   (const_string "misc"))
63 ;; Length (in # bytes)
65 (define_attr "length" "" (const_int 4))
67 ;; The length here is the length of a single asm.
69 (define_asm_attributes
70   [(set_attr "length" "4")
71    (set_attr "type" "misc")])
73 ;; pipeline model; so far we have only one.
74 (define_attr "pipe_model" "epiphany" (const_string "epiphany"))
76 (define_attr "rounding" "trunc,nearest"
77   (cond [(ne (symbol_ref "TARGET_ROUND_NEAREST") (const_int 0))
78          (const_string "nearest")]
79         (const_string "trunc")))
81 (define_attr "fp_mode" "round_unknown,round_nearest,round_trunc,int,caller,none"
82   (cond [(eq_attr "type" "fp,v2fp,fp_sfunc")
83          (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_rounding")
84          (eq_attr "type" "call")
85          (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_mode")
86          (eq_attr "type" "fp_int")
87          (const_string "int")]
88         (const_string "none")))
90 (include "epiphany-sched.md")
92 (include "predicates.md")
93 (include "constraints.md")
95 ;; modes that are held in a single register, and hence, a word.
96 (define_mode_iterator WMODE [SI SF HI QI V2HI V4QI])
97 (define_mode_iterator WMODE2 [SI SF HI QI V2HI V4QI])
99 ;; modes that are held in a two single registers
100 (define_mode_iterator DWMODE [DI DF V2SI V2SF V4HI V8QI])
102 ;; Double-word mode made up of two single-word mode values.
103 (define_mode_iterator DWV2MODE [V2SI V2SF])
104 (define_mode_attr vmode_part [(V2SI "si") (V2SF "sf")])
105 (define_mode_attr vmode_PART [(V2SI "SI") (V2SF "SF")])
106 (define_mode_attr vmode_fp_type [(V2SI "fp_int") (V2SF "fp")])
107 (define_mode_attr vmode_ccmode [(V2SI "CC") (V2SF "CC_FP")])
108 (define_mode_attr vmode_cc [(V2SI "CC_REGNUM") (V2SF "CCFP_REGNUM")])
110 ;; Move instructions.
112 (define_expand "mov<mode>"
113   [(set (match_operand:WMODE 0 "general_operand" "")
114         (match_operand:WMODE 1 "general_operand" ""))]
115   ""
117   if (<MODE>mode == V4QImode || <MODE>mode == V2HImode)
118     {
119       operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
120       operands[1] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
121       emit_insn (gen_movsi (operands[0], operands[1]));
122       DONE;
123     }
124   if (GET_CODE (operands[0]) == MEM)
125     operands[1] = force_reg (<MODE>mode, operands[1]);
126   if (<MODE>mode == SImode
127       && (operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx))
128     {
129       rtx reg = operands[0];
131       if (!REG_P (reg))
132         reg = gen_reg_rtx (SImode);
133       emit_insn (gen_move_frame (reg, operands[1]));
134       operands[1] = reg;
135       if (operands[0] == reg)
136         DONE;
137     }
140 (define_insn "*movqi_insn"
141   [(set (match_operand:QI 0 "move_dest_operand" "=Rcs,   r,  r,r,m")
142         (match_operand:QI 1 "move_src_operand"   "Rcs,rU16,Cal,m,r"))]
143 ;; ??? Needed?
144   "gpr_operand (operands[0], QImode)
145    || gpr_operand (operands[1], QImode)"
146   "@
147    mov %0,%1
148    mov %0,%1
149    mov %0,%1
150    ldrb %0,%1
151    strb %1,%0"
152   [(set_attr "type" "move,move,move,load,store")])
154 (define_insn_and_split "*movhi_insn"
155   [(set (match_operand:HI 0 "move_dest_operand" "=r,  r,r,m")
156         (match_operand:HI 1 "move_src_operand""rU16,Cal,m,r"))]
157   "gpr_operand (operands[0], HImode)
158    || gpr_operand (operands[1], HImode)"
159   "@
160    mov %0,%1
161    mov %0,%%low(%1); %1
162    ldrh %0,%c1
163    strh %1,%c0"
164   "reload_completed && CONSTANT_P (operands[1])
165    && !satisfies_constraint_U16 (operands[1]) && TARGET_SPLIT_LOHI"
166   [(set (match_dup 2) (match_dup 3))]
167   "operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
168    operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);"
169   [(set_attr "type" "move,move,load,store")])
171 ;; We use a special pattern for a move from the frame pointer to
172 ;; show the flag clobber that is needed when this move is changed
173 ;; to an add by register elimination.
174 ;; ??? A pseudo register might be equivalent to a function invariant,
175 ;; and thus placed by reload into reg_equiv_invariant; if the pseudo
176 ;; does not get a hard register, we then end up with the function
177 ;; invariant in its place, i.e. an unexpected clobber of the flags
178 ;; register.
180 ;; N.B. operand 1 is an operand so that reload will perform elimination.
182 ;; The post-reload pattern recognition and splitting is done in frame_move_1.
183 (define_insn "move_frame"
184   [(set (match_operand:SI 0 "gpr_operand" "=r")
185         (match_operand:SI 1 "register_operand" "r"))
186    (clobber (reg:CC CC_REGNUM))]
187   "operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx"
188   "#")
190 (define_insn "movsi_high"
191   [(set (match_operand:SI 0 "gpr_operand" "+r")
192         (ior:SI (and:SI (match_dup 0) (const_int 65535))
193                 (high:SI (match_operand:SI 1 "move_src_operand" "i"))))]
194   ""
195   "movt %0, %%high(%1)"
196   [(set_attr "type" "move")
197    (set_attr "length" "4")])
199 (define_insn "movsi_lo_sum"
200   [(set (match_operand:SI 0 "gpr_operand" "=r")
201         (lo_sum:SI (const_int 0)
202                    (match_operand:SI 1 "move_src_operand" "i")))]
203   ""
204   "mov %0, %%low(%1)"
205   [(set_attr "type" "move")
206    (set_attr "length" "4")])
208 (define_insn_and_split "*movsi_insn"
209   [(set (match_operand:SI 0 "move_dest_operand"
210          "=   r,  r,  r,  r,  r,   r,   m,  r,  Rct")
211         (match_operand:SI 1 "move_src_operand"
212          "rU16Rra,Cm1,Cl1,Cr1,Cal,mSra,rRra,Rct,r"))]
213   "gpr_operand (operands[0], SImode)
214    || gpr_operand (operands[1], SImode)
215    || satisfies_constraint_Sra (operands[1])"
217   switch (which_alternative)
218     {
219     case 0: return "mov %0,%1";
220     case 1: return "add %0,%-,(1+%1)";
221     case 2: operands[1] = GEN_INT (exact_log2 (-INTVAL (operands[1])));
222       return "lsl %0,%-,%1";
223     case 3: operands[1] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
224       return "lsr %0,%-,%1";
225     case 4: return "mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1";
226     case 5: return "ldr %0,%C1";
227     case 6: return "str %1,%C0";
228     case 7: return "movfs %0,%1";
229     case 8: return "movts %0,%1";
230     default: gcc_unreachable ();
231     }
233   "reload_completed && CONSTANT_P (operands[1])
234    && !satisfies_constraint_U16 (operands[1])
235    && !satisfies_constraint_Cm1 (operands[1])
236    && !satisfies_constraint_Cl1 (operands[1])
237    && !satisfies_constraint_Cr1 (operands[1])
238    && TARGET_SPLIT_LOHI"
239   [(match_dup 2) (match_dup 3)]
240   "operands[2] = gen_movsi_lo_sum (operands[0], operands[1]);
241    operands[3] = gen_movsi_high (operands[0], operands[1]);"
242   [(set_attr "type" "move,misc,misc,misc,move,load,store,flow,flow")
243    (set_attr "length" "4,4,4,4,8,4,4,4,4")])
245 (define_split
246   [(set (match_operand:SI 0 "nonimmediate_operand")
247         (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
248   "reload_completed && !MACHINE_FUNCTION (cfun)->lr_clobbered"
249   [(set (match_dup 0) (reg:SI GPR_LR))])
251 (define_split
252   [(set (match_operand:SI 0 "gpr_operand")
253         (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
254   "reload_completed"
255   [(set (match_dup 0) (match_dup 1))]
257   emit_insn (gen_reload_insi_ra (operands[0], operands[1]));
258   DONE;
261 (define_expand "reload_insi_ra"
262   [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))]
263   ""
265   rtx addr
266     = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx);
268   addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
269   operands[1] = gen_frame_mem (SImode, addr);
272 ;; If the frame pointer elimination offset is zero, we'll use this pattern.
273 ;; Note that the splitter can accept any gpr in operands[1]; this is
274 ;; necessary, (e.g. for compile/20021015-1.c -O0,)
275 ;; because when register elimination cannot be done with the constant
276 ;; as an immediate operand of the add instruction, reload will resort to
277 ;; loading the constant into a reload register, using gen_add2_insn to add
278 ;; the stack pointer, and then use the reload register as new source in
279 ;; the move_frame pattern.
280 (define_insn_and_split "*move_frame_1"
281   [(set (match_operand:SI 0 "gpr_operand" "=r")
282         (match_operand:SI 1 "gpr_operand" "r"))
283    (clobber (reg:CC CC_REGNUM))]
284   "(reload_in_progress || reload_completed)
285    && (operands[1] == stack_pointer_rtx
286        || operands[1] == hard_frame_pointer_rtx)"
287   "#"
288   "reload_in_progress || reload_completed"
289   [(set (match_dup 0) (match_dup 1))])
291 (define_expand "mov<mode>"
292   [(set (match_operand:DWMODE 0 "general_operand" "")
293         (match_operand:DWMODE 1 "general_operand" ""))]
294   ""
295   "
297   if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT
298       || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
299     {
300       if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)
301         {
302           rtx o0l, o0h, o1l, o1h;
304           o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
305           o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode,
306                                      UNITS_PER_WORD);
307           o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
308           o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode,
309                                      UNITS_PER_WORD);
310           if (reg_overlap_mentioned_p (o0l, o1h))
311             {
312               emit_move_insn (o0h, o1h);
313               emit_move_insn (o0l, o1l);
314             }
315           else
316             {
317               emit_move_insn (o0l, o1l);
318               emit_move_insn (o0h, o1h);
319             }
320           DONE;
321         }
322       /* lower_subreg has a tendency to muck up vectorized code.
323          To protect the wide memory accesses, we must use same-size
324          subregs.  */
325       if (epiphany_vect_align != 4 /* == 8 */
326           && !reload_in_progress
327           && (GET_CODE (operands[0]) == MEM || GET_CODE (operands[1]) == MEM)
328           && !misaligned_operand (operands[1], <MODE>mode)
329           && (GET_CODE (operands[0]) != SUBREG
330               || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
331                   != GET_MODE_SIZE (<MODE>mode)
332                   && GET_CODE (operands[1]) != SUBREG)))
333         {
334           operands[0]
335             = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0);
336           operands[1]
337             = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0);
338           emit_insn (gen_movdi (operands[0], operands[1]));
339           DONE;
340         }
341     }
342   /* Everything except mem = const or mem = mem can be done easily.  */
344   if (GET_CODE (operands[0]) == MEM)
345     operands[1] = force_reg (<MODE>mode, operands[1]);
348 (define_insn_and_split "*mov<mode>_insn"
349   [(set (match_operand:DWMODE 0 "move_dest_operand"      "=r,   r,r,m")
350         (match_operand:DWMODE 1 "move_double_src_operand" "r,CalE,m,r"))]
351   "(gpr_operand (operands[0], <MODE>mode)
352     || gpr_operand (operands[1], <MODE>mode))"
353   "@
354    #
355    #
356    ldrd %0,%X1
357    strd %1,%X0"
358   "reload_completed
359    && (((!MEM_P (operands[0]) || misaligned_operand (operands[0], <MODE>mode))
360         && (!MEM_P (operands[1])
361             || misaligned_operand (operands[1], <MODE>mode)))
362        || epiphany_vect_align == 4)"
363   [(set (match_dup 2) (match_dup 3))
364    (set (match_dup 4) (match_dup 5))]
366   int word0 = 0, word1 = UNITS_PER_WORD;
368   if (post_modify_operand (operands[0], <MODE>mode)
369       || post_modify_operand (operands[1], <MODE>mode))
370     word0 = UNITS_PER_WORD, word1 = 0;
372   operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
373   operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
374   operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
375   operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
376   if (post_modify_operand (operands[0], <MODE>mode))
377     operands[2]
378       = change_address (operands[2], VOIDmode,
379                         plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0),
380                                        UNITS_PER_WORD));
381   if (post_modify_operand (operands[1], <MODE>mode))
382     operands[3]
383       = change_address (operands[3], VOIDmode,
384                         plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0),
385                                        UNITS_PER_WORD));
387   [(set_attr "type" "move,move,load,store")
388    (set_attr "length" "8,16,4,4")])
391 (define_insn_and_split "*movsf_insn"
392   [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
393         (match_operand:SF 1 "move_src_operand"   "r,E,m,r"))]
394   "gpr_operand (operands[0], SFmode)
395    || gpr_operand (operands[1], SFmode)"
396   "@
397    mov %0,%1
398    mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
399    ldr %0,%C1
400    str %1,%C0"
401   "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
402   [(set (match_dup 2) (match_dup 3))]
403   "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
404    operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
405   [(set_attr "type" "move,move,load,store")
406    (set_attr "length" "4,8,4,4")])
408 (define_expand "addsi3"
409   [(set (match_operand:SI 0 "add_reg_operand" "")
410         (plus:SI (match_operand:SI 1 "add_reg_operand" "")
411                  (match_operand:SI 2 "add_operand" "")))]
412   ""
413   "
415   if (reload_in_progress || reload_completed)
416     emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
417   else if (TARGET_FP_IARITH && add_reg_operand (operands[2], SImode))
418     emit_insn (gen_iadd (operands[0], operands[1], operands[2]));
419   else
420     emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
421   DONE;
424 (define_insn "addsi3_i"
425   [(set (match_operand:SI 0 "add_reg_operand" "=r")
426         (plus:SI (match_operand:SI 1 "add_reg_operand" "%r")
427                  (match_operand:SI 2 "add_operand" "rL")))
428    (clobber (reg:CC CC_REGNUM))]
429   ""
430   "add %0,%1,%2"
431 [(set_attr "type" "misc")])
433 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
434 ; can identify the unresolved flags clobber problem, and also to
435 ; avoid unwanted matches.
437 ; At -O0 / -O1 we don't peephole all instances away.  We could get better
438 ; debug unwinding through the emitted code if we added a splitter.
439 (define_insn "addsi3_r"
440   [(set (match_operand:SI 0 "gpr_operand" "=r")
441         (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
442                  (match_operand:SI 2 "nonmemory_operand" "rCar")))
443    (clobber (reg:CC UNKNOWN_REGNUM))]
444   "reload_in_progress || reload_completed"
446   int scratch = (0x17
447                  ^ (true_regnum (operands[0]) & 1)
448                  ^ (true_regnum (operands[1]) & 2)
449                  ^ (true_regnum (operands[2]) & 4));
450   asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
451   asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
452   output_asm_insn ("add %0,%1,%2", operands);
453   asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
454   asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
455   return "";
457   [(set_attr "length" "20")
458    (set_attr "type" "misc")])
460 ;; reload uses gen_addsi2 because it doesn't understand the need for
461 ;; the clobber.
462 (define_peephole2
463   [(set (match_operand:SI 0 "gpr_operand" "")
464         (match_operand:SI 1 "const_int_operand" ""))
465    (parallel [(set (match_dup 0)
466                    (plus:SI (match_dup 0)
467                             (match_operand:SI 2 "gpr_operand")))
468               (clobber (reg:CC UNKNOWN_REGNUM))])]
469   "satisfies_constraint_L (operands[1])
470    || ((operands[2] == stack_pointer_rtx
471         || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
472        && !peep2_regno_dead_p (2, CC_REGNUM)
473        && satisfies_constraint_Car (operands[1]))"
474   [(parallel [(set (match_dup 0)
475                    (plus:SI (match_dup 2) (match_dup 1)))
476               (clobber (reg:CC UNKNOWN_REGNUM))])]
477   ;; FIXME:
478   ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
479   ;; "peep2_rescan = true;"
482 (define_peephole2
483   [(match_parallel 5 ""
484      [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
485    (parallel [(set (match_operand:SI 0 "gpr_operand" "")
486                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
487                             (match_operand:SI 2 "nonmemory_operand" "")))
488               (clobber (reg:CC UNKNOWN_REGNUM))])]
489   "REGNO (operands[3]) == CC_REGNUM
490    && (gpr_operand (operands[2], SImode)
491        || satisfies_constraint_L (operands[2]))
492    && !reg_overlap_mentioned_p (operands[0], operands[5])
493    && !reg_set_p (operands[1], operands[5])
494    && !reg_set_p (operands[2], operands[5])"
495   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
496                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
497                             (match_operand:SI 2 "nonmemory_operand" "")))
498               (clobber (reg:CC CC_REGNUM))])
499    (match_dup 5)]
500   "")
502 (define_peephole2
503   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
504                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
505                             (match_operand:SI 2 "nonmemory_operand" "")))
506               (clobber (reg:CC UNKNOWN_REGNUM))])]
507   "peep2_regno_dead_p (1, CC_REGNUM)
508    && (gpr_operand (operands[2], SImode)
509        || satisfies_constraint_L (operands[2]))"
510   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
511                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
512                             (match_operand:SI 2 "nonmemory_operand" "")))
513               (clobber (reg:CC CC_REGNUM))])]
514   "")
516 (define_peephole2
517   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
518                    (plus:SI (reg:SI GPR_SP)
519                             (match_operand:SI 1 "nonmemory_operand" "")))
520               (clobber (reg:CC UNKNOWN_REGNUM))])]
521   "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
522    || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
523   [(set (match_dup 0) (reg:SI GPR_SP))
524    (set (mem:WMODE (post_modify (match_dup 0)
525                                 (plus:SI (match_dup 0) (match_dup 1))))
526         (reg:WMODE GPR_SP))]
527   "")
531 (define_peephole2
532   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
533                    (plus:SI (reg:SI GPR_FP)
534                             (match_operand:SI 1 "nonmemory_operand" "")))
535               (clobber (reg:CC UNKNOWN_REGNUM))])
536    (match_scratch:WMODE 2 "r")]
537   "frame_pointer_needed
538    && ((REG_P (operands[1])
539         && !reg_overlap_mentioned_p (operands[0], operands[1]))
540        || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
541   [(set (match_dup 0) (reg:SI GPR_FP))
542    (set (match_dup 2)
543         (mem:WMODE (post_modify (match_dup 0)
544                                 (plus:SI (match_dup 0) (match_dup 1)))))]
545   "")
547 (define_expand "subsi3"
548   [(set (match_operand:SI 0 "gpr_operand" "")
549         (plus:SI (match_operand:SI 1 "add_reg_operand" "")
550                  (match_operand:SI 2 "arith_operand" "")))]
551   ""
552   "
554   gcc_assert (!reload_in_progress && !reload_completed);
556   if (TARGET_FP_IARITH)
557     emit_insn (gen_isub (operands[0], operands[1], operands[2]));
558   else
559     emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2]));
560   DONE;
563 (define_insn "subsi3_i"
564   [(set (match_operand:SI 0 "gpr_operand" "=r")
565         (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
566                   (match_operand:SI 2 "arith_operand" "rL")))
567    (clobber (reg:CC CC_REGNUM))]
568   ""
569   "sub %0,%1,%2"
570   [(set_attr "type" "misc")])
572 ; After mode-switching, floating point operations, fp_sfuncs and calls
573 ; must exhibit the use of the control register, lest the setting of the
574 ; control register could be deleted or moved.  OTOH a use of a hard register
575 ; greatly coundounds optimizers like the rtl loop optimizers or combine.
576 ; Therefore, we put an extra pass immediately after the mode switching pass
577 ; that inserts the USEs of the control registers, and sets a flag in struct
578 ; machine_function that float_operation can henceforth only match with that
579 ; USE.
581 ;; Addition
582 (define_expand "addsf3"
583   [(parallel
584      [(set (match_operand:SF 0 "gpr_operand" "")
585            (plus:SF (match_operand:SF 1 "gpr_operand" "")
586                     (match_operand:SF 2 "gpr_operand" "")))
587       (clobber (reg:CC_FP CCFP_REGNUM))])])
589 (define_insn "*addsf3_i"
590   [(match_parallel 3 "float_operation"
591      [(set (match_operand:SF 0 "gpr_operand" "=r")
592            (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
593                     (match_operand:SF 2 "gpr_operand" "r")))
594       (clobber (reg:CC_FP CCFP_REGNUM))])]
595   ""
596   "fadd %0,%1,%2"
597   [(set_attr "type" "fp")])
599 ;; Subtraction
600 (define_expand "subsf3"
601   [(parallel
602      [(set (match_operand:SF 0 "gpr_operand" "")
603            (minus:SF (match_operand:SF 1 "gpr_operand" "")
604                      (match_operand:SF 2 "gpr_operand" "")))
605       (clobber (reg:CC_FP CCFP_REGNUM))])])
607 (define_insn "*subsf3_i"
608   [(match_parallel 3 "float_operation"
609      [(set (match_operand:SF 0 "gpr_operand" "=r")
610            (minus:SF (match_operand:SF 1 "gpr_operand" "r")
611                      (match_operand:SF 2 "gpr_operand" "r")))
612       (clobber (reg:CC_FP CCFP_REGNUM))])]
613   ""
614   "fsub %0,%1,%2"
615   [(set_attr "type" "fp")])
617 (define_expand "subsf3_f"
618   [(parallel
619      [(set (reg:CC_FP CCFP_REGNUM)
620            (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
621                           (match_operand:SF 2 "gpr_operand" "r")))
622       (set (match_operand:SF 0 "gpr_operand" "=r")
623            (minus:SF (match_dup 1) (match_dup 2)))])]
624   "!TARGET_SOFT_CMPSF")
626 (define_insn "*subsf3_f_i"
627   [(match_parallel 3 "float_operation"
628      [(set (reg:CC_FP CCFP_REGNUM)
629            (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
630                           (match_operand:SF 2 "gpr_operand" "r")))
631       (set (match_operand:SF 0 "gpr_operand" "=r")
632            (minus:SF (match_dup 1) (match_dup 2)))])]
633   "!TARGET_SOFT_CMPSF"
634   "fsub %0,%1,%2"
635   [(set_attr "type" "fp")])
637 ; There is an fabs instruction, but it has longer latency.
638 (define_expand "abssf2"
639   [(set (match_operand:SF 0 "gpr_operand" "")
640         (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
641   ""
642   "
644   rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
645                                                            SFmode, 0));
646   rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
648   emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
649   emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
650   DONE;
653 ;; Multiplication
654 (define_expand "mulsf3"
655   [(parallel
656      [(set (match_operand:SF 0 "gpr_operand" "")
657            (mult:SF (match_operand:SF 1 "gpr_operand" "")
658                     (match_operand:SF 2 "gpr_operand" "")))
659       (clobber (reg:CC_FP CCFP_REGNUM))])])
661 (define_insn "*mulsf3_i"
662   [(match_parallel 3 "float_operation"
663      [(set (match_operand:SF 0 "gpr_operand" "=r")
664            (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
665                     (match_operand:SF 2 "gpr_operand" "r")))
666       (clobber (reg:CC_FP CCFP_REGNUM))])]
667   ""
668   "fmul %0,%1,%2"
669   [(set_attr "type" "fp")])
671 ;; Division
672 (define_expand "divsf3"
673   [(set (match_operand:SF 0 "gpr_operand" "")
674         (div:SF (match_operand:SF 1 "gpr_operand" "")
675                 (match_operand:SF 2 "gpr_operand" "")))]
676   "flag_reciprocal_math"
678   rtx one = CONST1_RTX (SFmode);
679   rtx dst = operands[0];
681   if (rtx_equal_p (dst, operands[1]))
682     {
683       emit_move_insn (dst, one);
684       DONE;
685     }
686   else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
687     dst = gen_reg_rtx (SFmode);
688   emit_insn (gen_recipsf2 (dst, one, operands[2],
689                            sfunc_symbol (\"__fast_recipsf2\")));
690   emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
691   DONE;
694 ;; Before reload, keep the hard reg usage to clobbers so that the loop
695 ;; optimizers can more easily move this insn.
696 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
697 ;; but sched1 can still cause trouble then, and there is no guarantee of
698 ;; better register allocations.
699 ;; Neither is there when using the opposite strategy - putting explicit
700 ;; hard register references into pre-reload rtl.
701 (define_expand "recipsf2"
702   [(parallel
703      [(set (match_operand:SF 0 "gpr_operand" "")
704            (div:SF (match_operand:SF 1 "const_float_1_operand" "")
705                    (match_operand:SF 2 "move_src_operand" "")))
706       (use (match_operand:SI 3 "move_src_operand" ""))
707       (clobber (reg:SF 0))
708       (clobber (reg:SI 1))
709       (clobber (reg:SF GPR_IP))
710       (clobber (reg:DI GPR_16))
711       (clobber (reg:DI GPR_18))
712       (clobber (reg:SI GPR_20))
713       (clobber (reg:SI GPR_LR))
714       (clobber (reg:CC CC_REGNUM))
715       (clobber (reg:CC_FP CCFP_REGNUM))])])
717 (define_insn_and_split "*recipsf2_1"
718   [(match_parallel 4 "float_operation"
719      [(set (match_operand:SF 0 "gpr_operand" "=r,r")
720            (div:SF (match_operand:SF 1 "const_float_1_operand" "")
721                    (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
722       (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
723       (clobber (reg:SF 0))
724       (clobber (reg:SI 1))
725       (clobber (reg:SF GPR_IP))
726       (clobber (reg:DI GPR_16))
727       (clobber (reg:DI GPR_18))
728       (clobber (reg:SI GPR_20))
729       (clobber (reg:SI GPR_LR))
730       (clobber (reg:CC CC_REGNUM))
731       (clobber (reg:CC_FP CCFP_REGNUM))])]
732   "flag_reciprocal_math"
733   "#"
734   "&& reload_completed"
735   [(set (reg:SI 1) (match_dup 3))
736    (set (reg:SF 0) (match_dup 2))
737    (parallel
738      [(set (reg:SF 0)
739            (div:SF (match_dup 1)
740                    (reg:SF 0)))
741       (use (reg:SI 1))
742       (clobber (reg:SI GPR_IP))
743       (clobber (reg:DI GPR_16))
744       (clobber (reg:DI GPR_18))
745       (clobber (reg:SI GPR_20))
746       (clobber (reg:SI GPR_LR))
747       (clobber (reg:CC CC_REGNUM))
748       (clobber (reg:CC_FP CCFP_REGNUM))
749       (match_dup 5)
750       (match_dup 6)])
751    (set (match_dup 0) (reg:SF 0))]
752   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
753    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
754   [(set_attr "type" "fp_sfunc")
755    (set_attr "length" "16,24")])
757 (define_insn "*recipsf2_2"
758   [(match_parallel 1 "float_operation"
759      [(set (reg:SF 0)
760            (div:SF (match_operand:SF 0 "const_float_1_operand" "")
761                    (reg:SF 0)))
762       (use (reg:SI 1))
763       (clobber (reg:SI GPR_IP))
764       (clobber (reg:DI GPR_16))
765       (clobber (reg:DI GPR_18))
766       (clobber (reg:SI GPR_20))
767       (clobber (reg:SI GPR_LR))
768       (clobber (reg:CC CC_REGNUM))
769       (clobber (reg:CC_FP CCFP_REGNUM))])]
770   "flag_reciprocal_math"
771   "jalr r1"
772   [(set_attr "type" "fp_sfunc")])
775 ;; Fused multiply-add
776 (define_expand "fmasf4"
777   [(parallel
778      [(set (match_operand:SF 0 "gpr_operand" "")
779            (fma:SF (match_operand:SF 1 "gpr_operand" "")
780                    (match_operand:SF 2 "gpr_operand" "")
781                    (match_operand:SF 3 "gpr_operand" "")))
782       (clobber (reg:CC_FP CCFP_REGNUM))])]
783   "")
785 ; The multiply operands are commutative, but since they have the
786 ; same constraints, there is no point in telling reload about this.
787 (define_insn "*fmadd"
788   [(match_parallel 4 "float_operation"
789      [(set (match_operand:SF 0 "gpr_operand" "=r")
790            (fma:SF (match_operand:SF 1 "gpr_operand" "r")
791                    (match_operand:SF 2 "gpr_operand" "r")
792                    (match_operand:SF 3 "gpr_operand" "0")))
793       (clobber (reg:CC_FP CCFP_REGNUM))])]
794   ""
795   "fmadd %0,%1,%2"
796   [(set_attr "type" "fp")])
798 ; Once vetorization consistently works for this port, should check
799 ; if the fmadd / fmsub patterns still serve a purpose.  With the
800 ; introduction of fma / fnma handling by the SSA optimizers,
801 ; at least scalars should be handled by these optimizers, would
802 ; have to see how well they do on vectors from auto-vectorization.
804 ; combiner pattern, also used by vector combiner pattern
805 (define_expand "maddsf"
806   [(parallel
807      [(set (match_operand:SF 0 "gpr_operand" "=r")
808            (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
809                              (match_operand:SF 2 "gpr_operand" "r"))
810                     (match_operand:SF 3 "gpr_operand" "0")))
811       (clobber (reg:CC_FP CCFP_REGNUM))])]
812   "TARGET_FUSED_MADD")
814 (define_insn "*maddsf_combine"
815   [(match_parallel 4 "float_operation"
816      [(set (match_operand:SF 0 "gpr_operand" "=r")
817            (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
818                              (match_operand:SF 2 "gpr_operand" "r"))
819                     (match_operand:SF 3 "gpr_operand" "0")))
820       (clobber (reg:CC_FP CCFP_REGNUM))])]
821   "TARGET_FUSED_MADD"
822   "fmadd %0,%1,%2"
823   [(set_attr "type" "fp")])
825 ;; Fused multiply-sub
826 (define_expand "fnmasf4"
827   [(parallel
828      [(set (match_operand:SF 0 "gpr_operand" "")
829            (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
830                    (match_operand:SF 2 "gpr_operand" "")
831                    (match_operand:SF 3 "gpr_operand" "")))
832       (clobber (reg:CC_FP CCFP_REGNUM))])]
833   "")
835 (define_insn "*fmsub"
836   [(match_parallel 4 "float_operation"
837      [(set (match_operand:SF 0 "gpr_operand" "=r")
838            (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" "r"))
839                    (match_operand:SF 2 "gpr_operand" "r")
840                    (match_operand:SF 3 "gpr_operand" "0")))
841       (clobber (reg:CC_FP CCFP_REGNUM))])]
842   ""
843   "fmsub %0,%1,%2"
844   [(set_attr "type" "fp")])
846 (define_insn "*fmsub_combine"
847   [(match_parallel 4 "float_operation"
848      [(set (match_operand:SF 0 "gpr_operand" "=r")
849            (minus:SF  (match_operand:SF 3 "gpr_operand" "0")
850                       (mult:SF (match_operand:SF 1 "gpr_operand" "r")
851                                (match_operand:SF 2 "gpr_operand" "r"))))
852       (clobber (reg:CC_FP CCFP_REGNUM))])]
853   "TARGET_FUSED_MADD"
854   "fmsub %0,%1,%2"
855   [(set_attr "type" "fp")])
857 ;; float / integer conversions
859 (define_expand "floatsisf2"
860   [(parallel
861      [(set (match_operand:SF 0 "gpr_operand" "")
862            (float:SF (match_operand:SI 1 "gpr_operand" "")))
863       (clobber (reg:CC_FP CCFP_REGNUM))])])
865 (define_insn "*floatsisf2_i"
866   [(match_parallel 2 "float_operation"
867      [(set (match_operand:SF 0 "gpr_operand" "=r")
868            (float:SF (match_operand:SI 1 "gpr_operand" "r")))
869       (clobber (reg:CC_FP CCFP_REGNUM))])]
870   ""
871   "float %0, %1"
872   [(set_attr "type" "fp")])
874 (define_expand "floatsisf2_cmp"
875   [(parallel
876      [(set (reg:CC_FP CCFP_REGNUM)
877            (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
878                           (match_dup 2)))
879       (set (match_operand:SF 0 "gpr_operand" "=r")
880            (float:SF (match_dup 1)))])]
881   ""
882   "operands[2] = CONST0_RTX (SFmode);")
884 (define_insn "*floatsisf2_cmp_i"
885   [(match_parallel 3 "float_operation"
886      [(set (reg:CC_FP CCFP_REGNUM)
887            (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
888                           (match_operand:SF 2 "const0_operand" "")))
889       (set (match_operand:SF 0 "gpr_operand" "=r")
890            (float:SF (match_dup 1)))])]
891   ""
892   "float %0, %1"
893   [(set_attr "type" "fp")])
895 (define_expand "floatunssisf2"
896   [(set (match_operand:SF 0 "gpr_operand" "")
897         (float:SF (match_operand:SI 1 "gpr_operand" "")))]
898   "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
900   rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
901   rtx tmp = gen_reg_rtx (SImode);
902   rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
904   if (reg_overlap_mentioned_p (operands[0], operands[1]))
905     operands[1] = copy_to_mode_reg (SImode, operands[1]);
906   emit_insn (gen_floatsisf2 (operands[0], operands[1]));
907   emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
908   emit_insn (gen_sub_f (tmp, tmp, cst));
909   emit_insn (gen_movsfcc (operands[0], cmp,
910                           simplify_gen_subreg (SFmode, tmp, SImode, 0),
911                           operands[0]));
912   DONE;
915 (define_expand "fix_truncsfsi2"
916   [(parallel
917      [(set (match_operand:SI 0 "gpr_operand" "")
918            (fix:SI (match_operand:SF 1 "gpr_operand" "")))
919       (clobber (reg:CC_FP CCFP_REGNUM))])])
921 (define_insn "*fix_truncsfsi2_i"
922   [(match_parallel 2 "float_operation"
923      [(set (match_operand:SI 0 "gpr_operand" "=r")
924            (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
925       (clobber (reg:CC_FP CCFP_REGNUM))])]
926   ""
927   "fix %0, %1"
928   [(set_attr "type" "fp")
929    (set (attr "fp_mode")
930         (cond [(match_test "TARGET_MAY_ROUND_FOR_TRUNC")
931                (const_string "round_unknown")]
932               (const_string "round_trunc")))])
934 (define_expand "fixuns_truncsfsi2"
935   [(set (match_operand:SI 0 "gpr_operand" "")
936         (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
937   ""
939   if (reg_overlap_mentioned_p (operands[0], operands[1]))
940     operands[1] = copy_to_mode_reg (SImode, operands[1]);
941   if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
942     {
943       rtx op1si;
944       /* By toggling what it to be bit31 before the shift, we get a chance to
945          use a short movt insn.  */
946       rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
947       rtx tmp = gen_reg_rtx (SImode);
948       rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
949       rtx cmp
950         = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
952       op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
953       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
954       emit_insn (gen_subsi3_i (tmp, op1si, bit31));
955       emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
956       emit_insn (gen_cmpsi_cc_insn (op1si, limit));
957       emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
958     }
959   else
960     {
961       REAL_VALUE_TYPE offset;
962       rtx limit;
963       rtx tmp = gen_reg_rtx (SFmode);
964       rtx label = gen_label_rtx ();
965       rtx bit31;
966       rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
967       rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
969       real_2expN (&offset, 31, SFmode);
970       limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode);
971       limit = force_reg (SFmode, limit);
972       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
973       emit_insn (gen_subsf3_f (tmp, operands[1], limit));
974       emit_jump_insn (gen_branch_insn (label, cmp, cc1));
975       bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
976       emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
977       emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
978       emit_label (label);
979     }
980   DONE;
983 (define_expand "iadd"
984   [(parallel
985      [(set (match_operand:SF 0 "gpr_operand" "")
986            (plus:SI (match_operand:SF 1 "gpr_operand" "")
987                     (match_operand:SF 2 "gpr_operand" "")))
988       (clobber (reg:CC_FP CCFP_REGNUM))])])
990 (define_insn "*iadd_i"
991   [(match_parallel 3 "float_operation"
992      [(set (match_operand:SI 0 "gpr_operand" "=r")
993            (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
994                     (match_operand:SI 2 "gpr_operand" "r")))
995       (clobber (reg:CC_FP CCFP_REGNUM))])]
996   ""
997   "iadd %0, %1, %2"
998   [(set_attr "type" "fp_int")])
1000 (define_expand "isub"
1001   [(parallel
1002      [(set (match_operand:SF 0 "gpr_operand" "")
1003            (minus:SI (match_operand:SF 1 "gpr_operand" "")
1004                      (match_operand:SF 2 "gpr_operand" "")))
1005       (clobber (reg:CC_FP CCFP_REGNUM))])])
1007 (define_insn "*isub_i"
1008   [(match_parallel 3 "float_operation"
1009      [(set (match_operand:SI 0 "gpr_operand" "=r")
1010            (minus:SI (match_operand:SI 1 "gpr_operand" "r")
1011                      (match_operand:SI 2 "gpr_operand" "r")))
1012       (clobber (reg:CC_FP CCFP_REGNUM))])]
1013   ""
1014   "isub %0, %1, %2"
1015   [(set_attr "type" "fp_int")])
1017 ; Try to figure out if we over-committed the FPU, and if so, move
1018 ; some insns back over to the integer pipe.
1020 ; The peephole optimizer 'consumes' the insns that are explicitly
1021 ; mentioned.  We do not want the preceding insn reconsidered, but
1022 ; we do want that for the following one, so that if we have a run
1023 ; of five fpu users, two of them get changed.  Therefore, we
1024 ; use next_active_insn to look at the 'following' insn.  That should
1025 ; exist, because peephole2 runs after reload, and there has to be
1026 ; a return after an fp_int insn.
1027 ; ??? However, we can not even ordinarily match the preceding insn;
1028 ; there is some bug in the generators such that then it leaves out
1029 ; the check for PARALLEL before the length check for the then-second
1030 ; main insn.  Observed when compiling compatibility-atomic-c++0x.cc
1031 ; from libstdc++-v3.
1032 (define_peephole2
1033   [(match_parallel 3 "float_operation"
1034      [(set (match_operand:SI 0 "gpr_operand" "")
1035            (match_operator:SI 4 "addsub_operator"
1036              [(match_operand:SI 1 "gpr_operand" "")
1037               (match_operand:SI 2 "gpr_operand" "")]))
1038       (clobber (reg:CC_FP CCFP_REGNUM))])]
1039   "get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1040    && peep2_regno_dead_p (1, CC_REGNUM)
1041    && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))"
1042   [(parallel [(set (match_dup 0) (match_dup 4))
1043               (clobber (reg:CC CC_REGNUM))])]
1046 (define_expand "mulsi3"
1047   [(parallel
1048      [(set (match_operand:SI 0 "gpr_operand" "")
1049            (mult:SI (match_operand:SI 1 "gpr_operand" "")
1050                     (match_operand:SI 2 "gpr_operand" "")))
1051       (clobber (reg:CC_FP CCFP_REGNUM))])])
1053 (define_insn "*imul"
1054   [(match_parallel 3 "float_operation"
1055      [(set (match_operand:SI 0 "gpr_operand" "=r")
1056            (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
1057                     (match_operand:SI 2 "gpr_operand" "r")))
1058       (clobber (reg:CC_FP CCFP_REGNUM))])]
1059   ""
1060   "imul %0, %1, %2"
1061   [(set_attr "type" "fp_int")])
1063 ; combiner pattern, also used by vector combiner pattern
1064 (define_expand "maddsi"
1065   [(parallel
1066      [(set (match_operand:SI 0 "gpr_operand" "=r")
1067            (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1068                              (match_operand:SI 2 "gpr_operand" "r"))
1069                     (match_operand:SI 3 "gpr_operand" "0")))
1070       (clobber (reg:CC_FP CCFP_REGNUM))])]
1071   "")
1073 (define_insn "*maddsi_combine"
1074   [(match_parallel 4 "float_operation"
1075      [(set (match_operand:SI 0 "gpr_operand" "=r")
1076            (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1077                              (match_operand:SI 2 "gpr_operand" "r"))
1078                     (match_operand:SI 3 "gpr_operand" "0")))
1079       (clobber (reg:CC_FP CCFP_REGNUM))])]
1080   ""
1081   "imadd %0, %1, %2"
1082   [(set_attr "type" "fp_int")])
1084 (define_insn "*imsub"
1085   [(match_parallel 4 "float_operation"
1086      [(set (match_operand:SI 0 "gpr_operand" "=r")
1087            (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1088                      (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1089                               (match_operand:SI 2 "gpr_operand" "r"))))
1090       (clobber (reg:CC_FP CCFP_REGNUM))])]
1091   ""
1092   "imsub %0, %1, %2"
1093   [(set_attr "type" "fp_int")])
1095 (define_expand "divsi3"
1096   [(parallel
1097      [(set (match_operand:SI 0 "move_dest_operand" "")
1098            (div:SI (match_operand:SI 1 "move_src_operand" "")
1099                    (match_operand:SI 2 "move_src_operand" "")))
1100       (use (match_dup 3))
1101       (clobber (reg:SI 0))
1102       (clobber (reg:SI 1))
1103       (clobber (reg:SI GPR_IP))
1104       (clobber (reg:DI GPR_16))
1105       (clobber (reg:DI GPR_18))
1106       (clobber (reg:SI GPR_20))
1107       (clobber (reg:SI GPR_LR))
1108       (clobber (reg:CC CC_REGNUM))
1109       (clobber (reg:CC_FP CCFP_REGNUM))])]
1110   ""
1111   "operands[3] = sfunc_symbol (\"__divsi3\");")
1113 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1114 ;; optimizers can more easily move this insn.
1115 (define_insn_and_split "*divsi3_1"
1116   [(match_parallel 4 "float_operation"
1117      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1118            (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1119                    (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1120       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1121       (clobber (reg:SI 0))
1122       (clobber (reg:SI 1))
1123       (clobber (reg:SI GPR_IP))
1124       (clobber (reg:DI GPR_16))
1125       (clobber (reg:DI GPR_18))
1126       (clobber (reg:SI GPR_20))
1127       (clobber (reg:SI GPR_LR))
1128       (clobber (reg:CC CC_REGNUM))
1129       (clobber (reg:CC_FP CCFP_REGNUM))])]
1130   ""
1131   "#"
1132   "&& reload_completed"
1133   [(set (reg:SI 0) (match_dup 1))
1134    (set (reg:SI 1) (match_dup 2))
1135    (parallel
1136      [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1137       (use (match_dup 3))
1138       (clobber (reg:SI 1))
1139       (clobber (reg:SI GPR_IP))
1140       (clobber (reg:DI GPR_16))
1141       (clobber (reg:DI GPR_18))
1142       (clobber (reg:SI GPR_20))
1143       (clobber (reg:SI GPR_LR))
1144       (clobber (reg:CC CC_REGNUM))
1145       (clobber (reg:CC_FP CCFP_REGNUM))
1146       (match_dup 5)
1147       (match_dup 6)])
1148    (set (match_dup 0) (reg:SI 0))]
1149   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1150    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1151   [(set_attr "type" "fp_sfunc")
1152    (set_attr "length" "16,24")])
1154 (define_insn "*divsi3_2"
1155   [(match_parallel 1 "float_operation"
1156      [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1157       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1158       (clobber (reg:SI 1))
1159       (clobber (reg:SI GPR_IP))
1160       (clobber (reg:DI GPR_16))
1161       (clobber (reg:DI GPR_18))
1162       (clobber (reg:SI GPR_20))
1163       (clobber (reg:SI GPR_LR))
1164       (clobber (reg:CC CC_REGNUM))
1165       (clobber (reg:CC_FP CCFP_REGNUM))])]
1166   ""
1167   "%f0"
1168   [(set_attr "type" "fp_sfunc")])
1170 (define_expand "udivsi3"
1171   [(parallel
1172      [(set (match_operand:SI 0 "move_dest_operand" "")
1173            (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1174                     (match_operand:SI 2 "move_src_operand" "")))
1175       (use (match_dup 3))
1176       (clobber (reg:SI 0))
1177       (clobber (reg:SI 1))
1178       (clobber (reg:SI GPR_IP))
1179       (clobber (reg:DI GPR_16))
1180       (clobber (reg:SI GPR_18))
1181       (clobber (reg:SI GPR_LR))
1182       (clobber (reg:CC CC_REGNUM))
1183       (clobber (reg:CC_FP CCFP_REGNUM))])]
1184   ""
1185   "operands[3] = sfunc_symbol (\"__udivsi3\");")
1187 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1188 ;; optimizers can more easily move this insn.
1189 (define_insn_and_split "*udivsi3_1"
1190   [(match_parallel 4 "float_operation"
1191      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1192            (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1193                     (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1194       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1195       (clobber (reg:SI 0))
1196       (clobber (reg:SI 1))
1197       (clobber (reg:SI GPR_IP))
1198       (clobber (reg:DI GPR_16))
1199       (clobber (reg:SI GPR_18))
1200       (clobber (reg:SI GPR_LR))
1201       (clobber (reg:CC CC_REGNUM))
1202       (clobber (reg:CC_FP CCFP_REGNUM))])]
1203   ""
1204   "#"
1205   "&& reload_completed"
1206   [(set (reg:SI 0) (match_dup 1))
1207    (set (reg:SI 1) (match_dup 2))
1208    (parallel
1209      [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1210       (use (match_dup 3))
1211       (clobber (reg:SI 1))
1212       (clobber (reg:SI GPR_IP))
1213       (clobber (reg:DI GPR_16))
1214       (clobber (reg:SI GPR_18))
1215       (clobber (reg:SI GPR_LR))
1216       (clobber (reg:CC CC_REGNUM))
1217       (clobber (reg:CC_FP CCFP_REGNUM))
1218       (match_dup 5)
1219       (match_dup 6)])
1220    (set (match_dup 0) (reg:SI 0))]
1221   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1222    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1223   [(set_attr "type" "fp_sfunc")
1224    (set_attr "length" "16,24")])
1226 (define_insn "*udivsi3_2"
1227   [(match_parallel 1 "float_operation"
1228      [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1229       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1230       (clobber (reg:SI 1))
1231       (clobber (reg:SI GPR_IP))
1232       (clobber (reg:DI GPR_16))
1233       (clobber (reg:SI GPR_18))
1234       (clobber (reg:SI GPR_LR))
1235       (clobber (reg:CC CC_REGNUM))
1236       (clobber (reg:CC_FP CCFP_REGNUM))])]
1237   ""
1238   "%f0"
1239   [(set_attr "type" "fp_sfunc")])
1241 (define_expand "modsi3"
1242   [(parallel
1243      [(set (match_operand:SI 0 "move_dest_operand" "")
1244            (mod:SI (match_operand:SI 1 "move_src_operand" "")
1245                    (match_operand:SI 2 "move_src_operand" "")))
1246       (use (match_dup 3))
1247       (clobber (reg:SI 0))
1248       (clobber (reg:SI 1))
1249       (clobber (reg:SI 2))
1250       (clobber (reg:SI GPR_IP))
1251       (clobber (reg:DI GPR_16))
1252       (clobber (reg:DI GPR_18))
1253       (clobber (reg:SI GPR_LR))
1254       (clobber (reg:CC CC_REGNUM))
1255       (clobber (reg:CC_FP CCFP_REGNUM))])]
1256   ""
1257   "operands[3] = sfunc_symbol (\"__modsi3\");")
1259 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1260 ;; optimizers can more easily move this insn.
1261 (define_insn_and_split "*modsi3_1"
1262   [(match_parallel 4 "float_operation"
1263      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1264            (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1265                    (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1266       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1267       (clobber (reg:SI 0))
1268       (clobber (reg:SI 1))
1269       (clobber (reg:SI 2))
1270       (clobber (reg:SI GPR_IP))
1271       (clobber (reg:DI GPR_16))
1272       (clobber (reg:DI GPR_18))
1273       (clobber (reg:SI GPR_LR))
1274       (clobber (reg:CC CC_REGNUM))
1275       (clobber (reg:CC_FP CCFP_REGNUM))])]
1276   ""
1277   "#"
1278   "&& reload_completed"
1279   [(set (reg:SI 0) (match_dup 1))
1280    (set (reg:SI 1) (match_dup 2))
1281    (parallel
1282      [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1283       (use (match_dup 3))
1284       (clobber (reg:SI 2))
1285       (clobber (reg:SI GPR_IP))
1286       (clobber (reg:DI GPR_16))
1287       (clobber (reg:DI GPR_18))
1288       (clobber (reg:SI GPR_LR))
1289       (clobber (reg:CC CC_REGNUM))
1290       (clobber (reg:CC_FP CCFP_REGNUM))
1291       (match_dup 5)
1292       (match_dup 6)])
1293    (set (match_dup 0) (reg:SI 0))]
1294   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1295    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1296   [(set_attr "type" "fp_sfunc")
1297    (set_attr "length" "16,24")])
1299 (define_insn "*modsi3_2"
1300   [(match_parallel 1 "float_operation"
1301      [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1302       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1303       (clobber (reg:SI 2))
1304       (clobber (reg:SI GPR_IP))
1305       (clobber (reg:DI GPR_16))
1306       (clobber (reg:DI GPR_18))
1307       (clobber (reg:SI GPR_LR))
1308       (clobber (reg:CC CC_REGNUM))
1309       (clobber (reg:CC_FP CCFP_REGNUM))])]
1310   ""
1311   "%f0"
1312   [(set_attr "type" "fp_sfunc")])
1314 (define_expand "umodsi3"
1315   [(parallel
1316      [(set (match_operand:SI 0 "move_dest_operand" "")
1317            (umod:SI (match_operand:SI 1 "move_src_operand" "")
1318                     (match_operand:SI 2 "move_src_operand" "")))
1319       (use (match_dup 3))
1320       (clobber (reg:SI 0))
1321       (clobber (reg:SI 1))
1322       (clobber (reg:SI 2))
1323       (clobber (reg:SI GPR_IP))
1324       (clobber (reg:DI GPR_16))
1325       (clobber (reg:SI GPR_LR))
1326       (clobber (reg:CC CC_REGNUM))
1327       (clobber (reg:CC_FP CCFP_REGNUM))])]
1328   ""
1329   "operands[3] = sfunc_symbol (\"__umodsi3\");")
1331 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1332 ;; optimizers can more easily move this insn.
1333 (define_insn_and_split "*umodsi3_1"
1334   [(match_parallel 4 "float_operation"
1335      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1336            (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1337                     (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1338       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1339       (clobber (reg:SI 0))
1340       (clobber (reg:SI 1))
1341       (clobber (reg:SI 2))
1342       (clobber (reg:SI GPR_IP))
1343       (clobber (reg:DI GPR_16))
1344       (clobber (reg:SI GPR_LR))
1345       (clobber (reg:CC CC_REGNUM))
1346       (clobber (reg:CC_FP CCFP_REGNUM))])]
1347   ""
1348   "#"
1349   "&& reload_completed"
1350   [(set (reg:SI 0) (match_dup 1))
1351    (set (reg:SI 1) (match_dup 2))
1352    (parallel
1353      [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1354       (use (match_dup 3))
1355       (clobber (reg:SI 2))
1356       (clobber (reg:SI GPR_IP))
1357       (clobber (reg:DI GPR_16))
1358       (clobber (reg:SI GPR_LR))
1359       (clobber (reg:CC CC_REGNUM))
1360       (clobber (reg:CC_FP CCFP_REGNUM))
1361       (match_dup 5)
1362       (match_dup 6)])
1363    (set (match_dup 0) (reg:SI 0))]
1364   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1365    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1366   [(set_attr "type" "fp_sfunc")
1367    (set_attr "length" "16,24")])
1369 (define_insn "*umodsi3_2"
1370   [(match_parallel 1 "float_operation"
1371      [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1372       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1373       (clobber (reg:SI 2))
1374       (clobber (reg:SI GPR_IP))
1375       (clobber (reg:DI GPR_16))
1376       (clobber (reg:SI GPR_LR))
1377       (clobber (reg:CC CC_REGNUM))
1378       (clobber (reg:CC_FP CCFP_REGNUM))])]
1379   ""
1380   "%f0"
1381   [(set_attr "type" "fp_sfunc")])
1383 ; Disable interrupts.
1384 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1385 ; might have changed settings that we do not want to mess with.
1386 (define_insn "gid"
1387   [(set (reg:SI CONFIG_REGNUM)
1388         (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1389   ""
1390   "gid"
1391   [(set_attr "type" "flow")])
1393 ; Enable interrupts.
1394 ; Present CONTROL_REGNUM here to make sure it is live before the
1395 ; actual uses in floating point insns / calls are inserted.
1396 ; FWIW, interrupts also do mind what is in the control register.
1397 (define_insn "gie"
1398   [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1399   ""
1400   "gie"
1401   [(set_attr "type" "flow")])
1403 ; Floating point instructions require manipulating the control register.
1404 ; Manipulating the control register needs aritmetic.
1405 ; Arithmetic clobbers flags.
1406 ; The flags are in the status register, which also contains the alternate
1407 ; flag and the interrupt enable/disable bits.
1408 ; saving/restoring status and mixing up the order with gid/gie could
1409 ; lead to disaster.
1410 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1411 ; away.  But when we really need it, we must make sure that we don't change
1412 ; anything but the flags.
1413 ; N.B.: We could make the constant easier to load by inverting it, but
1414 ; then we'd need to clobber the saved value - and that would make optimizing
1415 ; away unneeded saves/restores harder / less likely.
1416 (define_expand "movcc"
1417   [(parallel [(set (match_operand:CC 0 "cc_move_operand"  "")
1418                    (match_operand:CC 1 "cc_move_operand" ""))
1419               (use (match_dup 2))
1420               (clobber (match_scratch:SI 3                 "=X, &r"))])]
1421   ""
1422   "operands[2] = gen_int_mode (~0x10f0, SImode);")
1424 (define_insn "*movcc_i"
1425   [(set (match_operand:CC 0 "cc_move_operand"  "=r,Rcc")
1426         (match_operand:CC 1 "cc_move_operand" "Rcc,  r"))
1427    (use (match_operand:SI 2 "nonmemory_operand"  "X,  r"))
1428    (clobber (match_scratch:SI 3                 "=X, &r"))]
1429   ""
1430   "@
1431    movfs %0,status
1432    movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1433   [(set_attr "type" "flow")
1434    (set_attr "length" "20,4")])
1436 (define_insn_and_split "set_fp_mode"
1437   [(set (reg:SI FP_NEAREST_REGNUM)
1438         (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1439    (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1440    (set (reg:SI FP_ANYFP_REGNUM)
1441         (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1442    (use (match_operand:SI 2 "gpr_operand" "r"))
1443    (clobber (reg:CC CC_REGNUM))
1444    (clobber (match_scratch:SI 3 "=&r"))]
1445   ""
1446   "#"
1447   "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1448   [(const_int 0)]
1450   if (!reload_completed)
1451     emit_note (NOTE_INSN_DELETED);
1452   else
1453     epiphany_expand_set_fp_mode (operands);
1454   DONE;
1458 ;; Boolean instructions.
1460 ;; We don't define the DImode versions as expand_binop does a good enough job.
1462 (define_insn "andsi3"
1463   [(set (match_operand:SI 0 "gpr_operand" "=r")
1464         (and:SI (match_operand:SI 1 "gpr_operand" "r")
1465                 (match_operand:SI 2 "gpr_operand" "r")))
1466    (clobber (reg:CC CC_REGNUM))]
1467   ""
1468   "and %0,%1,%2")
1470 (define_insn "iorsi3"
1471   [(set (match_operand:SI 0 "gpr_operand" "=r")
1472         (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1473                 (match_operand:SI 2 "gpr_operand" "r")))
1474    (clobber (reg:CC CC_REGNUM))]
1475   ""
1476   "orr %0,%1,%2")
1478 (define_insn "xorsi3"
1479   [(set (match_operand:SI 0 "gpr_operand" "=r")
1480         (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1481                 (match_operand:SI 2 "gpr_operand" "r")))
1482    (clobber (reg:CC CC_REGNUM))]
1483   ""
1484   "eor %0,%1,%2")
1486 (define_expand "one_cmplsi2"
1487   [(set (match_operand:SI 0 "gpr_operand" "")
1488         (xor:SI (match_operand:SI 1 "gpr_operand" "")
1489                 (match_dup 2)))]
1490   ""
1492   if (epiphany_m1reg >= 0)
1493     emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1494   else
1495     emit_insn (gen_xorsi3 (operands[0], operands[1],
1496                            force_reg (SImode, GEN_INT (-1))));
1497   DONE;
1500 ; Note that folding this pattern into the xorsi3 pattern would make combine
1501 ; less effective.
1502 (define_insn "one_cmplsi2_i"
1503   [(set (match_operand:SI 0 "gpr_operand" "=r")
1504         (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1505    (clobber (reg:CC CC_REGNUM))]
1506   "epiphany_m1reg >= 0"
1507   "eor %0,%1,%-")
1509 ;; Shift instructions.
1510 ;; In principle we could support arbitrary symbolic values as shift constant
1511 ;; (truncating the value appropriately), but that would require a suitable
1512 ;; relocation and assembler & linker support.
1513 (define_insn "ashrsi3"
1514   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1515         (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1516                      (match_operand:SI 2 "arith_operand" "r,K")))
1517    (clobber (reg:CC CC_REGNUM))]
1518   ""
1519   "asr %0,%1,%2"
1520   [(set_attr "length" "4")
1521    (set_attr "type" "shift")])
1523 (define_insn "ashrsi3_tst"
1524   [(set (reg:CC CC_REGNUM)
1525         (compare:CC
1526           (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1527                        (match_operand:SI 2 "arith_operand" "r,K"))
1528         (const_int 0)))
1529    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1530         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1531   ""
1532   "asr %0,%1,%2"
1533   [(set_attr "length" "4")
1534    (set_attr "type" "shift")])
1536 ;; Logical Shift Right
1537 (define_insn "lshrsi3"
1538   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1539         (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1540                      (match_operand:SI 2 "arith_operand" "r,K")))
1541    (clobber (reg:CC CC_REGNUM))]
1542   ""
1543   "lsr %0,%1,%2"
1544   [(set_attr "length" "4")
1545    (set_attr "type" "shift")])
1547 (define_insn "lshrsi3_tst"
1548   [(set (reg:CC CC_REGNUM)
1549         (compare:CC
1550           (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1551                        (match_operand:SI 2 "arith_operand" "r,K"))
1552         (const_int 0)))
1553    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1554         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1555   ""
1556   "lsr %0,%1,%2"
1557   [(set_attr "length" "4")
1558    (set_attr "type" "shift")])
1560 ;; Logical/Arithmetic Shift Left
1561 (define_insn "ashlsi3"
1562   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1563         (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1564                    (match_operand:SI 2 "arith_operand" "r,K")))
1565    (clobber (reg:CC CC_REGNUM))]
1566   ""
1567   "lsl %0,%1,%2"
1568   [(set_attr "length" "4")
1569    (set_attr "type" "shift")])
1571 (define_insn "*ashlsi_btst"
1572   [(set (reg:CC_N_NE CC_REGNUM)
1573         (compare:CC_N_NE
1574           (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1575                            (const_int 1)
1576                            (match_operand 2 "const_int_operand" "K"))
1577           (const_int 0)))
1578    (clobber (match_scratch:SI 0 "=r"))]
1579   ""
1581   rtx xop[3];
1583   xop[0] = operands[0];
1584   xop[1] = operands[1];
1585   xop[2] = GEN_INT (31-INTVAL (operands[2]));
1586   output_asm_insn ("lsl %0,%1,%2", xop);
1587   return "";
1590 ;; zero extensions
1591 (define_insn_and_split "zero_extendqisi2"
1592   [(set (match_operand:SI 0 "register_operand" "=r,r")
1593         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1594    (clobber (reg:CC CC_REGNUM))]
1595   ""
1596   "@
1597    #
1598    ldrb %0,%1"
1599   "reload_completed
1600    ? true_regnum (operands[1]) >= 0
1601    : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1602   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1603               (clobber (reg:CC CC_REGNUM))])
1604    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1605               (clobber (reg:CC CC_REGNUM))])]
1606   "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1608 (define_insn "zero_extendhisi2"
1609   [(set (match_operand:SI 0 "register_operand" "=r,r")
1610         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1611   ""
1612   "@
1613    movt %0, 0
1614    ldrh %0,%c1")
1617 ;; Compare instructions.
1619 (define_insn "cmpsi_cc_insn"
1620   [(set (reg:CC CC_REGNUM)
1621         (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1622                     (match_operand:SI 1 "arith_operand" "r,L")))
1623    (clobber (match_scratch:SI 2 "=r,r"))]
1624   ""
1625   "sub %2,%0,%1"
1626   [(set_attr "type" "compare")])
1628 (define_insn "sub_f"
1629   [(set (reg:CC CC_REGNUM)
1630         (compare:CC (match_operand:SI 1 "gpr_operand"  "r,r")
1631                     (match_operand:SI 2 "arith_operand" "r,L")))
1632    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1633         (minus:SI (match_dup 1) (match_dup 2)))]
1634   ""
1635   "sub %0,%1,%2"
1636   [(set_attr "type" "compare")])
1638 (define_insn "*sub_f_add_imm"
1639   [(set (reg:CC CC_REGNUM)
1640         (compare:CC (match_operand:SI 1 "gpr_operand"  "r")
1641                     (match_operand:SI 2 "arith_int_operand" "L")))
1642    (set (match_operand:SI 0 "gpr_operand" "=r")
1643         (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "L")))]
1644   "INTVAL (operands[2]) == -INTVAL (operands[3])"
1645   "sub %0,%1,%2"
1646   [(set_attr "type" "compare")])
1648 (define_expand "abssi2"
1649   [(set (match_dup 2) (const_int 0))
1650    (parallel [(set (reg:CC CC_REGNUM)
1651                    (compare:CC (match_dup 2)
1652                                (match_operand:SI 1 "nonmemory_operand" "")))
1653               (set (match_dup 3)
1654                    (minus:SI (match_dup 2) (match_dup 1)))])
1655    (set (match_operand:SI 0 "gpr_operand" "=r")
1656         (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1657                          (match_dup 3)
1658                          (match_dup 1)))]
1659   "TARGET_CMOVE"
1660   "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1662 (define_insn "*add_c"
1663   [(set (reg:CC_C_LTU CC_REGNUM)
1664         (compare:CC_C_LTU
1665           (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1666                    (match_operand:SI 2 "arith_operand" "r,L"))
1667           (match_dup 1)))
1668    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1669         (plus:SI (match_dup 1) (match_dup 2)))]
1670   ""
1671   "add %0,%1,%2"
1672   [(set_attr "type" "compare")])
1674 (define_insn "*add_c_rev"
1675   [(set (reg:CC_C_LTU CC_REGNUM)
1676         (compare:CC_C_LTU
1677           (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1678                    (match_operand:SI 2 "arith_operand" "r,L"))
1679           (match_dup 1)))
1680    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1681         (plus:SI (match_dup 2) (match_dup 1)))]
1682   ""
1683   "add %0,%1,%2"
1684   [(set_attr "type" "compare")])
1686 (define_insn "*sub_c"
1687   [(set (reg:CC_C_GTU CC_REGNUM)
1688         (compare:CC_C_GTU
1689           (minus:SI (match_operand:SI 1 "gpr_operand"  "r,r")
1690                     (match_operand:SI 2 "arith_operand" "r,L"))
1691           (match_dup 1)))
1692    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1693         (minus:SI (match_dup 1) (match_dup 2)))]
1694   ""
1695   "sub %0,%1,%2"
1696   [(set_attr "type" "compare")])
1698 (define_insn "*sub_c_void"
1699   [(set (reg:CC_C_GTU CC_REGNUM)
1700         (compare:CC_C_GTU
1701           (minus:SI (match_operand:SI 1 "gpr_operand"  "r,r")
1702                     (match_operand:SI 2 "arith_operand" "r,L"))
1703           (match_dup 1)))
1704    (clobber (match_scratch:SI 0 "=r,r"))]
1705   ""
1706   "sub %0,%1,%2"
1707   [(set_attr "type" "compare")])
1709 ; floating point comparisons
1711 (define_insn "*cmpsf_cc_insn"
1712   [(match_parallel 3 "float_operation"
1713      [(set (reg:CC_FP CCFP_REGNUM)
1714            (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1715                           (match_operand:SF 1 "gpr_operand" "r")))
1716       (clobber (match_scratch:SF 2 "=r"))])]
1717   "!TARGET_SOFT_CMPSF"
1718   "fsub %2,%0,%1"
1719   [(set_attr "type" "fp")
1720    (set_attr "fp_mode" "round_unknown")])
1722 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1723 ;; to allow the rtl loop optimizer to generate comparisons?  OTOH
1724 ;; we want call_address_operand to enforce valid operands so that
1725 ;; combine won't do silly things, allowing instruction scheduling to do
1726 ;; a proper job.
1727 (define_insn "*cmpsf_eq"
1728   [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (reg:SF 0) (reg:SF 1)))
1729    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1730    (clobber (reg:SI GPR_IP))
1731    (clobber (reg:SI GPR_LR))]
1732   "TARGET_SOFT_CMPSF"
1733   "%f0"
1734   [(set_attr "type" "sfunc")])
1736 (define_insn "*cmpsf_gte"
1737   [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (reg:SF 0) (reg:SF 1)))
1738    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1739    (clobber (reg:SI GPR_IP))
1740    (clobber (reg:SI GPR_LR))]
1741   "TARGET_SOFT_CMPSF"
1742   "%f0"
1743   [(set_attr "type" "sfunc")])
1745 (define_insn "*cmpsf_ord"
1746   [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1747    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1748    (clobber (reg:SI GPR_IP))
1749    (clobber (reg:SI GPR_16))
1750    (clobber (reg:SI GPR_LR))]
1751   "TARGET_SOFT_CMPSF"
1752   "%f0"
1753   [(set_attr "type" "sfunc")])
1755 (define_insn "*cmpsf_uneq"
1756   [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1757    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1758    (clobber (reg:SI GPR_IP))
1759    (clobber (reg:SI GPR_16))
1760    (clobber (reg:SI GPR_LR))]
1761   "TARGET_SOFT_CMPSF"
1762   "%f0"
1763   [(set_attr "type" "sfunc")])
1765 ;; conditional moves
1767 (define_expand "mov<mode>cc"
1768   [(set (match_operand:WMODE 0 "gpr_operand" "")
1769         (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1770                             (match_operand:WMODE 2 "gpr_operand" "")
1771                             (match_operand:WMODE 3 "gpr_operand" "")))]
1772   "TARGET_CMOVE"
1774   rtx cmp_op0 = XEXP (operands[1], 0);
1775   rtx cmp_op1 = XEXP (operands[1], 1);
1776   enum machine_mode cmp_in_mode;
1777   enum rtx_code code = GET_CODE (operands[1]);
1779   cmp_in_mode = GET_MODE (cmp_op0);
1780   if (cmp_in_mode == VOIDmode)
1781     cmp_in_mode = GET_MODE (cmp_op1);
1782   if (cmp_in_mode == VOIDmode)
1783     cmp_in_mode = SImode;
1784   /* If the operands are a better match when reversed, swap them now.
1785      This allows combine to see the proper comparison codes.  */
1786   if (rtx_equal_p (operands[0], operands[2])
1787       && !rtx_equal_p (operands[0], operands[3]))
1788     {
1789       rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1790       code = (FLOAT_MODE_P (GET_MODE (cmp_op0))
1791               ? reverse_condition_maybe_unordered (code)
1792               : reverse_condition (code));
1793     }
1795   if (proper_comparison_operator (operands[1], VOIDmode))
1796     operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1797   else
1798     {
1799       if (!currently_expanding_to_rtl)
1800         {
1801           /* ???  It would seem safest to FAIL here, but that would defeat
1802              the purpose of having an if-conversion pass; its logic currently
1803              assumes that the backend should be safe to insert condition code
1804              setting instructions, as the same condition codes were presumably
1805              set by the if-conversion input code.  */
1806         }
1807       /* What mode to give as first operand to gen_compare_reg here is
1808          debatable.  VOIDmode would be minimalist; telling gen_compare_reg
1809          to use the mode of CC_REGNUM (or putting it on the comparison
1810          operator afterwards) is also a logical choice.  OTOH, by using
1811          <MODE>mode, we have mode combine opportunities with flag setting
1812          operations - if we get some.  */
1813       operands[1]
1814         = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1815     }
1818 (define_insn "*mov<mode>cc_insn"
1819   [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1820         (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1821                               [(match_operand 4 "cc_operand") (const_int 0)])
1822                             (match_operand:WMODE 1 "gpr_operand" "r")
1823                             (match_operand:WMODE 2 "gpr_operand" "0")))]
1824   "TARGET_CMOVE"
1825   "mov%d3 %0,%1"
1826   [(set_attr "type" "cmove")])
1828 (define_peephole2
1829   [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
1830                    (match_operand:WMODE 1 "" ""))
1831               (clobber (match_operand 8 "cc_operand"))])
1832    (match_operand 2 "" "")
1833    (set (match_operand:WMODE2 3 "gpr_operand" "")
1834         (match_operand:WMODE2 9 "gpr_operand" ""))
1835    (set (match_dup 3)
1836         (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1837                                [(match_operand 6 "cc_operand")
1838                                 (match_operand 7 "const0_operand")])
1839                              (match_operand:WMODE2 4 "nonmemory_operand" "")
1840                              (match_dup 3)))]
1841   "REGNO (operands[0]) == REGNO (operands[9])
1842    && peep2_reg_dead_p (3, operands[0])
1843    && !reg_set_p (operands[0], operands[2])
1844    && !reg_set_p (operands[3], operands[2])
1845    && !reg_overlap_mentioned_p (operands[3], operands[2])"
1846   [(parallel [(set (match_dup 10) (match_dup 1))
1847               (clobber (match_dup 8))])
1848    (match_dup 2)
1849    (set (match_dup 3)
1850         (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1852   operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1853                                       <WMODE2:MODE>mode, 0);
1854   replace_rtx (operands[2], operands[9], operands[3]);
1855   replace_rtx (operands[2], operands[0], operands[10]);
1856   gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
1859 (define_peephole2
1860   [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
1861               (set (match_operand:WMODE 0 "gpr_operand" "")
1862                    (match_operand:WMODE 1 "" ""))])
1863    (set (match_operand:WMODE2 3 "gpr_operand" "")
1864         (match_operand:WMODE2 4 "gpr_operand"))
1865    (set (match_dup 3)
1866         (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1867                                [(match_dup 6)
1868                                (match_operand:WMODE 7 "const0_operand")])
1869                             (match_operand:WMODE2 8 "gpr_operand")
1870                             (match_dup 3)))]
1871   "REGNO (operands[0]) == REGNO (operands[8])
1872    && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
1873    && peep2_reg_dead_p (3, operands[6])
1874    && peep2_reg_dead_p (3, operands[0])
1875    && !reg_overlap_mentioned_p (operands[4], operands[3])"
1876   [(parallel [(set (match_dup 6) (match_dup 2))
1877               (set (match_dup 9) (match_dup 1))])
1878    (set (match_dup 3)
1879         (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1880   "
1882   operands[5]
1883     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
1884                                          GET_MODE (operands[6])),
1885                       GET_MODE (operands[5]), operands[6], operands[7]);
1886   operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1887                                      <WMODE2:MODE>mode, 0);
1890 ;; These control RTL generation for conditional jump insns
1892 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
1893 ;; they must allow const0_rtx for both comparison operands
1894 (define_expand "cbranchsi4"
1895   [(set (reg CC_REGNUM)
1896         (compare (match_operand:SI 1 "add_operand" "")
1897                  (match_operand:SI 2 "arith_operand" "")))
1898    (set (pc)
1899         (if_then_else
1900               (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
1901                                                                (const_int 0)])
1902               (label_ref (match_operand 3 "" ""))
1903               (pc)))]
1904   ""
1906   rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
1907                              operands[1], operands[2]);
1908   emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1909   DONE;
1912 (define_expand "cbranchsf4"
1913   [(set (reg CC_REGNUM)
1914         (compare (match_operand:SF 1 "arith_operand" "")
1915                  (match_operand:SF 2 "arith_operand" "")))
1916    (set (pc)
1917         (if_then_else
1918               (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
1919                                                        (const_int 0)])
1920               (label_ref (match_operand 3 "" ""))
1921               (pc)))]
1922   ""
1924   rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
1925                              operands[1], operands[2]);
1926   emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1927   DONE;
1930 ;; Now match both normal and inverted jump.
1932 (define_insn "branch_insn"
1933   [(set (pc)
1934         (if_then_else (match_operator 1 "proper_comparison_operator"
1935                                       [(match_operand 2 "cc_operand")
1936                                        (const_int 0)])
1937                       (label_ref (match_operand 0 "" ""))
1938                       (pc)))]
1939   ""
1940   "b%d1 %l0"
1941   [(set_attr "type" "branch")])
1943 (define_insn "*rev_branch_insn"
1944   [(set (pc)
1945         (if_then_else (match_operator 1 "proper_comparison_operator"
1946                                       [(reg CC_REGNUM) (const_int 0)])
1947                       (pc)
1948                       (label_ref (match_operand 0 "" ""))))]
1949   ""
1950   "b%D1 %l0"
1951   [(set_attr "type" "branch")])
1953 ;; Unconditional and other jump instructions.
1955 (define_insn "jump"
1956   [(set (pc) (label_ref (match_operand 0 "" "")))]
1957   ""
1958   "b %l0"
1959   [(set_attr "type" "uncond_branch")])
1961 (define_insn "indirect_jump"
1962   [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
1963   ""
1964   "jr %0"
1965   [(set_attr "type" "uncond_branch")])
1967 (define_expand "tablejump"
1968   [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
1969               (use (label_ref (match_operand 1 "" "")))])]
1970   ""
1972   /* In PIC mode, the table entries are stored PC relative.
1973      Convert the relative address to an absolute address.  */
1974   if (flag_pic)
1975     {
1976       rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1978       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1979                                          op1, NULL_RTX, 0, OPTAB_DIRECT);
1980     }
1983 (define_insn "*tablejump_internal"
1984   [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
1985    (use (label_ref (match_operand 1 "" "")))]
1986   ""
1987   "jr %0;"
1988   [(set_attr "type" "uncond_branch")])
1990 (define_insn "*tablejump_hi_internal"
1991   [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
1992    (use (label_ref (match_operand 1 "" "")))]
1993   "optimize_size && TARGET_SMALL16"
1994   "jr %0;"
1995   [(set_attr "type" "uncond_branch")])
1998 (define_expand "call"
1999   ;; operands[1] is stack_size_rtx
2000   ;; operands[2] is next_arg_register
2001   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2002                     (match_operand 1 "" ""))
2003              (clobber (reg:SI GPR_LR))])]
2004   ""
2006   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2008   if (!call_operand (operands[1], VOIDmode))
2009     operands[0]
2010       = change_address (operands[0], VOIDmode,
2011                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2012   if (epiphany_uninterruptible_p (current_function_decl)
2013       != target_uninterruptible)
2014     {
2015       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2016       emit_call_insn
2017         (gen_rtx_PARALLEL
2018           (VOIDmode,
2019            gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2020                          gen_rtx_CLOBBER (VOIDmode,
2021                                           gen_rtx_REG (SImode, GPR_LR)))));
2022       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2023       DONE;
2024     }
2027 (define_insn "*call_i"
2028   [(match_parallel 2 "float_operation"
2029      [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
2030             (match_operand 1 "" ""))
2031       (clobber (reg:SI GPR_LR))])]
2032   ""
2033   "%f0"
2034   [(set_attr "type" "call")])
2036 (define_expand "sibcall"
2037   ;; operands[1] is stack_size_rtx
2038   ;; operands[2] is next_arg_register
2039   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2040                     (match_operand 1 "" ""))
2041              (return)])]
2042   ""
2044   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2046   if (!call_operand (operands[1], VOIDmode))
2047     operands[0]
2048       = change_address (operands[0], VOIDmode,
2049                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2050   if (epiphany_uninterruptible_p (current_function_decl)
2051       != target_uninterruptible)
2052     {
2053       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2054       emit_call_insn
2055         (gen_rtx_PARALLEL
2056           (VOIDmode,
2057            gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2058                          ret_rtx)));
2059       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2060       DONE;
2061     }
2064 (define_insn "*sibcall_i"
2065   [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
2066          (match_operand 1 "" ""))
2067    (return)]
2068   ""
2069   "@
2070    b %0
2071    jr %0"
2072   [(set_attr "type" "call")])
2074 (define_expand "call_value"
2075   ;; operand 2 is stack_size_rtx
2076   ;; operand 3 is next_arg_register
2077   [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2078                    (call (match_operand:SI 1 "call_operand" "")
2079                          (match_operand 2 "" "")))
2080              (clobber (reg:SI GPR_LR))])]
2081   ""
2083   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2085   if (!call_operand (operands[1], VOIDmode))
2086     operands[1]
2087       = change_address (operands[1], VOIDmode,
2088                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2089   if (epiphany_uninterruptible_p (current_function_decl)
2090       != target_uninterruptible)
2091     {
2092       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2093       emit_call_insn
2094         (gen_rtx_PARALLEL
2095           (VOIDmode,
2096            gen_rtvec (2, gen_rtx_SET
2097                            (VOIDmode, operands[0],
2098                             gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2099                          gen_rtx_CLOBBER (VOIDmode,
2100                                           gen_rtx_REG (SImode, GPR_LR)))));
2101       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2102       DONE;
2103     }
2106 (define_insn "*call_value_i"
2107   [(match_parallel 3 "float_operation"
2108      [(set (match_operand 0 "gpr_operand" "=r,r")
2109            (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2110                  (match_operand 2 "" "")))
2111       (clobber (reg:SI GPR_LR))])]
2112   ""
2113   "%f1"
2114   [(set_attr "type" "call")
2115    (set_attr "length" "4")])
2117 (define_expand "sibcall_value"
2118   ;; operand 2 is stack_size_rtx
2119   ;; operand 3 is next_arg_register
2120   [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2121                    (call (match_operand:SI 1 "call_operand" "")
2122                          (match_operand 2 "" "")))
2123              (return)])]
2124   ""
2126   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2128   if (!call_operand (operands[1], VOIDmode))
2129     operands[1]
2130       = change_address (operands[1], VOIDmode,
2131                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2132   if (epiphany_uninterruptible_p (current_function_decl)
2133       != target_uninterruptible)
2134     {
2135       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2136       emit_call_insn
2137         (gen_rtx_PARALLEL
2138           (VOIDmode,
2139            gen_rtvec (2, gen_rtx_SET
2140                            (VOIDmode, operands[0],
2141                             gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2142                          ret_rtx)));
2143       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2144       DONE;
2145     }
2148 (define_insn "*sibcall_value_i"
2149   [(set (match_operand 0 "gpr_operand" "=r,r")
2150         (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2151               (match_operand 2 "" "")))
2152    (return)]
2153   ""
2154   "@
2155    b %1
2156    jr %1"
2157   [(set_attr "type" "call")
2158    (set_attr "length" "4")])
2160 (define_expand "prologue"
2161   [(pc)]
2162   ""
2164   epiphany_expand_prologue ();
2165   DONE;
2168 (define_expand "epilogue"
2169   [(pc)]
2170   ""
2172   epiphany_expand_epilogue (0);
2173   DONE;
2176 (define_expand "sibcall_epilogue"
2177   [(pc)]
2178   ""
2180   epiphany_expand_epilogue (1);
2181   DONE;
2184 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2185 ; in the prologue / epilogue expanders how many times lr is set.
2186 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2187 ; any explicit use of lr will cause it to be saved; hence we cannot
2188 ; represent the blink use in return / sibcall instructions themselves, and
2189 ; instead have to show it in EPILOGUE_USES.
2190 (define_insn "return_i"
2191   [(return)]
2192   "reload_completed"
2193   "rts"
2194   [(set_attr "type" "uncond_branch")])
2196 (define_insn "return_internal_interrupt"
2197   [(return)
2198    (unspec_volatile [(const_int 0)] 1)]
2199   ""
2200   "rti"
2201   [(set_attr "type" "uncond_branch")])
2203 (define_insn "stack_adjust_add"
2204   [(set (reg:SI GPR_SP)
2205         (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2206    (clobber (reg:CC CC_REGNUM))
2207    (clobber (reg:SI STATUS_REGNUM))
2208    (clobber (match_operand:BLK 1 "memory_operand" "=m"))]
2209   "reload_completed"
2210   "add sp,sp,%0")
2212 (define_insn "stack_adjust_mov"
2213   [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2214    (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2215   "reload_completed"
2216   "mov sp,fp"
2217   [(set_attr "type" "move")])
2219 (define_insn "stack_adjust_str"
2220   [(set (match_operand 0 "stacktop_operand" "=m")
2221         (match_operand 1 "any_gpr_operand" "r"))
2222    (set (reg:SI GPR_SP)
2223         (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2224    (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2225   "reload_completed"
2227   return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2228           ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2230   [(set_attr "type" "store")])
2232 (define_insn "stack_adjust_ldr"
2233   [(set (match_operand:SI 0 "gpr_operand" "=r")
2234         (match_operand:SI 1 "stacktop_operand" "m"))
2235    (set (reg:SI GPR_SP)
2236         (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2237    (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2238   "reload_completed"
2239   "ldr %0,%1,%C2"
2240   [(set_attr "type" "load")])
2242 ;; Define some fake vector operations so that the vectorizer is happy to use
2243 ;; 64 bit loads/stores.
2244 (define_expand "vec_unpacks_lo_v4hi"
2245   [(match_operand:V2SI 0 "gpr_operand")
2246    (match_operand:V4HI 1 "gpr_operand")]
2247   ""
2249   rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2250   rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2251   rtx outh
2252     = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2254   if (reg_overlap_mentioned_p (outl, in))
2255     in = copy_to_mode_reg (SImode, in);
2256   emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2257   emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2258   emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2259   DONE;
2262 (define_expand "vec_unpacks_hi_v4hi"
2263   [(match_operand:V2SI 0 "gpr_operand")
2264    (match_operand:V4HI 1 "gpr_operand")]
2265   ""
2267   rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2268   rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2269   rtx outh
2270     = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2272   if (reg_overlap_mentioned_p (outl, in))
2273     in = copy_to_mode_reg (SImode, in);
2274   emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2275   emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2276   emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2277   DONE;
2280 (define_code_iterator addsub [plus minus])
2282 (define_code_iterator alu_binop
2283   [plus minus and ior xor])
2285 (define_code_attr insn_opname
2286   [(plus "add") (minus "sub") (mult "mul") (div "div")
2287    (and "and") (ior "ior") (xor "xor")])
2289 ; You might think that this would work better as a define_expand, but
2290 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2291 ; We need to keep inputs and outputs as register pairs if we want to
2292 ; get sensible register allocation for double-word load and store operations.
2293 (define_insn_and_split "<insn_opname>v2si3"
2294   [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2295         (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2296                         (match_operand:V2SI 2 "gpr_operand" "r")))
2297    (clobber (reg:CC CC_REGNUM))]
2298   ""
2299   "#"
2300   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2301   [(const_int 0)]
2303   rtx o0l, o0h, o1l, o1h, o2l, o2h;
2305   o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2306   o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2307   o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2308   o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2309   o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2310   o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2311   if (reg_overlap_mentioned_p (o0l, o1h))
2312     o1h = copy_to_mode_reg (SImode, o1h);
2313   if (reg_overlap_mentioned_p (o0l, o2h))
2314     o2h = copy_to_mode_reg (SImode, o2h);
2315   emit_insn (gen_<insn_opname>si3 (o0l, o1l, o2l));
2316   emit_insn (gen_<insn_opname>si3 (o0h, o1h, o2h));
2317   DONE;
2319   [(set_attr "length" "8")])
2321 (define_expand "<insn_opname>v2sf3"
2322   [(parallel
2323      [(set (match_operand:V2SF 0 "gpr_operand" "")
2324            (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2325                         (match_operand:V2SF 2 "gpr_operand" "")))
2326       (clobber (reg:CC_FP CCFP_REGNUM))])])
2328 (define_insn_and_split "<insn_opname>v2sf3_i"
2329   [(match_parallel 3 "float_operation"
2330      [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2331            (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2332                         (match_operand:V2SF 2 "gpr_operand" "r")))
2333       (clobber (reg:CC_FP CCFP_REGNUM))])]
2334   ""
2335   "#"
2336   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2337   [(parallel
2338      [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2339       (clobber (reg:CC_FP CCFP_REGNUM))
2340       (match_dup 10)
2341       (match_dup 11)])
2342    (parallel
2343      [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2344       (clobber (reg:CC_FP CCFP_REGNUM))
2345       (match_dup 10)
2346       (match_dup 11)])]
2348   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2349   operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2350   operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2351   operands[7]
2352     = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2353   operands[8]
2354     = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2355   operands[9]
2356     = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2357   if (!reload_completed)
2358     {
2359       if (reg_overlap_mentioned_p (operands[4], operands[8]))
2360         operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2361       if (reg_overlap_mentioned_p (operands[4], operands[9]))
2362         operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2363       emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2364       emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2365       DONE;
2366     }
2367   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2368   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2369   operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2370   operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2372   [(set_attr "length" "8")
2373    (set_attr "type" "v2fp")])
2375 (define_expand "mul<mode>3"
2376   [(parallel
2377      [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2378            (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2379                           (match_operand:DWV2MODE 2 "gpr_operand" "")))
2380       (clobber (reg:CC_FP CCFP_REGNUM))])])
2382 (define_insn_and_split "mul<mode>3_i"
2383   [(match_parallel 3 "float_operation"
2384      [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2385            (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2386                           (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2387       (clobber (reg:CC_FP CCFP_REGNUM))])]
2388   ""
2389   "#"
2390   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2391   [(parallel
2392      [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2393       (clobber (reg:CC_FP CCFP_REGNUM))
2394       (match_dup 10)
2395       (match_dup 11)])
2396    (parallel
2397      [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2398       (clobber (reg:CC_FP CCFP_REGNUM))
2399       (match_dup 10)
2400       (match_dup 11)])]
2402   operands[4]
2403     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2404   operands[5]
2405     = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2406   operands[6]
2407     = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2408   operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2409                                      <MODE>mode, UNITS_PER_WORD);
2410   operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2411                                      <MODE>mode, UNITS_PER_WORD);
2412   operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2413                                      <MODE>mode, UNITS_PER_WORD);
2414   if (!reload_completed)
2415     {
2416       if (reg_overlap_mentioned_p (operands[4], operands[8]))
2417         operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2418       if (reg_overlap_mentioned_p (operands[4], operands[9]))
2419         operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2420       emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2421       emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2422       DONE;
2423     }
2424   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2425   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2426   operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2427   operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2429   [(set_attr "length" "8")
2430    (set_attr "type" "<vmode_fp_type>")])
2432 (define_insn_and_split "*fmadd<mode>_combine"
2433   [(match_parallel 4 "float_operation"
2434      [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2435            (plus:DWV2MODE (mult:<MODE>
2436                                 (match_operand:<MODE> 1 "gpr_operand" "r")
2437                                 (match_operand:<MODE> 2 "gpr_operand" "r"))
2438                           (match_operand:<MODE> 3 "gpr_operand" "0")))
2439       (clobber (reg:CC_FP CCFP_REGNUM))])]
2440   "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2441   "#"
2442   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2443   [(parallel
2444      [(set (match_dup 5)
2445            (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2446                               (match_dup 8)))
2447       (clobber (reg:CC_FP CCFP_REGNUM))
2448       (match_dup 13)
2449       (match_dup 14)])
2450    (parallel
2451      [(set (match_dup 9)
2452            (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2453                               (match_dup 12)))
2454       (clobber (reg:CC_FP CCFP_REGNUM))
2455       (match_dup 13)
2456       (match_dup 14)])]
2458   operands[5]
2459     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2460   operands[6]
2461     = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2462   operands[7]
2463     = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2464   operands[8]
2465     = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2466   operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2467                                      <MODE>mode, UNITS_PER_WORD);
2468   operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2469                                       <MODE>mode, UNITS_PER_WORD);
2470   operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2471                                       <MODE>mode, UNITS_PER_WORD);
2472   operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2473                                       <MODE>mode, UNITS_PER_WORD);
2474   if (!reload_completed)
2475     {
2476       if (reg_overlap_mentioned_p (operands[5], operands[10]))
2477         operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2478       if (reg_overlap_mentioned_p (operands[5], operands[11]))
2479         operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2480       if (reg_overlap_mentioned_p (operands[5], operands[12]))
2481         operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2482       emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2483                                        operands[8]));
2484       emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2485                                        operands[12]));
2486       DONE;
2487     }
2488   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2489   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2490   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2491   operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2492   operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2494   [(set_attr "length" "8")
2495    (set_attr "type" "<vmode_fp_type>")])
2497 (define_expand "vec_set<mode>"
2498   [(match_operand:DWV2MODE 0 "register_operand")
2499    (match_operand:<vmode_PART> 1 "register_operand")
2500    (match_operand 2 "const_int_operand" "")]
2501   ""
2503   operands[0]
2504     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2505                            UNITS_PER_WORD * INTVAL (operands[2]));
2506   emit_move_insn (operands[0], operands[1]);
2507   DONE;
2510 (define_expand "movmisalign<mode>"
2511  [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "")
2512        (match_operand:DWV2MODE 1 "general_operand" ""))]
2513  ""
2515   rtx op00, op01, op10, op11;
2517   op00 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2518   op01 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2519                               UNITS_PER_WORD);
2520   op10 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2521   op11 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode,
2522                               UNITS_PER_WORD);
2523   emit_move_insn (op00, op10);
2524   emit_move_insn (op01, op11);
2525   DONE;
2528 (define_insn "nop"
2529   [(const_int 0)]
2530   ""
2531   "nop"
2532   [(set_attr "type" "flow")])