* gimplify.c (nonlocal_vlas): Delete.
[official-gcc.git] / gcc / config / epiphany / epiphany.md
blob67a1d34e4f1233ac4f3d5826335f14d011ae4aad
1 ;; Machine description of the Adaptiva epiphany cpu for GNU C compiler
2 ;; Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 ;; Contributed by Embecosm on behalf of Adapteva, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 (define_constants
24   [(GPR_0                        0)
25    (GPR_1                        1)
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   if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
269     {
270       start_sequence ();
271       epiphany_expand_prologue ();
272       if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
273         epiphany_expand_epilogue (0);
274       end_sequence ();
275       gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_known);
276     }
277   addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
278   operands[1] = gen_frame_mem (SImode, addr);
281 ;; If the frame pointer elimination offset is zero, we'll use this pattern.
282 ;; Note that the splitter can accept any gpr in operands[1]; this is
283 ;; necessary, (e.g. for compile/20021015-1.c -O0,)
284 ;; because when register elimination cannot be done with the constant
285 ;; as an immediate operand of the add instruction, reload will resort to
286 ;; loading the constant into a reload register, using gen_add2_insn to add
287 ;; the stack pointer, and then use the reload register as new source in
288 ;; the move_frame pattern.
289 (define_insn_and_split "*move_frame_1"
290   [(set (match_operand:SI 0 "gpr_operand" "=r")
291         (match_operand:SI 1 "gpr_operand" "r"))
292    (clobber (reg:CC CC_REGNUM))]
293   "(reload_in_progress || reload_completed)
294    && (operands[1] == stack_pointer_rtx
295        || operands[1] == hard_frame_pointer_rtx)"
296   "#"
297   "reload_in_progress || reload_completed"
298   [(set (match_dup 0) (match_dup 1))])
300 (define_expand "mov<mode>"
301   [(set (match_operand:DWMODE 0 "general_operand" "")
302         (match_operand:DWMODE 1 "general_operand" ""))]
303   ""
304   "
306   if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT
307       || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
308     {
309       if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)
310         {
311           rtx o0l, o0h, o1l, o1h;
313           o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
314           o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode,
315                                      UNITS_PER_WORD);
316           o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
317           o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode,
318                                      UNITS_PER_WORD);
319           if (reg_overlap_mentioned_p (o0l, o1h))
320             {
321               emit_move_insn (o0h, o1h);
322               emit_move_insn (o0l, o1l);
323             }
324           else
325             {
326               emit_move_insn (o0l, o1l);
327               emit_move_insn (o0h, o1h);
328             }
329           DONE;
330         }
331       /* lower_subreg has a tendency to muck up vectorized code.
332          To protect the wide memory accesses, we must use same-size
333          subregs.  */
334       if (epiphany_vect_align != 4 /* == 8 */
335           && !reload_in_progress
336           && (GET_CODE (operands[0]) == MEM || GET_CODE (operands[1]) == MEM)
337           && !misaligned_operand (operands[1], <MODE>mode)
338           && (GET_CODE (operands[0]) != SUBREG
339               || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
340                   != GET_MODE_SIZE (<MODE>mode)
341                   && GET_CODE (operands[1]) != SUBREG)))
342         {
343           operands[0]
344             = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0);
345           operands[1]
346             = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0);
347           emit_insn (gen_movdi (operands[0], operands[1]));
348           DONE;
349         }
350     }
351   /* Everything except mem = const or mem = mem can be done easily.  */
353   if (GET_CODE (operands[0]) == MEM)
354     operands[1] = force_reg (<MODE>mode, operands[1]);
357 (define_insn_and_split "*mov<mode>_insn"
358   [(set (match_operand:DWMODE 0 "move_dest_operand"      "=r,   r,r,m")
359         (match_operand:DWMODE 1 "move_double_src_operand" "r,CalE,m,r"))]
360   "(gpr_operand (operands[0], <MODE>mode)
361     || gpr_operand (operands[1], <MODE>mode))"
362   "@
363    #
364    #
365    ldrd %0,%X1
366    strd %1,%X0"
367   "reload_completed
368    && (((!MEM_P (operands[0]) || misaligned_operand (operands[0], <MODE>mode))
369         && (!MEM_P (operands[1])
370             || misaligned_operand (operands[1], <MODE>mode)))
371        || epiphany_vect_align == 4)"
372   [(set (match_dup 2) (match_dup 3))
373    (set (match_dup 4) (match_dup 5))]
375   int word0 = 0, word1 = UNITS_PER_WORD;
377   if (post_modify_operand (operands[0], <MODE>mode)
378       || post_modify_operand (operands[1], <MODE>mode))
379     word0 = UNITS_PER_WORD, word1 = 0;
381   operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
382   operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
383   operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
384   operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
385   if (post_modify_operand (operands[0], <MODE>mode))
386     operands[2]
387       = change_address (operands[2], VOIDmode,
388                         plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0),
389                                        UNITS_PER_WORD));
390   if (post_modify_operand (operands[1], <MODE>mode))
391     operands[3]
392       = change_address (operands[3], VOIDmode,
393                         plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0),
394                                        UNITS_PER_WORD));
396   [(set_attr "type" "move,move,load,store")
397    (set_attr "length" "8,16,4,4")])
400 (define_insn_and_split "*movsf_insn"
401   [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
402         (match_operand:SF 1 "move_src_operand"   "r,E,m,r"))]
403   "gpr_operand (operands[0], SFmode)
404    || gpr_operand (operands[1], SFmode)"
405   "@
406    mov %0,%1
407    mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
408    ldr %0,%C1
409    str %1,%C0"
410   "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
411   [(set (match_dup 2) (match_dup 3))]
412   "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
413    operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
414   [(set_attr "type" "move,move,load,store")
415    (set_attr "length" "4,8,4,4")])
417 (define_expand "addsi3"
418   [(set (match_operand:SI 0 "add_reg_operand" "")
419         (plus:SI (match_operand:SI 1 "add_reg_operand" "")
420                  (match_operand:SI 2 "add_operand" "")))]
421   ""
422   "
424   if (reload_in_progress || reload_completed)
425     emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
426   else if (TARGET_FP_IARITH && add_reg_operand (operands[2], SImode))
427     emit_insn (gen_iadd (operands[0], operands[1], operands[2]));
428   else
429     emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
430   DONE;
433 ; The default case of epiphany_print_operand emits IMMEDIATE_PREFIX
434 ; where appropriate; however, 'n' is processed by output_asm_insn
435 ; which doesn't, so we have to explicitly emit the '# in the
436 ; r/r/CnL output template alternative.
437 (define_insn "addsi3_i"
438   [(set (match_operand:SI 0 "add_reg_operand" "=r,r")
439         (plus:SI (match_operand:SI 1 "add_reg_operand" "%r,r")
440                  (match_operand:SI 2 "add_operand" "rL,CnL")))
441    (clobber (reg:CC CC_REGNUM))]
442   ""
443   "@
444    add %0,%1,%2
445    sub %0,%1,#%n2"
446 [(set_attr "type" "misc")])
448 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
449 ; can identify the unresolved flags clobber problem, and also to
450 ; avoid unwanted matches.
452 ; At -O0 / -O1 we don't peephole all instances away.  We could get better
453 ; debug unwinding through the emitted code if we added a splitter.
454 (define_insn "addsi3_r"
455   [(set (match_operand:SI 0 "gpr_operand" "=r")
456         (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
457                  (match_operand:SI 2 "nonmemory_operand" "rCar")))
458    (clobber (reg:CC UNKNOWN_REGNUM))]
459   "reload_in_progress || reload_completed"
461   int scratch = (0x17
462                  ^ (true_regnum (operands[0]) & 1)
463                  ^ (true_regnum (operands[1]) & 2)
464                  ^ (true_regnum (operands[2]) & 4));
465   asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
466   asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
467   output_asm_insn ("add %0,%1,%2", operands);
468   asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
469   asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
470   return "";
472   [(set_attr "length" "20")
473    (set_attr "type" "misc")])
475 ;; reload uses gen_addsi2 because it doesn't understand the need for
476 ;; the clobber.
477 (define_peephole2
478   [(set (match_operand:SI 0 "gpr_operand" "")
479         (match_operand:SI 1 "const_int_operand" ""))
480    (parallel [(set (match_dup 0)
481                    (plus:SI (match_dup 0)
482                             (match_operand:SI 2 "gpr_operand")))
483               (clobber (reg:CC UNKNOWN_REGNUM))])]
484   "satisfies_constraint_L (operands[1])
485    || ((operands[2] == stack_pointer_rtx
486         || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
487        && !peep2_regno_dead_p (2, CC_REGNUM)
488        && satisfies_constraint_Car (operands[1]))"
489   [(parallel [(set (match_dup 0)
490                    (plus:SI (match_dup 2) (match_dup 1)))
491               (clobber (reg:CC UNKNOWN_REGNUM))])]
492   ;; FIXME:
493   ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
494   ;; "peep2_rescan = true;"
497 (define_peephole2
498   [(match_parallel 5 ""
499      [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
500    (parallel [(set (match_operand:SI 0 "gpr_operand" "")
501                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
502                             (match_operand:SI 2 "nonmemory_operand" "")))
503               (clobber (reg:CC UNKNOWN_REGNUM))])]
504   "REGNO (operands[3]) == CC_REGNUM
505    && (gpr_operand (operands[2], SImode)
506        || satisfies_constraint_L (operands[2]))
507    && !reg_overlap_mentioned_p (operands[0], operands[5])
508    && !reg_set_p (operands[1], operands[5])
509    && !reg_set_p (operands[2], operands[5])"
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    (match_dup 5)]
515   "")
517 (define_peephole2
518   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
519                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
520                             (match_operand:SI 2 "nonmemory_operand" "")))
521               (clobber (reg:CC UNKNOWN_REGNUM))])]
522   "peep2_regno_dead_p (1, CC_REGNUM)
523    && (gpr_operand (operands[2], SImode)
524        || satisfies_constraint_L (operands[2]))"
525   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
526                    (plus:SI (match_operand:SI 1 "gpr_operand" "")
527                             (match_operand:SI 2 "nonmemory_operand" "")))
528               (clobber (reg:CC CC_REGNUM))])]
529   "")
531 (define_peephole2
532   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
533                    (plus:SI (reg:SI GPR_SP)
534                             (match_operand:SI 1 "nonmemory_operand" "")))
535               (clobber (reg:CC UNKNOWN_REGNUM))])]
536   "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
537    || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
538   [(set (match_dup 0) (reg:SI GPR_SP))
539    (set (mem:WMODE (post_modify (match_dup 0)
540                                 (plus:SI (match_dup 0) (match_dup 1))))
541         (reg:WMODE GPR_SP))]
542   "")
546 (define_peephole2
547   [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
548                    (plus:SI (reg:SI GPR_FP)
549                             (match_operand:SI 1 "nonmemory_operand" "")))
550               (clobber (reg:CC UNKNOWN_REGNUM))])
551    (match_scratch:WMODE 2 "r")]
552   "frame_pointer_needed
553    && ((REG_P (operands[1])
554         && !reg_overlap_mentioned_p (operands[0], operands[1]))
555        || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
556   [(set (match_dup 0) (reg:SI GPR_FP))
557    (set (match_dup 2)
558         (mem:WMODE (post_modify (match_dup 0)
559                                 (plus:SI (match_dup 0) (match_dup 1)))))]
560   "")
562 (define_expand "subsi3"
563   [(set (match_operand:SI 0 "gpr_operand" "")
564         (plus:SI (match_operand:SI 1 "add_reg_operand" "")
565                  (match_operand:SI 2 "arith_operand" "")))]
566   ""
567   "
569   gcc_assert (!reload_in_progress && !reload_completed);
571   if (TARGET_FP_IARITH)
572     emit_insn (gen_isub (operands[0], operands[1], operands[2]));
573   else
574     emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2]));
575   DONE;
578 (define_insn "subsi3_i"
579   [(set (match_operand:SI 0 "gpr_operand" "=r")
580         (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
581                   (match_operand:SI 2 "arith_operand" "rL")))
582    (clobber (reg:CC CC_REGNUM))]
583   ""
584   "sub %0,%1,%2"
585   [(set_attr "type" "misc")])
587 ; After mode-switching, floating point operations, fp_sfuncs and calls
588 ; must exhibit the use of the control register, lest the setting of the
589 ; control register could be deleted or moved.  OTOH a use of a hard register
590 ; greatly counfounds optimizers like the rtl loop optimizers or combine.
591 ; Therefore, we put an extra pass immediately after the mode switching pass
592 ; that inserts the USEs of the control registers, and sets a flag in struct
593 ; machine_function that float_operation can henceforth only match with that
594 ; USE.
596 ;; Addition
597 (define_expand "addsf3"
598   [(parallel
599      [(set (match_operand:SF 0 "gpr_operand" "")
600            (plus:SF (match_operand:SF 1 "gpr_operand" "")
601                     (match_operand:SF 2 "gpr_operand" "")))
602       (clobber (reg:CC_FP CCFP_REGNUM))])])
604 (define_insn "*addsf3_i"
605   [(match_parallel 3 "float_operation"
606      [(set (match_operand:SF 0 "gpr_operand" "=r")
607            (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
608                     (match_operand:SF 2 "gpr_operand" "r")))
609       (clobber (reg:CC_FP CCFP_REGNUM))])]
610   ""
611   "fadd %0,%1,%2"
612   [(set_attr "type" "fp")])
614 ;; Subtraction
615 (define_expand "subsf3"
616   [(parallel
617      [(set (match_operand:SF 0 "gpr_operand" "")
618            (minus:SF (match_operand:SF 1 "gpr_operand" "")
619                      (match_operand:SF 2 "gpr_operand" "")))
620       (clobber (reg:CC_FP CCFP_REGNUM))])])
622 (define_insn "*subsf3_i"
623   [(match_parallel 3 "float_operation"
624      [(set (match_operand:SF 0 "gpr_operand" "=r")
625            (minus:SF (match_operand:SF 1 "gpr_operand" "r")
626                      (match_operand:SF 2 "gpr_operand" "r")))
627       (clobber (reg:CC_FP CCFP_REGNUM))])]
628   ""
629   "fsub %0,%1,%2"
630   [(set_attr "type" "fp")])
632 (define_expand "subsf3_f"
633   [(parallel
634      [(set (reg:CC_FP CCFP_REGNUM)
635            (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
636                           (match_operand:SF 2 "gpr_operand" "r")))
637       (set (match_operand:SF 0 "gpr_operand" "=r")
638            (minus:SF (match_dup 1) (match_dup 2)))])]
639   "!TARGET_SOFT_CMPSF")
641 (define_insn "*subsf3_f_i"
642   [(match_parallel 3 "float_operation"
643      [(set (reg:CC_FP CCFP_REGNUM)
644            (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
645                           (match_operand:SF 2 "gpr_operand" "r")))
646       (set (match_operand:SF 0 "gpr_operand" "=r")
647            (minus:SF (match_dup 1) (match_dup 2)))])]
648   "!TARGET_SOFT_CMPSF"
649   "fsub %0,%1,%2"
650   [(set_attr "type" "fp")])
652 ; There is an fabs instruction, but it has longer latency.
653 (define_expand "abssf2"
654   [(set (match_operand:SF 0 "gpr_operand" "")
655         (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
656   ""
657   "
659   rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
660                                                            SFmode, 0));
661   rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
663   emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
664   emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
665   DONE;
668 ;; Multiplication
669 (define_expand "mulsf3"
670   [(parallel
671      [(set (match_operand:SF 0 "gpr_operand" "")
672            (mult:SF (match_operand:SF 1 "gpr_operand" "")
673                     (match_operand:SF 2 "gpr_operand" "")))
674       (clobber (reg:CC_FP CCFP_REGNUM))])])
676 (define_insn "*mulsf3_i"
677   [(match_parallel 3 "float_operation"
678      [(set (match_operand:SF 0 "gpr_operand" "=r")
679            (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
680                     (match_operand:SF 2 "gpr_operand" "r")))
681       (clobber (reg:CC_FP CCFP_REGNUM))])]
682   ""
683   "fmul %0,%1,%2"
684   [(set_attr "type" "fp")])
686 ;; Division
687 (define_expand "divsf3"
688   [(set (match_operand:SF 0 "gpr_operand" "")
689         (div:SF (match_operand:SF 1 "gpr_operand" "")
690                 (match_operand:SF 2 "gpr_operand" "")))]
691   "flag_reciprocal_math"
693   rtx one = CONST1_RTX (SFmode);
694   rtx dst = operands[0];
696   if (rtx_equal_p (dst, operands[1]))
697     {
698       emit_move_insn (dst, one);
699       DONE;
700     }
701   else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
702     dst = gen_reg_rtx (SFmode);
703   emit_insn (gen_recipsf2 (dst, one, operands[2],
704                            sfunc_symbol (\"__fast_recipsf2\")));
705   emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
706   DONE;
709 ;; Before reload, keep the hard reg usage to clobbers so that the loop
710 ;; optimizers can more easily move this insn.
711 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
712 ;; but sched1 can still cause trouble then, and there is no guarantee of
713 ;; better register allocations.
714 ;; Neither is there when using the opposite strategy - putting explicit
715 ;; hard register references into pre-reload rtl.
716 (define_expand "recipsf2"
717   [(parallel
718      [(set (match_operand:SF 0 "gpr_operand" "")
719            (div:SF (match_operand:SF 1 "const_float_1_operand" "")
720                    (match_operand:SF 2 "move_src_operand" "")))
721       (use (match_operand:SI 3 "move_src_operand" ""))
722       (clobber (reg:SF 0))
723       (clobber (reg:SI 1))
724       (clobber (reg:SF GPR_IP))
725       (clobber (reg:DI GPR_16))
726       (clobber (reg:DI GPR_18))
727       (clobber (reg:SI GPR_20))
728       (clobber (reg:SI GPR_LR))
729       (clobber (reg:CC CC_REGNUM))
730       (clobber (reg:CC_FP CCFP_REGNUM))])])
732 (define_insn_and_split "*recipsf2_1"
733   [(match_parallel 4 "float_operation"
734      [(set (match_operand:SF 0 "gpr_operand" "=r,r")
735            (div:SF (match_operand:SF 1 "const_float_1_operand" "")
736                    (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
737       (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
738       (clobber (reg:SF 0))
739       (clobber (reg:SI 1))
740       (clobber (reg:SF GPR_IP))
741       (clobber (reg:DI GPR_16))
742       (clobber (reg:DI GPR_18))
743       (clobber (reg:SI GPR_20))
744       (clobber (reg:SI GPR_LR))
745       (clobber (reg:CC CC_REGNUM))
746       (clobber (reg:CC_FP CCFP_REGNUM))])]
747   "flag_reciprocal_math"
748   "#"
749   "&& reload_completed"
750   [(set (reg:SI 1) (match_dup 3))
751    (set (reg:SF 0) (match_dup 2))
752    (parallel
753      [(set (reg:SF 0)
754            (div:SF (match_dup 1)
755                    (reg:SF 0)))
756       (use (reg:SI 1))
757       (clobber (reg:SI GPR_IP))
758       (clobber (reg:DI GPR_16))
759       (clobber (reg:DI GPR_18))
760       (clobber (reg:SI GPR_20))
761       (clobber (reg:SI GPR_LR))
762       (clobber (reg:CC CC_REGNUM))
763       (clobber (reg:CC_FP CCFP_REGNUM))
764       (match_dup 5)
765       (match_dup 6)])
766    (set (match_dup 0) (reg:SF 0))]
767   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
768    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
769   [(set_attr "type" "fp_sfunc")
770    (set_attr "length" "16,24")])
772 (define_insn "*recipsf2_2"
773   [(match_parallel 1 "float_operation"
774      [(set (reg:SF 0)
775            (div:SF (match_operand:SF 0 "const_float_1_operand" "")
776                    (reg:SF 0)))
777       (use (reg:SI 1))
778       (clobber (reg:SI GPR_IP))
779       (clobber (reg:DI GPR_16))
780       (clobber (reg:DI GPR_18))
781       (clobber (reg:SI GPR_20))
782       (clobber (reg:SI GPR_LR))
783       (clobber (reg:CC CC_REGNUM))
784       (clobber (reg:CC_FP CCFP_REGNUM))])]
785   "flag_reciprocal_math"
786   "jalr r1"
787   [(set_attr "type" "fp_sfunc")])
790 ;; Fused multiply-add
791 (define_expand "fmasf4"
792   [(parallel
793      [(set (match_operand:SF 0 "gpr_operand" "")
794            (fma:SF (match_operand:SF 1 "gpr_operand" "")
795                    (match_operand:SF 2 "gpr_operand" "")
796                    (match_operand:SF 3 "gpr_operand" "")))
797       (clobber (reg:CC_FP CCFP_REGNUM))])]
798   "")
800 ; The multiply operands are commutative, but since they have the
801 ; same constraints, there is no point in telling reload about this.
802 (define_insn "*fmadd"
803   [(match_parallel 4 "float_operation"
804      [(set (match_operand:SF 0 "gpr_operand" "=r")
805            (fma:SF (match_operand:SF 1 "gpr_operand" "r")
806                    (match_operand:SF 2 "gpr_operand" "r")
807                    (match_operand:SF 3 "gpr_operand" "0")))
808       (clobber (reg:CC_FP CCFP_REGNUM))])]
809   ""
810   "fmadd %0,%1,%2"
811   [(set_attr "type" "fp")])
813 ; Once vetorization consistently works for this port, should check
814 ; if the fmadd / fmsub patterns still serve a purpose.  With the
815 ; introduction of fma / fnma handling by the SSA optimizers,
816 ; at least scalars should be handled by these optimizers, would
817 ; have to see how well they do on vectors from auto-vectorization.
819 ; combiner pattern, also used by vector combiner pattern
820 (define_expand "maddsf"
821   [(parallel
822      [(set (match_operand:SF 0 "gpr_operand" "=r")
823            (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
824                              (match_operand:SF 2 "gpr_operand" "r"))
825                     (match_operand:SF 3 "gpr_operand" "0")))
826       (clobber (reg:CC_FP CCFP_REGNUM))])]
827   "TARGET_FUSED_MADD")
829 (define_insn "*maddsf_combine"
830   [(match_parallel 4 "float_operation"
831      [(set (match_operand:SF 0 "gpr_operand" "=r")
832            (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
833                              (match_operand:SF 2 "gpr_operand" "r"))
834                     (match_operand:SF 3 "gpr_operand" "0")))
835       (clobber (reg:CC_FP CCFP_REGNUM))])]
836   "TARGET_FUSED_MADD"
837   "fmadd %0,%1,%2"
838   [(set_attr "type" "fp")])
840 ;; Fused multiply-sub
841 (define_expand "fnmasf4"
842   [(parallel
843      [(set (match_operand:SF 0 "gpr_operand" "")
844            (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
845                    (match_operand:SF 2 "gpr_operand" "")
846                    (match_operand:SF 3 "gpr_operand" "")))
847       (clobber (reg:CC_FP CCFP_REGNUM))])]
848   "")
850 (define_insn "*fmsub"
851   [(match_parallel 4 "float_operation"
852      [(set (match_operand:SF 0 "gpr_operand" "=r")
853            (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" "r"))
854                    (match_operand:SF 2 "gpr_operand" "r")
855                    (match_operand:SF 3 "gpr_operand" "0")))
856       (clobber (reg:CC_FP CCFP_REGNUM))])]
857   ""
858   "fmsub %0,%1,%2"
859   [(set_attr "type" "fp")])
861 (define_insn "*fmsub_combine"
862   [(match_parallel 4 "float_operation"
863      [(set (match_operand:SF 0 "gpr_operand" "=r")
864            (minus:SF  (match_operand:SF 3 "gpr_operand" "0")
865                       (mult:SF (match_operand:SF 1 "gpr_operand" "r")
866                                (match_operand:SF 2 "gpr_operand" "r"))))
867       (clobber (reg:CC_FP CCFP_REGNUM))])]
868   "TARGET_FUSED_MADD"
869   "fmsub %0,%1,%2"
870   [(set_attr "type" "fp")])
872 ;; float / integer conversions
874 (define_expand "floatsisf2"
875   [(parallel
876      [(set (match_operand:SF 0 "gpr_operand" "")
877            (float:SF (match_operand:SI 1 "gpr_operand" "")))
878       (clobber (reg:CC_FP CCFP_REGNUM))])])
880 (define_insn "*floatsisf2_i"
881   [(match_parallel 2 "float_operation"
882      [(set (match_operand:SF 0 "gpr_operand" "=r")
883            (float:SF (match_operand:SI 1 "gpr_operand" "r")))
884       (clobber (reg:CC_FP CCFP_REGNUM))])]
885   ""
886   "float %0, %1"
887   [(set_attr "type" "fp")])
889 (define_expand "floatsisf2_cmp"
890   [(parallel
891      [(set (reg:CC_FP CCFP_REGNUM)
892            (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
893                           (match_dup 2)))
894       (set (match_operand:SF 0 "gpr_operand" "=r")
895            (float:SF (match_dup 1)))])]
896   ""
897   "operands[2] = CONST0_RTX (SFmode);")
899 (define_insn "*floatsisf2_cmp_i"
900   [(match_parallel 3 "float_operation"
901      [(set (reg:CC_FP CCFP_REGNUM)
902            (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
903                           (match_operand:SF 2 "const0_operand" "")))
904       (set (match_operand:SF 0 "gpr_operand" "=r")
905            (float:SF (match_dup 1)))])]
906   ""
907   "float %0, %1"
908   [(set_attr "type" "fp")])
910 (define_expand "floatunssisf2"
911   [(set (match_operand:SF 0 "gpr_operand" "")
912         (float:SF (match_operand:SI 1 "gpr_operand" "")))]
913   "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
915   rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
916   rtx tmp = gen_reg_rtx (SImode);
917   rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
919   if (reg_overlap_mentioned_p (operands[0], operands[1]))
920     operands[1] = copy_to_mode_reg (SImode, operands[1]);
921   emit_insn (gen_floatsisf2 (operands[0], operands[1]));
922   emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
923   emit_insn (gen_sub_f (tmp, tmp, cst));
924   emit_insn (gen_movsfcc (operands[0], cmp,
925                           simplify_gen_subreg (SFmode, tmp, SImode, 0),
926                           operands[0]));
927   DONE;
930 (define_expand "fix_truncsfsi2"
931   [(parallel
932      [(set (match_operand:SI 0 "gpr_operand" "")
933            (fix:SI (match_operand:SF 1 "gpr_operand" "")))
934       (clobber (reg:CC_FP CCFP_REGNUM))])])
936 (define_insn "*fix_truncsfsi2_i"
937   [(match_parallel 2 "float_operation"
938      [(set (match_operand:SI 0 "gpr_operand" "=r")
939            (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
940       (clobber (reg:CC_FP CCFP_REGNUM))])]
941   ""
942   "fix %0, %1"
943   [(set_attr "type" "fp")
944    (set (attr "fp_mode")
945         (cond [(match_test "TARGET_MAY_ROUND_FOR_TRUNC")
946                (const_string "round_unknown")]
947               (const_string "round_trunc")))])
949 (define_expand "fixuns_truncsfsi2"
950   [(set (match_operand:SI 0 "gpr_operand" "")
951         (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
952   ""
954   if (reg_overlap_mentioned_p (operands[0], operands[1]))
955     operands[1] = copy_to_mode_reg (SImode, operands[1]);
956   if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
957     {
958       rtx op1si;
959       /* By toggling what it to be bit31 before the shift, we get a chance to
960          use a short movt insn.  */
961       rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
962       rtx tmp = gen_reg_rtx (SImode);
963       rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
964       rtx cmp
965         = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
967       op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
968       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
969       emit_insn (gen_subsi3_i (tmp, op1si, bit31));
970       emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
971       emit_insn (gen_cmpsi_cc_insn (op1si, limit));
972       emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
973     }
974   else
975     {
976       REAL_VALUE_TYPE offset;
977       rtx limit;
978       rtx tmp = gen_reg_rtx (SFmode);
979       rtx_code_label *label = gen_label_rtx ();
980       rtx bit31;
981       rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
982       rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
984       real_2expN (&offset, 31, SFmode);
985       limit = const_double_from_real_value (offset, SFmode);
986       limit = force_reg (SFmode, limit);
987       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
988       emit_insn (gen_subsf3_f (tmp, operands[1], limit));
989       emit_jump_insn (gen_branch_insn (label, cmp, cc1));
990       bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
991       emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
992       emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
993       emit_label (label);
994     }
995   DONE;
998 (define_expand "iadd"
999   [(parallel
1000      [(set (match_operand:SF 0 "gpr_operand" "")
1001            (plus:SI (match_operand:SF 1 "gpr_operand" "")
1002                     (match_operand:SF 2 "gpr_operand" "")))
1003       (clobber (reg:CC_FP CCFP_REGNUM))])])
1005 (define_insn "*iadd_i"
1006   [(match_parallel 3 "float_operation"
1007      [(set (match_operand:SI 0 "gpr_operand" "=r")
1008            (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
1009                     (match_operand:SI 2 "gpr_operand" "r")))
1010       (clobber (reg:CC_FP CCFP_REGNUM))])]
1011   ""
1012   "iadd %0, %1, %2"
1013   [(set_attr "type" "fp_int")])
1015 (define_expand "isub"
1016   [(parallel
1017      [(set (match_operand:SF 0 "gpr_operand" "")
1018            (minus:SI (match_operand:SF 1 "gpr_operand" "")
1019                      (match_operand:SF 2 "gpr_operand" "")))
1020       (clobber (reg:CC_FP CCFP_REGNUM))])])
1022 (define_insn "*isub_i"
1023   [(match_parallel 3 "float_operation"
1024      [(set (match_operand:SI 0 "gpr_operand" "=r")
1025            (minus:SI (match_operand:SI 1 "gpr_operand" "r")
1026                      (match_operand:SI 2 "gpr_operand" "r")))
1027       (clobber (reg:CC_FP CCFP_REGNUM))])]
1028   ""
1029   "isub %0, %1, %2"
1030   [(set_attr "type" "fp_int")])
1032 ; Try to figure out if we over-committed the FPU, and if so, move
1033 ; some insns back over to the integer pipe.
1035 ; The peephole optimizer 'consumes' the insns that are explicitly
1036 ; mentioned.  We do not want the preceding insn reconsidered, but
1037 ; we do want that for the following one, so that if we have a run
1038 ; of five fpu users, two of them get changed.  Therefore, we
1039 ; use next_active_insn to look at the 'following' insn.  That should
1040 ; exist, because peephole2 runs after reload, and there has to be
1041 ; a return after an fp_int insn.
1042 ; ??? However, we can not even ordinarily match the preceding insn;
1043 ; there is some bug in the generators such that then it leaves out
1044 ; the check for PARALLEL before the length check for the then-second
1045 ; main insn.  Observed when compiling compatibility-atomic-c++0x.cc
1046 ; from libstdc++-v3.
1047 (define_peephole2
1048   [(match_parallel 3 "float_operation"
1049      [(set (match_operand:SI 0 "gpr_operand" "")
1050            (match_operator:SI 4 "addsub_operator"
1051              [(match_operand:SI 1 "gpr_operand" "")
1052               (match_operand:SI 2 "gpr_operand" "")]))
1053       (clobber (reg:CC_FP CCFP_REGNUM))])]
1054   "get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1055    && peep2_regno_dead_p (1, CC_REGNUM)
1056    && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))"
1057   [(parallel [(set (match_dup 0) (match_dup 4))
1058               (clobber (reg:CC CC_REGNUM))])]
1061 (define_peephole2
1062   [(match_parallel 3 "float_operation"
1063      [(set (match_operand:SI 0 "gpr_operand" "")
1064            (mult:SI
1065               (match_operand:SI 1 "gpr_operand" "")
1066               (match_operand:SI 2 "gpr_operand" "")))
1067       (clobber (reg:CC_FP CCFP_REGNUM))])]
1068   "prev_active_insn (peep2_next_insn (0))
1069    && get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1070    && peep2_regno_dead_p (1, CC_REGNUM)
1071    && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))
1072    && find_reg_note (insn, REG_EQUAL, NULL_RTX) != NULL_RTX
1073    && GET_CODE (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0)) == MULT
1074    && CONST_INT_P (XEXP (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0),
1075                          1))"
1076   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 4)))
1077               (clobber (reg:CC CC_REGNUM))])]
1079   operands[4]
1080     = XEXP (XEXP (find_reg_note (curr_insn, REG_EQUAL, NULL_RTX), 0), 1);
1083 (define_expand "mulsi3"
1084   [(parallel
1085      [(set (match_operand:SI 0 "gpr_operand" "")
1086            (mult:SI (match_operand:SI 1 "gpr_operand" "")
1087                     (match_operand:SI 2 "gpr_operand" "")))
1088       (clobber (reg:CC_FP CCFP_REGNUM))])])
1090 (define_insn "*imul"
1091   [(match_parallel 3 "float_operation"
1092      [(set (match_operand:SI 0 "gpr_operand" "=r")
1093            (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
1094                     (match_operand:SI 2 "gpr_operand" "r")))
1095       (clobber (reg:CC_FP CCFP_REGNUM))])]
1096   ""
1097   "imul %0, %1, %2"
1098   [(set_attr "type" "fp_int")])
1100 ; combiner pattern, also used by vector combiner pattern
1101 (define_expand "maddsi"
1102   [(parallel
1103      [(set (match_operand:SI 0 "gpr_operand" "=r")
1104            (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1105                              (match_operand:SI 2 "gpr_operand" "r"))
1106                     (match_operand:SI 3 "gpr_operand" "0")))
1107       (clobber (reg:CC_FP CCFP_REGNUM))])]
1108   "")
1110 (define_insn "*maddsi_combine"
1111   [(match_parallel 4 "float_operation"
1112      [(set (match_operand:SI 0 "gpr_operand" "=r")
1113            (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1114                              (match_operand:SI 2 "gpr_operand" "r"))
1115                     (match_operand:SI 3 "gpr_operand" "0")))
1116       (clobber (reg:CC_FP CCFP_REGNUM))])]
1117   ""
1118   "imadd %0, %1, %2"
1119   [(set_attr "type" "fp_int")])
1121 (define_insn "*imsub"
1122   [(match_parallel 4 "float_operation"
1123      [(set (match_operand:SI 0 "gpr_operand" "=r")
1124            (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1125                      (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1126                               (match_operand:SI 2 "gpr_operand" "r"))))
1127       (clobber (reg:CC_FP CCFP_REGNUM))])]
1128   ""
1129   "imsub %0, %1, %2"
1130   [(set_attr "type" "fp_int")])
1132 (define_expand "divsi3"
1133   [(parallel
1134      [(set (match_operand:SI 0 "move_dest_operand" "")
1135            (div:SI (match_operand:SI 1 "move_src_operand" "")
1136                    (match_operand:SI 2 "move_src_operand" "")))
1137       (use (match_dup 3))
1138       (clobber (reg:SI 0))
1139       (clobber (reg:SI 1))
1140       (clobber (reg:SI GPR_IP))
1141       (clobber (reg:DI GPR_16))
1142       (clobber (reg:DI GPR_18))
1143       (clobber (reg:SI GPR_20))
1144       (clobber (reg:SI GPR_LR))
1145       (clobber (reg:CC CC_REGNUM))
1146       (clobber (reg:CC_FP CCFP_REGNUM))])]
1147   ""
1148   "operands[3] = sfunc_symbol (\"__divsi3\");")
1150 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1151 ;; optimizers can more easily move this insn.
1152 (define_insn_and_split "*divsi3_1"
1153   [(match_parallel 4 "float_operation"
1154      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1155            (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1156                    (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1157       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1158       (clobber (reg:SI 0))
1159       (clobber (reg:SI 1))
1160       (clobber (reg:SI GPR_IP))
1161       (clobber (reg:DI GPR_16))
1162       (clobber (reg:DI GPR_18))
1163       (clobber (reg:SI GPR_20))
1164       (clobber (reg:SI GPR_LR))
1165       (clobber (reg:CC CC_REGNUM))
1166       (clobber (reg:CC_FP CCFP_REGNUM))])]
1167   ""
1168   "#"
1169   "&& reload_completed"
1170   [(set (reg:SI 0) (match_dup 1))
1171    (set (reg:SI 1) (match_dup 2))
1172    (parallel
1173      [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1174       (use (match_dup 3))
1175       (clobber (reg:SI 1))
1176       (clobber (reg:SI GPR_IP))
1177       (clobber (reg:DI GPR_16))
1178       (clobber (reg:DI GPR_18))
1179       (clobber (reg:SI GPR_20))
1180       (clobber (reg:SI GPR_LR))
1181       (clobber (reg:CC CC_REGNUM))
1182       (clobber (reg:CC_FP CCFP_REGNUM))
1183       (match_dup 5)
1184       (match_dup 6)])
1185    (set (match_dup 0) (reg:SI 0))]
1186   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1187    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1188   [(set_attr "type" "fp_sfunc")
1189    (set_attr "length" "16,24")])
1191 (define_insn "*divsi3_2"
1192   [(match_parallel 1 "float_operation"
1193      [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1194       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1195       (clobber (reg:SI 1))
1196       (clobber (reg:SI GPR_IP))
1197       (clobber (reg:DI GPR_16))
1198       (clobber (reg:DI GPR_18))
1199       (clobber (reg:SI GPR_20))
1200       (clobber (reg:SI GPR_LR))
1201       (clobber (reg:CC CC_REGNUM))
1202       (clobber (reg:CC_FP CCFP_REGNUM))])]
1203   ""
1204   "%f0"
1205   [(set_attr "type" "fp_sfunc")])
1207 (define_expand "udivsi3"
1208   [(parallel
1209      [(set (match_operand:SI 0 "move_dest_operand" "")
1210            (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1211                     (match_operand:SI 2 "move_src_operand" "")))
1212       (use (match_dup 3))
1213       (clobber (reg:SI 0))
1214       (clobber (reg:SI 1))
1215       (clobber (reg:SI GPR_IP))
1216       (clobber (reg:DI GPR_16))
1217       (clobber (reg:SI GPR_18))
1218       (clobber (reg:SI GPR_LR))
1219       (clobber (reg:CC CC_REGNUM))
1220       (clobber (reg:CC_FP CCFP_REGNUM))])]
1221   ""
1222   "operands[3] = sfunc_symbol (\"__udivsi3\");")
1224 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1225 ;; optimizers can more easily move this insn.
1226 (define_insn_and_split "*udivsi3_1"
1227   [(match_parallel 4 "float_operation"
1228      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1229            (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1230                     (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1231       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1232       (clobber (reg:SI 0))
1233       (clobber (reg:SI 1))
1234       (clobber (reg:SI GPR_IP))
1235       (clobber (reg:DI GPR_16))
1236       (clobber (reg:SI GPR_18))
1237       (clobber (reg:SI GPR_LR))
1238       (clobber (reg:CC CC_REGNUM))
1239       (clobber (reg:CC_FP CCFP_REGNUM))])]
1240   ""
1241   "#"
1242   "&& reload_completed"
1243   [(set (reg:SI 0) (match_dup 1))
1244    (set (reg:SI 1) (match_dup 2))
1245    (parallel
1246      [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1247       (use (match_dup 3))
1248       (clobber (reg:SI 1))
1249       (clobber (reg:SI GPR_IP))
1250       (clobber (reg:DI GPR_16))
1251       (clobber (reg:SI GPR_18))
1252       (clobber (reg:SI GPR_LR))
1253       (clobber (reg:CC CC_REGNUM))
1254       (clobber (reg:CC_FP CCFP_REGNUM))
1255       (match_dup 5)
1256       (match_dup 6)])
1257    (set (match_dup 0) (reg:SI 0))]
1258   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1259    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1260   [(set_attr "type" "fp_sfunc")
1261    (set_attr "length" "16,24")])
1263 (define_insn "*udivsi3_2"
1264   [(match_parallel 1 "float_operation"
1265      [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1266       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1267       (clobber (reg:SI 1))
1268       (clobber (reg:SI GPR_IP))
1269       (clobber (reg:DI GPR_16))
1270       (clobber (reg:SI GPR_18))
1271       (clobber (reg:SI GPR_LR))
1272       (clobber (reg:CC CC_REGNUM))
1273       (clobber (reg:CC_FP CCFP_REGNUM))])]
1274   ""
1275   "%f0"
1276   [(set_attr "type" "fp_sfunc")])
1278 (define_expand "modsi3"
1279   [(parallel
1280      [(set (match_operand:SI 0 "move_dest_operand" "")
1281            (mod:SI (match_operand:SI 1 "move_src_operand" "")
1282                    (match_operand:SI 2 "move_src_operand" "")))
1283       (use (match_dup 3))
1284       (clobber (reg:SI 0))
1285       (clobber (reg:SI 1))
1286       (clobber (reg:SI 2))
1287       (clobber (reg:SI GPR_IP))
1288       (clobber (reg:DI GPR_16))
1289       (clobber (reg:DI GPR_18))
1290       (clobber (reg:SI GPR_LR))
1291       (clobber (reg:CC CC_REGNUM))
1292       (clobber (reg:CC_FP CCFP_REGNUM))])]
1293   ""
1294   "operands[3] = sfunc_symbol (\"__modsi3\");")
1296 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1297 ;; optimizers can more easily move this insn.
1298 (define_insn_and_split "*modsi3_1"
1299   [(match_parallel 4 "float_operation"
1300      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1301            (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1302                    (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1303       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1304       (clobber (reg:SI 0))
1305       (clobber (reg:SI 1))
1306       (clobber (reg:SI 2))
1307       (clobber (reg:SI GPR_IP))
1308       (clobber (reg:DI GPR_16))
1309       (clobber (reg:DI GPR_18))
1310       (clobber (reg:SI GPR_LR))
1311       (clobber (reg:CC CC_REGNUM))
1312       (clobber (reg:CC_FP CCFP_REGNUM))])]
1313   ""
1314   "#"
1315   "&& reload_completed"
1316   [(set (reg:SI 0) (match_dup 1))
1317    (set (reg:SI 1) (match_dup 2))
1318    (parallel
1319      [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1320       (use (match_dup 3))
1321       (clobber (reg:SI 2))
1322       (clobber (reg:SI GPR_IP))
1323       (clobber (reg:DI GPR_16))
1324       (clobber (reg:DI GPR_18))
1325       (clobber (reg:SI GPR_LR))
1326       (clobber (reg:CC CC_REGNUM))
1327       (clobber (reg:CC_FP CCFP_REGNUM))
1328       (match_dup 5)
1329       (match_dup 6)])
1330    (set (match_dup 0) (reg:SI 0))]
1331   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1332    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1333   [(set_attr "type" "fp_sfunc")
1334    (set_attr "length" "16,24")])
1336 (define_insn "*modsi3_2"
1337   [(match_parallel 1 "float_operation"
1338      [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1339       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1340       (clobber (reg:SI 2))
1341       (clobber (reg:SI GPR_IP))
1342       (clobber (reg:DI GPR_16))
1343       (clobber (reg:DI GPR_18))
1344       (clobber (reg:SI GPR_LR))
1345       (clobber (reg:CC CC_REGNUM))
1346       (clobber (reg:CC_FP CCFP_REGNUM))])]
1347   ""
1348   "%f0"
1349   [(set_attr "type" "fp_sfunc")])
1351 (define_expand "umodsi3"
1352   [(parallel
1353      [(set (match_operand:SI 0 "move_dest_operand" "")
1354            (umod:SI (match_operand:SI 1 "move_src_operand" "")
1355                     (match_operand:SI 2 "move_src_operand" "")))
1356       (use (match_dup 3))
1357       (clobber (reg:SI 0))
1358       (clobber (reg:SI 1))
1359       (clobber (reg:SI 2))
1360       (clobber (reg:SI GPR_IP))
1361       (clobber (reg:DI GPR_16))
1362       (clobber (reg:SI GPR_LR))
1363       (clobber (reg:CC CC_REGNUM))
1364       (clobber (reg:CC_FP CCFP_REGNUM))])]
1365   ""
1366   "operands[3] = sfunc_symbol (\"__umodsi3\");")
1368 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1369 ;; optimizers can more easily move this insn.
1370 (define_insn_and_split "*umodsi3_1"
1371   [(match_parallel 4 "float_operation"
1372      [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1373            (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1374                     (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1375       (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1376       (clobber (reg:SI 0))
1377       (clobber (reg:SI 1))
1378       (clobber (reg:SI 2))
1379       (clobber (reg:SI GPR_IP))
1380       (clobber (reg:DI GPR_16))
1381       (clobber (reg:SI GPR_LR))
1382       (clobber (reg:CC CC_REGNUM))
1383       (clobber (reg:CC_FP CCFP_REGNUM))])]
1384   ""
1385   "#"
1386   "&& reload_completed"
1387   [(set (reg:SI 0) (match_dup 1))
1388    (set (reg:SI 1) (match_dup 2))
1389    (parallel
1390      [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1391       (use (match_dup 3))
1392       (clobber (reg:SI 2))
1393       (clobber (reg:SI GPR_IP))
1394       (clobber (reg:DI GPR_16))
1395       (clobber (reg:SI GPR_LR))
1396       (clobber (reg:CC CC_REGNUM))
1397       (clobber (reg:CC_FP CCFP_REGNUM))
1398       (match_dup 5)
1399       (match_dup 6)])
1400    (set (match_dup 0) (reg:SI 0))]
1401   "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1402    operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1403   [(set_attr "type" "fp_sfunc")
1404    (set_attr "length" "16,24")])
1406 (define_insn "*umodsi3_2"
1407   [(match_parallel 1 "float_operation"
1408      [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1409       (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1410       (clobber (reg:SI 2))
1411       (clobber (reg:SI GPR_IP))
1412       (clobber (reg:DI GPR_16))
1413       (clobber (reg:SI GPR_LR))
1414       (clobber (reg:CC CC_REGNUM))
1415       (clobber (reg:CC_FP CCFP_REGNUM))])]
1416   ""
1417   "%f0"
1418   [(set_attr "type" "fp_sfunc")])
1420 ; Disable interrupts.
1421 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1422 ; might have changed settings that we do not want to mess with.
1423 (define_insn "gid"
1424   [(set (reg:SI CONFIG_REGNUM)
1425         (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1426   ""
1427   "gid"
1428   [(set_attr "type" "flow")])
1430 ; Enable interrupts.
1431 ; Present CONTROL_REGNUM here to make sure it is live before the
1432 ; actual uses in floating point insns / calls are inserted.
1433 ; FWIW, interrupts also do mind what is in the control register.
1434 (define_insn "gie"
1435   [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1436   ""
1437   "gie"
1438   [(set_attr "type" "flow")])
1440 ; Floating point instructions require manipulating the control register.
1441 ; Manipulating the control register needs arithmetic.
1442 ; Arithmetic clobbers flags.
1443 ; The flags are in the status register, which also contains the alternate
1444 ; flag and the interrupt enable/disable bits.
1445 ; saving/restoring status and mixing up the order with gid/gie could
1446 ; lead to disaster.
1447 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1448 ; away.  But when we really need it, we must make sure that we don't change
1449 ; anything but the flags.
1450 ; N.B.: We could make the constant easier to load by inverting it, but
1451 ; then we'd need to clobber the saved value - and that would make optimizing
1452 ; away unneeded saves/restores harder / less likely.
1453 (define_expand "movcc"
1454   [(parallel [(set (match_operand:CC 0 "cc_move_operand"  "")
1455                    (match_operand:CC 1 "cc_move_operand" ""))
1456               (use (match_dup 2))
1457               (clobber (match_scratch:SI 3                 "=X, &r"))])]
1458   ""
1459   "operands[2] = gen_int_mode (~0x10f0, SImode);")
1461 (define_insn "*movcc_i"
1462   [(set (match_operand:CC 0 "cc_move_operand"  "=r,Rcc")
1463         (match_operand:CC 1 "cc_move_operand" "Rcc,  r"))
1464    (use (match_operand:SI 2 "nonmemory_operand"  "X,  r"))
1465    (clobber (match_scratch:SI 3                 "=X, &r"))]
1466   ""
1467   "@
1468    movfs %0,status
1469    movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1470   [(set_attr "type" "flow")
1471    (set_attr "length" "20,4")])
1473 (define_insn_and_split "save_config"
1474   [(set (match_operand:SI 0 "gpr_operand" "=r") (reg:SI CONFIG_REGNUM))
1475    (use (reg:SI FP_NEAREST_REGNUM))
1476    (use (reg:SI FP_TRUNCATE_REGNUM))
1477    (use (reg:SI FP_ANYFP_REGNUM))]
1478   ""
1479   "#"
1480   "reload_completed"
1481   [(set (match_dup 0) (reg:SI CONFIG_REGNUM))])
1483 (define_insn_and_split "set_fp_mode"
1484   [(set (reg:SI FP_NEAREST_REGNUM)
1485         (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1486    (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1487    (set (reg:SI FP_ANYFP_REGNUM)
1488         (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1489    (use (match_operand:SI 2 "gpr_operand" "r"))
1490    (clobber (reg:CC CC_REGNUM))
1491    (clobber (match_scratch:SI 3 "=&r"))]
1492   ""
1493   "#"
1494   "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1495   [(const_int 0)]
1497   if (!reload_completed)
1498     emit_note (NOTE_INSN_DELETED);
1499   else
1500     epiphany_expand_set_fp_mode (operands);
1501   DONE;
1505 ;; Boolean instructions.
1507 ;; We don't define the DImode versions as expand_binop does a good enough job.
1509 (define_insn "andsi3"
1510   [(set (match_operand:SI 0 "gpr_operand" "=r")
1511         (and:SI (match_operand:SI 1 "gpr_operand" "r")
1512                 (match_operand:SI 2 "gpr_operand" "r")))
1513    (clobber (reg:CC CC_REGNUM))]
1514   ""
1515   "and %0,%1,%2")
1517 (define_insn "iorsi3"
1518   [(set (match_operand:SI 0 "gpr_operand" "=r")
1519         (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1520                 (match_operand:SI 2 "gpr_operand" "r")))
1521    (clobber (reg:CC CC_REGNUM))]
1522   ""
1523   "orr %0,%1,%2")
1525 (define_insn "xorsi3"
1526   [(set (match_operand:SI 0 "gpr_operand" "=r")
1527         (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1528                 (match_operand:SI 2 "gpr_operand" "r")))
1529    (clobber (reg:CC CC_REGNUM))]
1530   ""
1531   "eor %0,%1,%2")
1533 (define_expand "one_cmplsi2"
1534   [(set (match_operand:SI 0 "gpr_operand" "")
1535         (xor:SI (match_operand:SI 1 "gpr_operand" "")
1536                 (match_dup 2)))]
1537   ""
1539   if (epiphany_m1reg >= 0)
1540     emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1541   else
1542     emit_insn (gen_xorsi3 (operands[0], operands[1],
1543                            force_reg (SImode, GEN_INT (-1))));
1544   DONE;
1547 ; Note that folding this pattern into the xorsi3 pattern would make combine
1548 ; less effective.
1549 (define_insn "one_cmplsi2_i"
1550   [(set (match_operand:SI 0 "gpr_operand" "=r")
1551         (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1552    (clobber (reg:CC CC_REGNUM))]
1553   "epiphany_m1reg >= 0"
1554   "eor %0,%1,%-")
1556 ;; Shift instructions.
1557 ;; In principle we could support arbitrary symbolic values as shift constant
1558 ;; (truncating the value appropriately), but that would require a suitable
1559 ;; relocation and assembler & linker support.
1560 (define_insn "ashrsi3"
1561   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1562         (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1563                      (match_operand:SI 2 "arith_operand" "r,K")))
1564    (clobber (reg:CC CC_REGNUM))]
1565   ""
1566   "asr %0,%1,%2"
1567   [(set_attr "length" "4")
1568    (set_attr "type" "shift")])
1570 (define_insn "ashrsi3_tst"
1571   [(set (reg:CC CC_REGNUM)
1572         (compare:CC
1573           (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1574                        (match_operand:SI 2 "arith_operand" "r,K"))
1575         (const_int 0)))
1576    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1577         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1578   ""
1579   "asr %0,%1,%2"
1580   [(set_attr "length" "4")
1581    (set_attr "type" "shift")])
1583 ;; Logical Shift Right
1584 (define_insn "lshrsi3"
1585   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1586         (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1587                      (match_operand:SI 2 "arith_operand" "r,K")))
1588    (clobber (reg:CC CC_REGNUM))]
1589   ""
1590   "lsr %0,%1,%2"
1591   [(set_attr "length" "4")
1592    (set_attr "type" "shift")])
1594 (define_insn "lshrsi3_tst"
1595   [(set (reg:CC CC_REGNUM)
1596         (compare:CC
1597           (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1598                        (match_operand:SI 2 "arith_operand" "r,K"))
1599         (const_int 0)))
1600    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1601         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1602   ""
1603   "lsr %0,%1,%2"
1604   [(set_attr "length" "4")
1605    (set_attr "type" "shift")])
1607 ;; Logical/Arithmetic Shift Left
1608 (define_insn "ashlsi3"
1609   [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1610         (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1611                    (match_operand:SI 2 "arith_operand" "r,K")))
1612    (clobber (reg:CC CC_REGNUM))]
1613   ""
1614   "lsl %0,%1,%2"
1615   [(set_attr "length" "4")
1616    (set_attr "type" "shift")])
1618 (define_insn "*ashlsi_btst"
1619   [(set (reg:CC_N_NE CC_REGNUM)
1620         (compare:CC_N_NE
1621           (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1622                            (const_int 1)
1623                            (match_operand 2 "const_int_operand" "K"))
1624           (const_int 0)))
1625    (clobber (match_scratch:SI 0 "=r"))]
1626   ""
1628   rtx xop[3];
1630   xop[0] = operands[0];
1631   xop[1] = operands[1];
1632   xop[2] = GEN_INT (31-INTVAL (operands[2]));
1633   output_asm_insn ("lsl %0,%1,%2", xop);
1634   return "";
1637 ;; zero extensions
1638 (define_insn_and_split "zero_extendqisi2"
1639   [(set (match_operand:SI 0 "register_operand" "=r,r")
1640         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1641    (clobber (reg:CC CC_REGNUM))]
1642   ""
1643   "@
1644    #
1645    ldrb %0,%1"
1646   "reload_completed
1647    ? true_regnum (operands[1]) >= 0
1648    : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1649   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1650               (clobber (reg:CC CC_REGNUM))])
1651    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1652               (clobber (reg:CC CC_REGNUM))])]
1653   "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1655 (define_insn "zero_extendhisi2"
1656   [(set (match_operand:SI 0 "register_operand" "=r,r")
1657         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1658   ""
1659   "@
1660    movt %0, 0
1661    ldrh %0,%c1")
1664 ;; Compare instructions.
1666 (define_insn "cmpsi_cc_insn"
1667   [(set (reg:CC CC_REGNUM)
1668         (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1669                     (match_operand:SI 1 "arith_operand" "r,L")))
1670    (clobber (match_scratch:SI 2 "=r,r"))]
1671   ""
1672   "sub %2,%0,%1"
1673   [(set_attr "type" "compare")])
1675 (define_insn "sub_f"
1676   [(set (reg:CC CC_REGNUM)
1677         (compare:CC (match_operand:SI 1 "gpr_operand"  "r,r")
1678                     (match_operand:SI 2 "arith_operand" "r,L")))
1679    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1680         (minus:SI (match_dup 1) (match_dup 2)))]
1681   ""
1682   "sub %0,%1,%2"
1683   [(set_attr "type" "compare")])
1685 (define_insn "*sub_f_add_imm"
1686   [(set (reg:CC CC_REGNUM)
1687         (compare:CC (match_operand:SI 1 "gpr_operand"  "r")
1688                     (match_operand:SI 2 "arith_int_operand" "L")))
1689    (set (match_operand:SI 0 "gpr_operand" "=r")
1690         (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "CnL")))]
1691   "INTVAL (operands[2]) == -INTVAL (operands[3])"
1692   "sub %0,%1,%2"
1693   [(set_attr "type" "compare")])
1695 (define_expand "abssi2"
1696   [(set (match_dup 2) (const_int 0))
1697    (parallel [(set (reg:CC CC_REGNUM)
1698                    (compare:CC (match_dup 2)
1699                                (match_operand:SI 1 "nonmemory_operand" "")))
1700               (set (match_dup 3)
1701                    (minus:SI (match_dup 2) (match_dup 1)))])
1702    (set (match_operand:SI 0 "gpr_operand" "=r")
1703         (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1704                          (match_dup 3)
1705                          (match_dup 1)))]
1706   "TARGET_CMOVE"
1707   "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1709 (define_insn "*add_c"
1710   [(set (reg:CC_C_LTU CC_REGNUM)
1711         (compare:CC_C_LTU
1712           (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1713                    (match_operand:SI 2 "arith_operand" "r,L"))
1714           (match_dup 1)))
1715    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1716         (plus:SI (match_dup 1) (match_dup 2)))]
1717   ""
1718   "add %0,%1,%2"
1719   [(set_attr "type" "compare")])
1721 (define_insn "*add_c_rev"
1722   [(set (reg:CC_C_LTU CC_REGNUM)
1723         (compare:CC_C_LTU
1724           (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1725                    (match_operand:SI 2 "arith_operand" "r,L"))
1726           (match_dup 1)))
1727    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1728         (plus:SI (match_dup 2) (match_dup 1)))]
1729   ""
1730   "add %0,%1,%2"
1731   [(set_attr "type" "compare")])
1733 (define_insn "*sub_c"
1734   [(set (reg:CC_C_GTU CC_REGNUM)
1735         (compare:CC_C_GTU
1736           (minus:SI (match_operand:SI 1 "gpr_operand"  "r,r")
1737                     (match_operand:SI 2 "arith_operand" "r,L"))
1738           (match_dup 1)))
1739    (set (match_operand:SI 0 "gpr_operand" "=r,r")
1740         (minus:SI (match_dup 1) (match_dup 2)))]
1741   ""
1742   "sub %0,%1,%2"
1743   [(set_attr "type" "compare")])
1745 (define_insn "*sub_c_void"
1746   [(set (reg:CC_C_GTU CC_REGNUM)
1747         (compare:CC_C_GTU
1748           (minus:SI (match_operand:SI 1 "gpr_operand"  "r,r")
1749                     (match_operand:SI 2 "arith_operand" "r,L"))
1750           (match_dup 1)))
1751    (clobber (match_scratch:SI 0 "=r,r"))]
1752   ""
1753   "sub %0,%1,%2"
1754   [(set_attr "type" "compare")])
1756 (define_code_iterator logical_op
1757   [and ior xor])
1759 (define_code_attr op_mnc
1760   [(plus "add") (minus "sub") (and "and") (ior "orr") (xor "eor")])
1762 (define_insn "*<op_mnc>_f"
1763   [(set (reg:CC CC_REGNUM)
1764         (compare:CC (logical_op:SI (match_operand:SI 1 "gpr_operand" "%r")
1765                                    (match_operand:SI 2 "gpr_operand"  "r"))
1766                     (const_int 0)))
1767    (set (match_operand:SI 0 "gpr_operand" "=r")
1768         (logical_op:SI (match_dup 1) (match_dup 2)))]
1769   ""
1770   "<op_mnc> %0,%1,%2"
1771   [(set_attr "type" "compare")])
1773 (define_insn_and_split "*mov_f"
1774   [(set (reg:CC CC_REGNUM)
1775         (compare:CC (match_operand:SI 1 "gpr_operand"  "r") (const_int 0)))
1776    (set (match_operand:SI 0 "gpr_operand" "=r") (match_dup 1))]
1777   ""
1778   "#"
1779   "reload_completed"
1780   [(parallel
1781     [(set (reg:CC CC_REGNUM)
1782           (compare:CC (and:SI (match_dup 1) (match_dup 1)) (const_int 0)))
1783      (set (match_operand:SI 0 "gpr_operand" "=r")
1784           (and:SI (match_dup 1) (match_dup 1)))])]
1785   ""
1786   [(set_attr "type" "compare")])
1788 (define_peephole2
1789   [(parallel
1790     [(set (match_operand:SI 0 "gpr_operand")
1791           (logical_op:SI (match_operand:SI 1 "gpr_operand")
1792                          (match_operand:SI 2 "gpr_operand")))
1793      (clobber (reg:CC CC_REGNUM))])
1794    (parallel
1795     [(set (reg:CC CC_REGNUM)
1796           (compare:CC (and:SI (match_dup 0) (match_dup 0)) (const_int 0)))
1797      (set (match_operand:SI 3 "gpr_operand")
1798           (and:SI (match_dup 0) (match_dup 0)))])]
1799   "peep2_reg_dead_p (2, operands[0])"
1800   [(parallel
1801     [(set (reg:CC CC_REGNUM)
1802           (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1803                       (const_int 0)))
1804      (set (match_dup 3) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1806 (define_peephole2
1807   [(parallel
1808     [(set (match_operand:SI 0 "gpr_operand")
1809           (logical_op:SI (match_operand:SI 1 "gpr_operand")
1810                          (match_operand:SI 2 "gpr_operand")))
1811      (clobber (reg:CC CC_REGNUM))])
1812    (parallel
1813     [(set (reg:CC CC_REGNUM)
1814           (compare:CC (and:SI (match_dup 0) (match_dup 0)) (const_int 0)))
1815      (set (match_operand:SI 3 "gpr_operand")
1816           (and:SI (match_dup 0) (match_dup 0)))])]
1817   "peep2_reg_dead_p (2, operands[3])"
1818   [(parallel
1819     [(set (reg:CC CC_REGNUM)
1820           (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1821                       (const_int 0)))
1822      (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1824 (define_peephole2
1825   [(parallel
1826     [(set (match_operand:SI 0 "gpr_operand")
1827           (logical_op:SI (match_operand:SI 1 "gpr_operand")
1828                          (match_operand:SI 2 "gpr_operand")))
1829      (clobber (reg:CC CC_REGNUM))])
1830    (parallel
1831     [(set (reg:CC CC_REGNUM)
1832           (compare:CC (match_dup 0) (const_int 0)))
1833      (clobber (match_operand:SI 3 "gpr_operand"))])]
1834   ""
1835   [(parallel
1836     [(set (reg:CC CC_REGNUM)
1837           (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1838                       (const_int 0)))
1839      (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1841 (define_expand "cstoresi4"
1842   [(parallel
1843     [(set (reg:CC CC_REGNUM)
1844           (match_operand:SI 1 "comparison_operator"))
1845      (match_operand:SI 2 "" "")])
1846    (set (match_dup 0) (match_operand:SI 3 "arith_operand" ""))
1847    (set (match_operand:SI 0 "gpr_operand" "=r")
1848         (if_then_else:SI (match_dup 4) (match_dup 5) (match_dup 0)))]
1849   ""
1851   enum rtx_code o2_code = GET_CODE (operands[2]);
1852   enum rtx_code cmp_code = GET_CODE (operands[1]);
1854   if ((o2_code == AND || o2_code == IOR || o2_code == XOR)
1855       && operands[3] == const0_rtx)
1856     {
1857       operands[2] = copy_rtx(operands[2]);
1858       XEXP (operands[2], 0) = force_reg (SImode, XEXP (operands[2], 0));
1859       XEXP (operands[2], 1) = force_reg (SImode, XEXP (operands[2], 1));
1860     }
1861   else
1862     operands[2] = force_reg (SImode, operands[2]);
1863   operands[1] = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
1864   if (cmp_code != NE)
1865     {
1866       operands[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode));
1867       operands[3] = const0_rtx;
1868     }
1869   else
1870     {
1871       if (operands[3] != const0_rtx)
1872         operands[2] = gen_rtx_MINUS (SImode, operands[2], operands[3]);
1873       operands[2] = gen_rtx_SET (operands[0], operands[2]);
1874       operands[3] = operands[0];
1875     }
1876   operands[4] = gen_rtx_fmt_ee (cmp_code, SImode,
1877                                 gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
1878   operands[5] = force_reg (SImode, GEN_INT (STORE_FLAG_VALUE));
1882 ; floating point comparisons
1884 (define_insn "*cmpsf_cc_insn"
1885   [(match_parallel 3 "float_operation"
1886      [(set (reg:CC_FP CCFP_REGNUM)
1887            (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1888                           (match_operand:SF 1 "gpr_operand" "r")))
1889       (clobber (match_scratch:SF 2 "=r"))])]
1890   "!TARGET_SOFT_CMPSF"
1891   "fsub %2,%0,%1"
1892   [(set_attr "type" "fp")
1893    (set_attr "fp_mode" "round_unknown")])
1895 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1896 ;; to allow the rtl loop optimizer to generate comparisons?  OTOH
1897 ;; we want call_address_operand to enforce valid operands so that
1898 ;; combine won't do silly things, allowing instruction scheduling to do
1899 ;; a proper job.
1900 (define_insn "*cmpsf_eq"
1901   [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (reg:SF 0) (reg:SF 1)))
1902    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1903    (clobber (reg:SI GPR_IP))
1904    (clobber (reg:SI GPR_LR))]
1905   "TARGET_SOFT_CMPSF"
1906   "%f0"
1907   [(set_attr "type" "sfunc")])
1909 (define_insn "*cmpsf_gte"
1910   [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (reg:SF 0) (reg:SF 1)))
1911    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1912    (clobber (reg:SI GPR_IP))
1913    (clobber (reg:SI GPR_LR))]
1914   "TARGET_SOFT_CMPSF"
1915   "%f0"
1916   [(set_attr "type" "sfunc")])
1918 (define_insn "*cmpsf_ord"
1919   [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1920    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1921    (clobber (reg:SI GPR_IP))
1922    (clobber (reg:SI GPR_16))
1923    (clobber (reg:SI GPR_LR))]
1924   ""
1925   "%f0"
1926   [(set_attr "type" "sfunc")])
1928 (define_insn "*cmpsf_uneq"
1929   [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1930    (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1931    (clobber (reg:SI GPR_IP))
1932    (clobber (reg:SI GPR_16))
1933    (clobber (reg:SI GPR_LR))]
1934   "TARGET_SOFT_CMPSF"
1935   "%f0"
1936   [(set_attr "type" "sfunc")])
1938 ;; conditional moves
1940 (define_expand "mov<mode>cc"
1941   [(set (match_operand:WMODE 0 "gpr_operand" "")
1942         (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1943                             (match_operand:WMODE 2 "gpr_operand" "")
1944                             (match_operand:WMODE 3 "gpr_operand" "")))]
1945   "TARGET_CMOVE"
1947   rtx cmp_op0 = XEXP (operands[1], 0);
1948   rtx cmp_op1 = XEXP (operands[1], 1);
1949   machine_mode cmp_in_mode;
1950   enum rtx_code code = GET_CODE (operands[1]);
1952   cmp_in_mode = GET_MODE (cmp_op0);
1953   if (cmp_in_mode == VOIDmode)
1954     cmp_in_mode = GET_MODE (cmp_op1);
1955   if (cmp_in_mode == VOIDmode)
1956     cmp_in_mode = SImode;
1957   /* If the operands are a better match when reversed, swap them now.
1958      This allows combine to see the proper comparison codes.  */
1959   if (rtx_equal_p (operands[0], operands[2])
1960       && !rtx_equal_p (operands[0], operands[3]))
1961     {
1962       rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1963       code = (FLOAT_MODE_P (GET_MODE (cmp_op0)) && !flag_finite_math_only
1964               ? reverse_condition_maybe_unordered (code)
1965               : reverse_condition (code));
1966     }
1968   if (proper_comparison_operator (operands[1], VOIDmode))
1969     operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1970   else
1971     {
1972       if (!currently_expanding_to_rtl)
1973         {
1974           /* ???  It would seem safest to FAIL here, but that would defeat
1975              the purpose of having an if-conversion pass; its logic currently
1976              assumes that the backend should be safe to insert condition code
1977              setting instructions, as the same condition codes were presumably
1978              set by the if-conversion input code.  */
1979         }
1980       /* What mode to give as first operand to gen_compare_reg here is
1981          debatable.  VOIDmode would be minimalist; telling gen_compare_reg
1982          to use the mode of CC_REGNUM (or putting it on the comparison
1983          operator afterwards) is also a logical choice.  OTOH, by using
1984          <MODE>mode, we have mode combine opportunities with flag setting
1985          operations - if we get some.  */
1986       operands[1]
1987         = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1988       if (!operands[1])
1989         FAIL;
1990     }
1993 (define_insn "*mov<mode>cc_insn"
1994   [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1995         (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1996                               [(match_operand 4 "cc_operand") (const_int 0)])
1997                             (match_operand:WMODE 1 "gpr_operand" "r")
1998                             (match_operand:WMODE 2 "gpr_operand" "0")))]
1999   "TARGET_CMOVE"
2000   "mov%d3 %0,%1"
2001   [(set_attr "type" "cmove")])
2003 (define_peephole2
2004   [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
2005                    (match_operand:WMODE 1 "" ""))
2006               (clobber (match_operand 8 "cc_operand"))])
2007    (match_operand 2 "" "")
2008    (set (match_operand:WMODE2 3 "gpr_operand" "")
2009         (match_operand:WMODE2 9 "gpr_operand" ""))
2010    (set (match_dup 3)
2011         (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
2012                                [(match_operand 6 "cc_operand")
2013                                 (match_operand 7 "const0_operand")])
2014                              (match_operand:WMODE2 4 "nonmemory_operand" "")
2015                              (match_dup 3)))]
2016   "REGNO (operands[0]) == REGNO (operands[9])
2017    && peep2_reg_dead_p (3, operands[0])
2018    && !reg_set_p (operands[0], operands[2])
2019    && !reg_set_p (operands[3], operands[2])
2020    && !reg_overlap_mentioned_p (operands[3], operands[2])"
2021   [(parallel [(set (match_dup 10) (match_dup 1))
2022               (clobber (match_dup 8))])
2023    (match_dup 2)
2024    (set (match_dup 3)
2025         (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
2027   operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
2028                                       <WMODE2:MODE>mode, 0);
2029   replace_rtx (operands[2], operands[9], operands[3], true);
2030   replace_rtx (operands[2], operands[0], operands[10], true);
2031   gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
2034 (define_peephole2
2035   [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
2036               (set (match_operand:WMODE 0 "gpr_operand" "")
2037                    (match_operand:WMODE 1 "" ""))])
2038    (set (match_operand:WMODE2 3 "gpr_operand" "")
2039         (match_operand:WMODE2 4 "gpr_operand"))
2040    (set (match_dup 3)
2041         (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
2042                                [(match_dup 6)
2043                                (match_operand:WMODE 7 "const0_operand")])
2044                             (match_operand:WMODE2 8 "gpr_operand")
2045                             (match_dup 3)))]
2046   "REGNO (operands[0]) == REGNO (operands[8])
2047    && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
2048    && peep2_reg_dead_p (3, operands[6])
2049    && peep2_reg_dead_p (3, operands[0])
2050    && !reg_overlap_mentioned_p (operands[4], operands[3])"
2051   [(parallel [(set (match_dup 6) (match_dup 2))
2052               (set (match_dup 9) (match_dup 1))])
2053    (set (match_dup 3)
2054         (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
2055   "
2057   operands[5]
2058     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
2059                                          GET_MODE (operands[6])),
2060                       GET_MODE (operands[5]), operands[6], operands[7]);
2061   operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
2062                                      <WMODE2:MODE>mode, 0);
2065 ;; These control RTL generation for conditional jump insns
2067 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
2068 ;; they must allow const0_rtx for both comparison operands
2069 (define_expand "cbranchsi4"
2070   [(set (reg CC_REGNUM)
2071         (compare (match_operand:SI 1 "add_operand" "")
2072                  (match_operand:SI 2 "arith_operand" "")))
2073    (set (pc)
2074         (if_then_else
2075               (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
2076                                                                (const_int 0)])
2077               (label_ref (match_operand 3 "" ""))
2078               (pc)))]
2079   ""
2081   rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
2082                              operands[1], operands[2]);
2083   emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
2084   DONE;
2087 (define_expand "cbranchsf4"
2088   [(set (reg CC_REGNUM)
2089         (compare (match_operand:SF 1 "arith_operand" "")
2090                  (match_operand:SF 2 "arith_operand" "")))
2091    (set (pc)
2092         (if_then_else
2093               (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
2094                                                        (const_int 0)])
2095               (label_ref (match_operand 3 "" ""))
2096               (pc)))]
2097   ""
2099   rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
2100                              operands[1], operands[2]);
2101   emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
2102   DONE;
2105 ;; Now match both normal and inverted jump.
2107 (define_insn "branch_insn"
2108   [(set (pc)
2109         (if_then_else (match_operator 1 "proper_comparison_operator"
2110                                       [(match_operand 2 "cc_operand")
2111                                        (const_int 0)])
2112                       (label_ref (match_operand 0 "" ""))
2113                       (pc)))]
2114   ""
2115   "b%d1 %l0"
2116   [(set_attr "type" "branch")])
2118 (define_insn "*rev_branch_insn"
2119   [(set (pc)
2120         (if_then_else (match_operator 1 "proper_comparison_operator"
2121                                       [(reg CC_REGNUM) (const_int 0)])
2122                       (pc)
2123                       (label_ref (match_operand 0 "" ""))))]
2124   ""
2125   "b%D1 %l0"
2126   [(set_attr "type" "branch")])
2128 ;; Unconditional and other jump instructions.
2130 (define_insn "jump"
2131   [(set (pc) (label_ref (match_operand 0 "" "")))]
2132   ""
2133   "b %l0"
2134   [(set_attr "type" "uncond_branch")])
2136 (define_insn "indirect_jump"
2137   [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
2138   ""
2139   "jr %0"
2140   [(set_attr "type" "uncond_branch")])
2142 (define_expand "tablejump"
2143   [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
2144               (use (label_ref (match_operand 1 "" "")))])]
2145   ""
2147   /* In PIC mode, the table entries are stored PC relative.
2148      Convert the relative address to an absolute address.  */
2149   if (flag_pic)
2150     {
2151       rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
2153       operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2154                                          op1, NULL_RTX, 0, OPTAB_DIRECT);
2155     }
2158 (define_insn "*tablejump_internal"
2159   [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
2160    (use (label_ref (match_operand 1 "" "")))]
2161   ""
2162   "jr %0;"
2163   [(set_attr "type" "uncond_branch")])
2165 (define_insn "*tablejump_hi_internal"
2166   [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
2167    (use (label_ref (match_operand 1 "" "")))]
2168   "optimize_size && TARGET_SMALL16"
2169   "jr %0;"
2170   [(set_attr "type" "uncond_branch")])
2173 (define_expand "call"
2174   ;; operands[1] is stack_size_rtx
2175   ;; operands[2] is next_arg_register
2176   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2177                     (match_operand 1 "" ""))
2178              (clobber (reg:SI GPR_LR))])]
2179   ""
2181   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2183   if (!call_operand (operands[1], VOIDmode))
2184     operands[0]
2185       = change_address (operands[0], VOIDmode,
2186                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2187   if (epiphany_uninterruptible_p (current_function_decl)
2188       != target_uninterruptible)
2189     {
2190       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2191       emit_call_insn
2192         (gen_rtx_PARALLEL
2193           (VOIDmode,
2194            gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2195                          gen_rtx_CLOBBER (VOIDmode,
2196                                           gen_rtx_REG (SImode, GPR_LR)))));
2197       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2198       DONE;
2199     }
2202 (define_insn "*call_i"
2203   [(match_parallel 2 "float_operation"
2204      [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
2205             (match_operand 1 "" ""))
2206       (clobber (reg:SI GPR_LR))])]
2207   ""
2208   "%f0"
2209   [(set_attr "type" "call")])
2211 (define_expand "sibcall"
2212   ;; operands[1] is stack_size_rtx
2213   ;; operands[2] is next_arg_register
2214   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2215                     (match_operand 1 "" ""))
2216              (return)])]
2217   ""
2219   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2221   if (!call_operand (operands[1], VOIDmode))
2222     operands[0]
2223       = change_address (operands[0], VOIDmode,
2224                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2225   if (epiphany_uninterruptible_p (current_function_decl)
2226       != target_uninterruptible)
2227     {
2228       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2229       emit_call_insn
2230         (gen_rtx_PARALLEL
2231           (VOIDmode,
2232            gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2233                          ret_rtx)));
2234       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2235       DONE;
2236     }
2239 (define_insn "*sibcall_i"
2240   [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
2241          (match_operand 1 "" ""))
2242    (return)]
2243   ""
2244   "@
2245    b %0
2246    jr %0"
2247   [(set_attr "type" "call")])
2249 (define_expand "call_value"
2250   ;; operand 2 is stack_size_rtx
2251   ;; operand 3 is next_arg_register
2252   [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2253                    (call (match_operand:SI 1 "call_operand" "")
2254                          (match_operand 2 "" "")))
2255              (clobber (reg:SI GPR_LR))])]
2256   ""
2258   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2260   if (!call_operand (operands[1], VOIDmode))
2261     operands[1]
2262       = change_address (operands[1], VOIDmode,
2263                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2264   if (epiphany_uninterruptible_p (current_function_decl)
2265       != target_uninterruptible)
2266     {
2267       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2268       emit_call_insn
2269         (gen_rtx_PARALLEL
2270           (VOIDmode,
2271            gen_rtvec (2, gen_rtx_SET
2272                            (operands[0],
2273                             gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2274                          gen_rtx_CLOBBER (VOIDmode,
2275                                           gen_rtx_REG (SImode, GPR_LR)))));
2276       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2277       DONE;
2278     }
2281 (define_insn "*call_value_i"
2282   [(match_parallel 3 "float_operation"
2283      [(set (match_operand 0 "gpr_operand" "=r,r")
2284            (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2285                  (match_operand 2 "" "")))
2286       (clobber (reg:SI GPR_LR))])]
2287   ""
2288   "%f1"
2289   [(set_attr "type" "call")
2290    (set_attr "length" "4")])
2292 (define_expand "sibcall_value"
2293   ;; operand 2 is stack_size_rtx
2294   ;; operand 3 is next_arg_register
2295   [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2296                    (call (match_operand:SI 1 "call_operand" "")
2297                          (match_operand 2 "" "")))
2298              (return)])]
2299   ""
2301   bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2303   if (!call_operand (operands[1], VOIDmode))
2304     operands[1]
2305       = change_address (operands[1], VOIDmode,
2306                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2307   if (epiphany_uninterruptible_p (current_function_decl)
2308       != target_uninterruptible)
2309     {
2310       emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2311       emit_call_insn
2312         (gen_rtx_PARALLEL
2313           (VOIDmode,
2314            gen_rtvec (2, gen_rtx_SET
2315                            (operands[0],
2316                             gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2317                          ret_rtx)));
2318       emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2319       DONE;
2320     }
2323 (define_insn "*sibcall_value_i"
2324   [(set (match_operand 0 "gpr_operand" "=r,r")
2325         (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2326               (match_operand 2 "" "")))
2327    (return)]
2328   ""
2329   "@
2330    b %1
2331    jr %1"
2332   [(set_attr "type" "call")
2333    (set_attr "length" "4")])
2335 (define_expand "prologue"
2336   [(pc)]
2337   ""
2339   epiphany_expand_prologue ();
2340   DONE;
2343 (define_expand "epilogue"
2344   [(pc)]
2345   ""
2347   epiphany_expand_epilogue (0);
2348   DONE;
2351 (define_expand "sibcall_epilogue"
2352   [(pc)]
2353   ""
2355   epiphany_expand_epilogue (1);
2356   DONE;
2359 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2360 ; in the prologue / epilogue expanders how many times lr is set.
2361 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2362 ; any explicit use of lr will cause it to be saved; hence we cannot
2363 ; represent the blink use in return / sibcall instructions themselves, and
2364 ; instead have to show it in EPILOGUE_USES.
2365 (define_insn "return_i"
2366   [(return)]
2367   "reload_completed"
2368   "rts"
2369   [(set_attr "type" "uncond_branch")])
2371 (define_insn "return_internal_interrupt"
2372   [(return)
2373    (unspec_volatile [(const_int 0)] 1)]
2374   ""
2375   "rti"
2376   [(set_attr "type" "uncond_branch")])
2378 (define_insn "stack_adjust_add"
2379   [(set (reg:SI GPR_SP)
2380         (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2381    (clobber (reg:CC CC_REGNUM))
2382    (clobber (reg:SI STATUS_REGNUM))
2383    (clobber (match_operand:BLK 1 "memclob_operand" "=X"))]
2384   "reload_completed"
2385   "add sp,sp,%0")
2387 (define_insn "stack_adjust_mov"
2388   [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2389    (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2390   "reload_completed"
2391   "mov sp,fp"
2392   [(set_attr "type" "move")])
2394 (define_insn "stack_adjust_str"
2395   [(set (match_operand 0 "stacktop_operand" "=m")
2396         (match_operand 1 "any_gpr_operand" "r"))
2397    (set (reg:SI GPR_SP)
2398         (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2399    (clobber (match_operand:BLK 3 "memclob_operand" "=X"))]
2400   "reload_completed"
2402   return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2403           ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2405   [(set_attr "type" "store")])
2407 (define_insn "stack_adjust_ldr"
2408   [(set (match_operand:SI 0 "gpr_operand" "=r")
2409         (match_operand:SI 1 "stacktop_operand" "m"))
2410    (set (reg:SI GPR_SP)
2411         (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2412    (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2413   "reload_completed"
2414   "ldr %0,%1,%C2"
2415   [(set_attr "type" "load")])
2417 ;; Define some fake vector operations so that the vectorizer is happy to use
2418 ;; 64 bit loads/stores.
2419 (define_expand "vec_unpacks_lo_v4hi"
2420   [(match_operand:V2SI 0 "gpr_operand")
2421    (match_operand:V4HI 1 "gpr_operand")]
2422   ""
2424   rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2425   rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2426   rtx outh
2427     = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2429   if (reg_overlap_mentioned_p (outl, in))
2430     in = copy_to_mode_reg (SImode, in);
2431   emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2432   emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2433   emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2434   DONE;
2437 (define_expand "vec_unpacks_hi_v4hi"
2438   [(match_operand:V2SI 0 "gpr_operand")
2439    (match_operand:V4HI 1 "gpr_operand")]
2440   ""
2442   rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2443   rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2444   rtx outh
2445     = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2447   if (reg_overlap_mentioned_p (outl, in))
2448     in = copy_to_mode_reg (SImode, in);
2449   emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2450   emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2451   emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2452   DONE;
2455 (define_code_iterator addsub [plus minus])
2457 (define_code_iterator alu_binop
2458   [plus minus and ior xor])
2460 (define_code_attr insn_opname
2461   [(plus "add") (minus "sub") (mult "mul") (div "div")
2462    (and "and") (ior "ior") (xor "xor")])
2464 ; The addsi3 / subsi3 do checks that we don't want when splitting V2SImode
2465 ; operations into two SImode operations.
2466 (define_code_attr si_pattern_suffix
2467   [(plus "_i") (minus "_i") (and "") (ior "") (xor "")])
2469 ; You might think that this would work better as a define_expand, but
2470 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2471 ; We need to keep inputs and outputs as register pairs if we want to
2472 ; get sensible register allocation for double-word load and store operations.
2473 (define_insn_and_split "<insn_opname>v2si3"
2474   [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2475         (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2476                         (match_operand:V2SI 2 "gpr_operand" "r")))
2477    (clobber (reg:CC CC_REGNUM))]
2478   ""
2479   "#"
2480   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2481   [(const_int 0)]
2483   rtx o0l, o0h, o1l, o1h, o2l, o2h;
2485   o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2486   o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2487   o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2488   o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2489   o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2490   o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2491   if (reg_overlap_mentioned_p (o0l, o1h))
2492     o1h = copy_to_mode_reg (SImode, o1h);
2493   if (reg_overlap_mentioned_p (o0l, o2h))
2494     o2h = copy_to_mode_reg (SImode, o2h);
2495   emit_insn (gen_<insn_opname>si3<si_pattern_suffix> (o0l, o1l, o2l));
2496   emit_insn (gen_<insn_opname>si3<si_pattern_suffix> (o0h, o1h, o2h));
2497   DONE;
2499   [(set_attr "length" "8")])
2501 (define_expand "<insn_opname>v2sf3"
2502   [(parallel
2503      [(set (match_operand:V2SF 0 "gpr_operand" "")
2504            (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2505                         (match_operand:V2SF 2 "gpr_operand" "")))
2506       (clobber (reg:CC_FP CCFP_REGNUM))])])
2508 (define_insn_and_split "<insn_opname>v2sf3_i"
2509   [(match_parallel 3 "float_operation"
2510      [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2511            (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2512                         (match_operand:V2SF 2 "gpr_operand" "r")))
2513       (clobber (reg:CC_FP CCFP_REGNUM))])]
2514   ""
2515   "#"
2516   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2517   [(parallel
2518      [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2519       (clobber (reg:CC_FP CCFP_REGNUM))
2520       (match_dup 10)
2521       (match_dup 11)])
2522    (parallel
2523      [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2524       (clobber (reg:CC_FP CCFP_REGNUM))
2525       (match_dup 10)
2526       (match_dup 11)])]
2528   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2529   operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2530   operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2531   operands[7]
2532     = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2533   operands[8]
2534     = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2535   operands[9]
2536     = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2537   if (!reload_completed)
2538     {
2539       if (reg_overlap_mentioned_p (operands[4], operands[8]))
2540         operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2541       if (reg_overlap_mentioned_p (operands[4], operands[9]))
2542         operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2543       emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2544       emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2545       DONE;
2546     }
2547   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2548   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2549   operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2550   operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2552   [(set_attr "length" "8")
2553    (set_attr "type" "v2fp")])
2555 (define_expand "ashlv2si3"
2556   [(parallel
2557      [(set (match_operand:V2SI 0 "gpr_operand" "")
2558            (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "")
2559                         (match_operand:SI 2 "general_operand")))
2560       (use (match_dup 3))
2561       (clobber (reg:CC_FP CCFP_REGNUM))])]
2562   ""
2564   if (const_int_operand (operands[2], VOIDmode))
2565     operands[3]
2566       = copy_to_mode_reg (SImode, GEN_INT (1 << INTVAL (operands[2])));
2567   else
2568     {
2569       int o, i;
2570       rtx xop[2], last_out = pc_rtx;
2572       for (o = 0; o <= UNITS_PER_WORD; o += UNITS_PER_WORD)
2573         {
2574           for (i = 0; i < 2; i++)
2575             {
2576               xop[i]
2577                 = (i == 2 ? operands[2]
2578                    : simplify_gen_subreg (SImode, operands[i], V2SImode, o));
2579               gcc_assert (!reg_overlap_mentioned_p (last_out, xop[i])
2580                           /* ??? reg_overlap_mentioned_p doesn't understand
2581                              about multi-word SUBREGs.  */
2582                           || (GET_CODE (last_out) == SUBREG
2583                               && GET_CODE (xop[i]) == SUBREG
2584                               && SUBREG_REG (last_out) == SUBREG_REG (xop[i])
2585                               && ((SUBREG_BYTE (last_out) & -UNITS_PER_WORD)
2586                                   != (SUBREG_BYTE (xop[i]) & -UNITS_PER_WORD))));
2587             }
2588           emit_insn (gen_ashlsi3 (xop[0], xop[1], operands[2]));
2589           last_out = xop[0];
2590         }
2591       DONE;
2592     }
2595 (define_insn_and_split "*ashlv2si3_i"
2596   [(match_parallel 3 "float_operation"
2597      [(set (match_operand:V2SI 0 "gpr_operand" "=&r,*1*2")
2598            (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "r,r")
2599                         (match_operand 2 "const_int_operand" "n,n")))
2600       (use (match_operand:SI 4 "gpr_operand" "r,r"))
2601       (clobber (reg:CC_FP CCFP_REGNUM))])]
2602   ""
2603   "#"
2604   "reload_completed"
2605   [(parallel
2606      [(set (match_dup 5) (mult:SI (match_dup 6) (match_dup 4)))
2607            (clobber (reg:CC_FP CCFP_REGNUM))
2608            (match_dup 9)
2609            (match_dup 10)])
2610    (parallel
2611      [(set (match_dup 7) (mult:SI (match_dup 8) (match_dup 4)))
2612            (clobber (reg:CC_FP CCFP_REGNUM))
2613            (match_dup 9)
2614            (match_dup 10)])]
2616   operands[5] = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2617   operands[6] = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2618   operands[7] = simplify_gen_subreg (SImode, operands[0],
2619                                      V2SImode, UNITS_PER_WORD);
2620   operands[8] = simplify_gen_subreg (SImode, operands[1],
2621                                      V2SImode, UNITS_PER_WORD);
2622   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[8]));
2623   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[4]));
2624   operands[9] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2625   operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2626   rtx insn
2627     = (gen_rtx_PARALLEL
2628         (VOIDmode,
2629          gen_rtvec
2630           (4,
2631            gen_rtx_SET (operands[5],
2632                         gen_rtx_MULT (SImode, operands[6], operands[4])),
2633            gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
2634            operands[9], operands[10])));
2635   insn = emit_insn (insn);
2636   add_reg_note (insn, REG_EQUAL,
2637                 gen_rtx_ASHIFT (SImode, operands[6], operands[2]));
2638   insn
2639     = (gen_rtx_PARALLEL
2640         (VOIDmode,
2641          gen_rtvec
2642           (4,
2643            gen_rtx_SET (operands[7],
2644                         gen_rtx_MULT (SImode, operands[8], operands[4])),
2645            gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
2646            operands[9], operands[10])));
2647   insn = emit_insn (insn);
2648   add_reg_note (insn, REG_EQUAL,
2649                 gen_rtx_ASHIFT (SImode, operands[7], operands[2]));
2650   DONE;
2652   [(set_attr "length" "8")
2653    (set_attr "type" "fp_int")])
2655 (define_expand "mul<mode>3"
2656   [(parallel
2657      [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2658            (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2659                           (match_operand:DWV2MODE 2 "gpr_operand" "")))
2660       (clobber (reg:CC_FP CCFP_REGNUM))])])
2662 (define_insn_and_split "mul<mode>3_i"
2663   [(match_parallel 3 "float_operation"
2664      [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2665            (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2666                           (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2667       (clobber (reg:CC_FP CCFP_REGNUM))])]
2668   ""
2669   "#"
2670   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2671   [(parallel
2672      [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2673       (clobber (reg:CC_FP CCFP_REGNUM))
2674       (match_dup 10)
2675       (match_dup 11)])
2676    (parallel
2677      [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2678       (clobber (reg:CC_FP CCFP_REGNUM))
2679       (match_dup 10)
2680       (match_dup 11)])]
2682   operands[4]
2683     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2684   operands[5]
2685     = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2686   operands[6]
2687     = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2688   operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2689                                      <MODE>mode, UNITS_PER_WORD);
2690   operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2691                                      <MODE>mode, UNITS_PER_WORD);
2692   operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2693                                      <MODE>mode, UNITS_PER_WORD);
2694   if (!reload_completed)
2695     {
2696       if (reg_overlap_mentioned_p (operands[4], operands[8]))
2697         operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2698       if (reg_overlap_mentioned_p (operands[4], operands[9]))
2699         operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2700       emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2701       emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2702       DONE;
2703     }
2704   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2705   gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2706   operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2707   operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2709   [(set_attr "length" "8")
2710    (set_attr "type" "<vmode_fp_type>")])
2712 (define_insn_and_split "*fmadd<mode>_combine"
2713   [(match_parallel 4 "float_operation"
2714      [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2715            (plus:DWV2MODE (mult:<MODE>
2716                                 (match_operand:<MODE> 1 "gpr_operand" "r")
2717                                 (match_operand:<MODE> 2 "gpr_operand" "r"))
2718                           (match_operand:<MODE> 3 "gpr_operand" "0")))
2719       (clobber (reg:CC_FP CCFP_REGNUM))])]
2720   "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2721   "#"
2722   "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2723   [(parallel
2724      [(set (match_dup 5)
2725            (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2726                               (match_dup 8)))
2727       (clobber (reg:CC_FP CCFP_REGNUM))
2728       (match_dup 13)
2729       (match_dup 14)])
2730    (parallel
2731      [(set (match_dup 9)
2732            (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2733                               (match_dup 12)))
2734       (clobber (reg:CC_FP CCFP_REGNUM))
2735       (match_dup 13)
2736       (match_dup 14)])]
2738   operands[5]
2739     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2740   operands[6]
2741     = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2742   operands[7]
2743     = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2744   operands[8]
2745     = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2746   operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2747                                      <MODE>mode, UNITS_PER_WORD);
2748   operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2749                                       <MODE>mode, UNITS_PER_WORD);
2750   operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2751                                       <MODE>mode, UNITS_PER_WORD);
2752   operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2753                                       <MODE>mode, UNITS_PER_WORD);
2754   if (!reload_completed)
2755     {
2756       if (reg_overlap_mentioned_p (operands[5], operands[10]))
2757         operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2758       if (reg_overlap_mentioned_p (operands[5], operands[11]))
2759         operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2760       if (reg_overlap_mentioned_p (operands[5], operands[12]))
2761         operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2762       emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2763                                        operands[8]));
2764       emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2765                                        operands[12]));
2766       DONE;
2767     }
2768   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2769   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2770   gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2771   operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2772   operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2774   [(set_attr "length" "8")
2775    (set_attr "type" "<vmode_fp_type>")])
2777 (define_expand "vec_set<mode>"
2778   [(match_operand:DWV2MODE 0 "register_operand")
2779    (match_operand:<vmode_PART> 1 "register_operand")
2780    (match_operand 2 "const_int_operand" "")]
2781   ""
2783   operands[0]
2784     = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2785                            UNITS_PER_WORD * INTVAL (operands[2]));
2786   emit_move_insn (operands[0], operands[1]);
2787   DONE;
2790 (define_expand "movmisalign<mode>"
2791  [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "")
2792        (match_operand:DWV2MODE 1 "general_operand" ""))]
2793  ""
2795   rtx op00, op01, op10, op11;
2797   op00 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2798   op01 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2799                               UNITS_PER_WORD);
2800   op10 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2801   op11 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode,
2802                               UNITS_PER_WORD);
2803   emit_move_insn (op00, op10);
2804   emit_move_insn (op01, op11);
2805   DONE;
2808 (define_insn "nop"
2809   [(const_int 0)]
2810   ""
2811   "nop"
2812   [(set_attr "type" "flow")])