1 ;; Machine description of the Adaptiva epiphany cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007, 2009, 2010,
3 ;; 2011, 2012 Free Software Foundation, Inc.
4 ;; Contributed by Embecosm on behalf of Adapteva, Inc.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
33 (ARG_POINTER_REGNUM 64)
34 (FRAME_POINTER_REGNUM 65)
35 (CC_REGNUM 66) ;; 66 or 17
36 (CCFP_REGNUM 67) ;; 67 or 18
43 (FP_NEAREST_REGNUM 74)
44 (FP_TRUNCATE_REGNUM 75)
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)
57 ;; Insn type. Used to default other attribute values.
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")
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" ""))]
117 if (<MODE>mode == V4QImode || <MODE>mode == V2HImode)
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]));
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))
129 rtx reg = operands[0];
132 reg = gen_reg_rtx (SImode);
133 emit_insn (gen_move_frame (reg, operands[1]));
135 if (operands[0] == reg)
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"))]
144 "gpr_operand (operands[0], QImode)
145 || gpr_operand (operands[1], QImode)"
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)"
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
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"
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"))))]
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")))]
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)
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 ();
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")])
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))])
252 [(set (match_operand:SI 0 "gpr_operand")
253 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
255 [(set (match_dup 0) (match_dup 1))]
257 emit_insn (gen_reload_insi_ra (operands[0], operands[1]));
261 (define_expand "reload_insi_ra"
262 [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))]
266 = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx);
268 addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
269 operands[1] = gen_frame_mem (SImode, addr);
272 ;; If the frame pointer elimination offset is zero, we'll use this pattern.
273 ;; Note that the splitter can accept any gpr in operands[1]; this is
274 ;; necessary, (e.g. for compile/20021015-1.c -O0,)
275 ;; because when register elimination cannot be done with the constant
276 ;; as an immediate operand of the add instruction, reload will resort to
277 ;; loading the constant into a reload register, using gen_add2_insn to add
278 ;; the stack pointer, and then use the reload register as new source in
279 ;; the move_frame pattern.
280 (define_insn_and_split "*move_frame_1"
281 [(set (match_operand:SI 0 "gpr_operand" "=r")
282 (match_operand:SI 1 "gpr_operand" "r"))
283 (clobber (reg:CC CC_REGNUM))]
284 "(reload_in_progress || reload_completed)
285 && (operands[1] == stack_pointer_rtx
286 || operands[1] == hard_frame_pointer_rtx)"
288 "reload_in_progress || reload_completed"
289 [(set (match_dup 0) (match_dup 1))])
291 (define_expand "mov<mode>"
292 [(set (match_operand:DWMODE 0 "general_operand" "")
293 (match_operand:DWMODE 1 "general_operand" ""))]
297 if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT
298 || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
300 if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)
302 rtx o0l, o0h, o1l, o1h;
304 o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
305 o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode,
307 o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
308 o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode,
310 if (reg_overlap_mentioned_p (o0l, o1h))
312 emit_move_insn (o0h, o1h);
313 emit_move_insn (o0l, o1l);
317 emit_move_insn (o0l, o1l);
318 emit_move_insn (o0h, o1h);
322 /* lower_subreg has a tendency to muck up vectorized code.
323 To protect the wide memory accesses, we must use same-size
325 if (epiphany_vect_align != 4 /* == 8 */
326 && !reload_in_progress
327 && (GET_CODE (operands[0]) == MEM || GET_CODE (operands[1]) == MEM)
328 && !misaligned_operand (operands[1], <MODE>mode)
329 && (GET_CODE (operands[0]) != SUBREG
330 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
331 != GET_MODE_SIZE (<MODE>mode)
332 && GET_CODE (operands[1]) != SUBREG)))
335 = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0);
337 = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0);
338 emit_insn (gen_movdi (operands[0], operands[1]));
342 /* Everything except mem = const or mem = mem can be done easily. */
344 if (GET_CODE (operands[0]) == MEM)
345 operands[1] = force_reg (<MODE>mode, operands[1]);
348 (define_insn_and_split "*mov<mode>_insn"
349 [(set (match_operand:DWMODE 0 "move_dest_operand" "=r, r,r,m")
350 (match_operand:DWMODE 1 "move_double_src_operand" "r,CalE,m,r"))]
351 "(gpr_operand (operands[0], <MODE>mode)
352 || gpr_operand (operands[1], <MODE>mode))"
359 && (((!MEM_P (operands[0]) || misaligned_operand (operands[0], <MODE>mode))
360 && (!MEM_P (operands[1])
361 || misaligned_operand (operands[1], <MODE>mode)))
362 || epiphany_vect_align == 4)"
363 [(set (match_dup 2) (match_dup 3))
364 (set (match_dup 4) (match_dup 5))]
366 int word0 = 0, word1 = UNITS_PER_WORD;
368 if (post_modify_operand (operands[0], <MODE>mode)
369 || post_modify_operand (operands[1], <MODE>mode))
370 word0 = UNITS_PER_WORD, word1 = 0;
372 operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
373 operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
374 operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
375 operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
376 if (post_modify_operand (operands[0], <MODE>mode))
378 = change_address (operands[2], VOIDmode,
379 plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0),
381 if (post_modify_operand (operands[1], <MODE>mode))
383 = change_address (operands[3], VOIDmode,
384 plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0),
387 [(set_attr "type" "move,move,load,store")
388 (set_attr "length" "8,16,4,4")])
391 (define_insn_and_split "*movsf_insn"
392 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
393 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
394 "gpr_operand (operands[0], SFmode)
395 || gpr_operand (operands[1], SFmode)"
398 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
401 "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
402 [(set (match_dup 2) (match_dup 3))]
403 "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
404 operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
405 [(set_attr "type" "move,move,load,store")
406 (set_attr "length" "4,8,4,4")])
408 (define_expand "addsi3"
409 [(set (match_operand:SI 0 "add_reg_operand" "")
410 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
411 (match_operand:SI 2 "add_operand" "")))]
415 if (reload_in_progress || reload_completed)
416 emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
417 else if (TARGET_FP_IARITH && add_reg_operand (operands[2], SImode))
418 emit_insn (gen_iadd (operands[0], operands[1], operands[2]));
420 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
424 (define_insn "addsi3_i"
425 [(set (match_operand:SI 0 "add_reg_operand" "=r")
426 (plus:SI (match_operand:SI 1 "add_reg_operand" "%r")
427 (match_operand:SI 2 "add_operand" "rL")))
428 (clobber (reg:CC CC_REGNUM))]
431 [(set_attr "type" "misc")])
433 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
434 ; can identify the unresolved flags clobber problem, and also to
435 ; avoid unwanted matches.
437 ; At -O0 / -O1 we don't peephole all instances away. We could get better
438 ; debug unwinding through the emitted code if we added a splitter.
439 (define_insn "addsi3_r"
440 [(set (match_operand:SI 0 "gpr_operand" "=r")
441 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
442 (match_operand:SI 2 "nonmemory_operand" "rCar")))
443 (clobber (reg:CC UNKNOWN_REGNUM))]
444 "reload_in_progress || reload_completed"
447 ^ (true_regnum (operands[0]) & 1)
448 ^ (true_regnum (operands[1]) & 2)
449 ^ (true_regnum (operands[2]) & 4));
450 asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
451 asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
452 output_asm_insn ("add %0,%1,%2", operands);
453 asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
454 asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
457 [(set_attr "length" "20")
458 (set_attr "type" "misc")])
460 ;; reload uses gen_addsi2 because it doesn't understand the need for
463 [(set (match_operand:SI 0 "gpr_operand" "")
464 (match_operand:SI 1 "const_int_operand" ""))
465 (parallel [(set (match_dup 0)
466 (plus:SI (match_dup 0)
467 (match_operand:SI 2 "gpr_operand")))
468 (clobber (reg:CC UNKNOWN_REGNUM))])]
469 "satisfies_constraint_L (operands[1])
470 || ((operands[2] == stack_pointer_rtx
471 || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
472 && !peep2_regno_dead_p (2, CC_REGNUM)
473 && satisfies_constraint_Car (operands[1]))"
474 [(parallel [(set (match_dup 0)
475 (plus:SI (match_dup 2) (match_dup 1)))
476 (clobber (reg:CC UNKNOWN_REGNUM))])]
478 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
479 ;; "peep2_rescan = true;"
483 [(match_parallel 5 ""
484 [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
485 (parallel [(set (match_operand:SI 0 "gpr_operand" "")
486 (plus:SI (match_operand:SI 1 "gpr_operand" "")
487 (match_operand:SI 2 "nonmemory_operand" "")))
488 (clobber (reg:CC UNKNOWN_REGNUM))])]
489 "REGNO (operands[3]) == CC_REGNUM
490 && (gpr_operand (operands[2], SImode)
491 || satisfies_constraint_L (operands[2]))
492 && !reg_overlap_mentioned_p (operands[0], operands[5])
493 && !reg_set_p (operands[1], operands[5])
494 && !reg_set_p (operands[2], operands[5])"
495 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
496 (plus:SI (match_operand:SI 1 "gpr_operand" "")
497 (match_operand:SI 2 "nonmemory_operand" "")))
498 (clobber (reg:CC CC_REGNUM))])
503 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
504 (plus:SI (match_operand:SI 1 "gpr_operand" "")
505 (match_operand:SI 2 "nonmemory_operand" "")))
506 (clobber (reg:CC UNKNOWN_REGNUM))])]
507 "peep2_regno_dead_p (1, CC_REGNUM)
508 && (gpr_operand (operands[2], SImode)
509 || satisfies_constraint_L (operands[2]))"
510 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
511 (plus:SI (match_operand:SI 1 "gpr_operand" "")
512 (match_operand:SI 2 "nonmemory_operand" "")))
513 (clobber (reg:CC CC_REGNUM))])]
517 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
518 (plus:SI (reg:SI GPR_SP)
519 (match_operand:SI 1 "nonmemory_operand" "")))
520 (clobber (reg:CC UNKNOWN_REGNUM))])]
521 "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
522 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
523 [(set (match_dup 0) (reg:SI GPR_SP))
524 (set (mem:WMODE (post_modify (match_dup 0)
525 (plus:SI (match_dup 0) (match_dup 1))))
532 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
533 (plus:SI (reg:SI GPR_FP)
534 (match_operand:SI 1 "nonmemory_operand" "")))
535 (clobber (reg:CC UNKNOWN_REGNUM))])
536 (match_scratch:WMODE 2 "r")]
537 "frame_pointer_needed
538 && ((REG_P (operands[1])
539 && !reg_overlap_mentioned_p (operands[0], operands[1]))
540 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
541 [(set (match_dup 0) (reg:SI GPR_FP))
543 (mem:WMODE (post_modify (match_dup 0)
544 (plus:SI (match_dup 0) (match_dup 1)))))]
547 (define_expand "subsi3"
548 [(set (match_operand:SI 0 "gpr_operand" "")
549 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
550 (match_operand:SI 2 "arith_operand" "")))]
554 gcc_assert (!reload_in_progress && !reload_completed);
556 if (TARGET_FP_IARITH)
557 emit_insn (gen_isub (operands[0], operands[1], operands[2]));
559 emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2]));
563 (define_insn "subsi3_i"
564 [(set (match_operand:SI 0 "gpr_operand" "=r")
565 (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
566 (match_operand:SI 2 "arith_operand" "rL")))
567 (clobber (reg:CC CC_REGNUM))]
570 [(set_attr "type" "misc")])
572 ; After mode-switching, floating point operations, fp_sfuncs and calls
573 ; must exhibit the use of the control register, lest the setting of the
574 ; control register could be deleted or moved. OTOH a use of a hard register
575 ; greatly coundounds optimizers like the rtl loop optimizers or combine.
576 ; Therefore, we put an extra pass immediately after the mode switching pass
577 ; that inserts the USEs of the control registers, and sets a flag in struct
578 ; machine_function that float_operation can henceforth only match with that
582 (define_expand "addsf3"
584 [(set (match_operand:SF 0 "gpr_operand" "")
585 (plus:SF (match_operand:SF 1 "gpr_operand" "")
586 (match_operand:SF 2 "gpr_operand" "")))
587 (clobber (reg:CC_FP CCFP_REGNUM))])])
589 (define_insn "*addsf3_i"
590 [(match_parallel 3 "float_operation"
591 [(set (match_operand:SF 0 "gpr_operand" "=r")
592 (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
593 (match_operand:SF 2 "gpr_operand" "r")))
594 (clobber (reg:CC_FP CCFP_REGNUM))])]
597 [(set_attr "type" "fp")])
600 (define_expand "subsf3"
602 [(set (match_operand:SF 0 "gpr_operand" "")
603 (minus:SF (match_operand:SF 1 "gpr_operand" "")
604 (match_operand:SF 2 "gpr_operand" "")))
605 (clobber (reg:CC_FP CCFP_REGNUM))])])
607 (define_insn "*subsf3_i"
608 [(match_parallel 3 "float_operation"
609 [(set (match_operand:SF 0 "gpr_operand" "=r")
610 (minus:SF (match_operand:SF 1 "gpr_operand" "r")
611 (match_operand:SF 2 "gpr_operand" "r")))
612 (clobber (reg:CC_FP CCFP_REGNUM))])]
615 [(set_attr "type" "fp")])
617 (define_expand "subsf3_f"
619 [(set (reg:CC_FP CCFP_REGNUM)
620 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
621 (match_operand:SF 2 "gpr_operand" "r")))
622 (set (match_operand:SF 0 "gpr_operand" "=r")
623 (minus:SF (match_dup 1) (match_dup 2)))])]
624 "!TARGET_SOFT_CMPSF")
626 (define_insn "*subsf3_f_i"
627 [(match_parallel 3 "float_operation"
628 [(set (reg:CC_FP CCFP_REGNUM)
629 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
630 (match_operand:SF 2 "gpr_operand" "r")))
631 (set (match_operand:SF 0 "gpr_operand" "=r")
632 (minus:SF (match_dup 1) (match_dup 2)))])]
635 [(set_attr "type" "fp")])
637 ; There is an fabs instruction, but it has longer latency.
638 (define_expand "abssf2"
639 [(set (match_operand:SF 0 "gpr_operand" "")
640 (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
644 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
646 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
648 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
649 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
654 (define_expand "mulsf3"
656 [(set (match_operand:SF 0 "gpr_operand" "")
657 (mult:SF (match_operand:SF 1 "gpr_operand" "")
658 (match_operand:SF 2 "gpr_operand" "")))
659 (clobber (reg:CC_FP CCFP_REGNUM))])])
661 (define_insn "*mulsf3_i"
662 [(match_parallel 3 "float_operation"
663 [(set (match_operand:SF 0 "gpr_operand" "=r")
664 (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
665 (match_operand:SF 2 "gpr_operand" "r")))
666 (clobber (reg:CC_FP CCFP_REGNUM))])]
669 [(set_attr "type" "fp")])
672 (define_expand "divsf3"
673 [(set (match_operand:SF 0 "gpr_operand" "")
674 (div:SF (match_operand:SF 1 "gpr_operand" "")
675 (match_operand:SF 2 "gpr_operand" "")))]
676 "flag_reciprocal_math"
678 rtx one = CONST1_RTX (SFmode);
679 rtx dst = operands[0];
681 if (rtx_equal_p (dst, operands[1]))
683 emit_move_insn (dst, one);
686 else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
687 dst = gen_reg_rtx (SFmode);
688 emit_insn (gen_recipsf2 (dst, one, operands[2],
689 sfunc_symbol (\"__fast_recipsf2\")));
690 emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
694 ;; Before reload, keep the hard reg usage to clobbers so that the loop
695 ;; optimizers can more easily move this insn.
696 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
697 ;; but sched1 can still cause trouble then, and there is no guarantee of
698 ;; better register allocations.
699 ;; Neither is there when using the opposite strategy - putting explicit
700 ;; hard register references into pre-reload rtl.
701 (define_expand "recipsf2"
703 [(set (match_operand:SF 0 "gpr_operand" "")
704 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
705 (match_operand:SF 2 "move_src_operand" "")))
706 (use (match_operand:SI 3 "move_src_operand" ""))
709 (clobber (reg:SF GPR_IP))
710 (clobber (reg:DI GPR_16))
711 (clobber (reg:DI GPR_18))
712 (clobber (reg:SI GPR_20))
713 (clobber (reg:SI GPR_LR))
714 (clobber (reg:CC CC_REGNUM))
715 (clobber (reg:CC_FP CCFP_REGNUM))])])
717 (define_insn_and_split "*recipsf2_1"
718 [(match_parallel 4 "float_operation"
719 [(set (match_operand:SF 0 "gpr_operand" "=r,r")
720 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
721 (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
722 (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
725 (clobber (reg:SF GPR_IP))
726 (clobber (reg:DI GPR_16))
727 (clobber (reg:DI GPR_18))
728 (clobber (reg:SI GPR_20))
729 (clobber (reg:SI GPR_LR))
730 (clobber (reg:CC CC_REGNUM))
731 (clobber (reg:CC_FP CCFP_REGNUM))])]
732 "flag_reciprocal_math"
734 "&& reload_completed"
735 [(set (reg:SI 1) (match_dup 3))
736 (set (reg:SF 0) (match_dup 2))
739 (div:SF (match_dup 1)
742 (clobber (reg:SI GPR_IP))
743 (clobber (reg:DI GPR_16))
744 (clobber (reg:DI GPR_18))
745 (clobber (reg:SI GPR_20))
746 (clobber (reg:SI GPR_LR))
747 (clobber (reg:CC CC_REGNUM))
748 (clobber (reg:CC_FP CCFP_REGNUM))
751 (set (match_dup 0) (reg:SF 0))]
752 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
753 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
754 [(set_attr "type" "fp_sfunc")
755 (set_attr "length" "16,24")])
757 (define_insn "*recipsf2_2"
758 [(match_parallel 1 "float_operation"
760 (div:SF (match_operand:SF 0 "const_float_1_operand" "")
763 (clobber (reg:SI GPR_IP))
764 (clobber (reg:DI GPR_16))
765 (clobber (reg:DI GPR_18))
766 (clobber (reg:SI GPR_20))
767 (clobber (reg:SI GPR_LR))
768 (clobber (reg:CC CC_REGNUM))
769 (clobber (reg:CC_FP CCFP_REGNUM))])]
770 "flag_reciprocal_math"
772 [(set_attr "type" "fp_sfunc")])
775 ;; Fused multiply-add
776 (define_expand "fmasf4"
778 [(set (match_operand:SF 0 "gpr_operand" "")
779 (fma:SF (match_operand:SF 1 "gpr_operand" "")
780 (match_operand:SF 2 "gpr_operand" "")
781 (match_operand:SF 3 "gpr_operand" "")))
782 (clobber (reg:CC_FP CCFP_REGNUM))])]
785 ; The multiply operands are commutative, but since they have the
786 ; same constraints, there is no point in telling reload about this.
787 (define_insn "*fmadd"
788 [(match_parallel 4 "float_operation"
789 [(set (match_operand:SF 0 "gpr_operand" "=r")
790 (fma:SF (match_operand:SF 1 "gpr_operand" "r")
791 (match_operand:SF 2 "gpr_operand" "r")
792 (match_operand:SF 3 "gpr_operand" "0")))
793 (clobber (reg:CC_FP CCFP_REGNUM))])]
796 [(set_attr "type" "fp")])
798 ; Once vetorization consistently works for this port, should check
799 ; if the fmadd / fmsub patterns still serve a purpose. With the
800 ; introduction of fma / fnma handling by the SSA optimizers,
801 ; at least scalars should be handled by these optimizers, would
802 ; have to see how well they do on vectors from auto-vectorization.
804 ; combiner pattern, also used by vector combiner pattern
805 (define_expand "maddsf"
807 [(set (match_operand:SF 0 "gpr_operand" "=r")
808 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
809 (match_operand:SF 2 "gpr_operand" "r"))
810 (match_operand:SF 3 "gpr_operand" "0")))
811 (clobber (reg:CC_FP CCFP_REGNUM))])]
814 (define_insn "*maddsf_combine"
815 [(match_parallel 4 "float_operation"
816 [(set (match_operand:SF 0 "gpr_operand" "=r")
817 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
818 (match_operand:SF 2 "gpr_operand" "r"))
819 (match_operand:SF 3 "gpr_operand" "0")))
820 (clobber (reg:CC_FP CCFP_REGNUM))])]
823 [(set_attr "type" "fp")])
825 ;; Fused multiply-sub
826 (define_expand "fnmasf4"
828 [(set (match_operand:SF 0 "gpr_operand" "")
829 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
830 (match_operand:SF 2 "gpr_operand" "")
831 (match_operand:SF 3 "gpr_operand" "")))
832 (clobber (reg:CC_FP CCFP_REGNUM))])]
835 (define_insn "*fmsub"
836 [(match_parallel 4 "float_operation"
837 [(set (match_operand:SF 0 "gpr_operand" "=r")
838 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" "r"))
839 (match_operand:SF 2 "gpr_operand" "r")
840 (match_operand:SF 3 "gpr_operand" "0")))
841 (clobber (reg:CC_FP CCFP_REGNUM))])]
844 [(set_attr "type" "fp")])
846 (define_insn "*fmsub_combine"
847 [(match_parallel 4 "float_operation"
848 [(set (match_operand:SF 0 "gpr_operand" "=r")
849 (minus:SF (match_operand:SF 3 "gpr_operand" "0")
850 (mult:SF (match_operand:SF 1 "gpr_operand" "r")
851 (match_operand:SF 2 "gpr_operand" "r"))))
852 (clobber (reg:CC_FP CCFP_REGNUM))])]
855 [(set_attr "type" "fp")])
857 ;; float / integer conversions
859 (define_expand "floatsisf2"
861 [(set (match_operand:SF 0 "gpr_operand" "")
862 (float:SF (match_operand:SI 1 "gpr_operand" "")))
863 (clobber (reg:CC_FP CCFP_REGNUM))])])
865 (define_insn "*floatsisf2_i"
866 [(match_parallel 2 "float_operation"
867 [(set (match_operand:SF 0 "gpr_operand" "=r")
868 (float:SF (match_operand:SI 1 "gpr_operand" "r")))
869 (clobber (reg:CC_FP CCFP_REGNUM))])]
872 [(set_attr "type" "fp")])
874 (define_expand "floatsisf2_cmp"
876 [(set (reg:CC_FP CCFP_REGNUM)
877 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
879 (set (match_operand:SF 0 "gpr_operand" "=r")
880 (float:SF (match_dup 1)))])]
882 "operands[2] = CONST0_RTX (SFmode);")
884 (define_insn "*floatsisf2_cmp_i"
885 [(match_parallel 3 "float_operation"
886 [(set (reg:CC_FP CCFP_REGNUM)
887 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
888 (match_operand:SF 2 "const0_operand" "")))
889 (set (match_operand:SF 0 "gpr_operand" "=r")
890 (float:SF (match_dup 1)))])]
893 [(set_attr "type" "fp")])
895 (define_expand "floatunssisf2"
896 [(set (match_operand:SF 0 "gpr_operand" "")
897 (float:SF (match_operand:SI 1 "gpr_operand" "")))]
898 "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
900 rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
901 rtx tmp = gen_reg_rtx (SImode);
902 rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
904 if (reg_overlap_mentioned_p (operands[0], operands[1]))
905 operands[1] = copy_to_mode_reg (SImode, operands[1]);
906 emit_insn (gen_floatsisf2 (operands[0], operands[1]));
907 emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
908 emit_insn (gen_sub_f (tmp, tmp, cst));
909 emit_insn (gen_movsfcc (operands[0], cmp,
910 simplify_gen_subreg (SFmode, tmp, SImode, 0),
915 (define_expand "fix_truncsfsi2"
917 [(set (match_operand:SI 0 "gpr_operand" "")
918 (fix:SI (match_operand:SF 1 "gpr_operand" "")))
919 (clobber (reg:CC_FP CCFP_REGNUM))])])
921 (define_insn "*fix_truncsfsi2_i"
922 [(match_parallel 2 "float_operation"
923 [(set (match_operand:SI 0 "gpr_operand" "=r")
924 (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
925 (clobber (reg:CC_FP CCFP_REGNUM))])]
928 [(set_attr "type" "fp")
929 (set (attr "fp_mode")
930 (cond [(match_test "TARGET_MAY_ROUND_FOR_TRUNC")
931 (const_string "round_unknown")]
932 (const_string "round_trunc")))])
934 (define_expand "fixuns_truncsfsi2"
935 [(set (match_operand:SI 0 "gpr_operand" "")
936 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
939 if (reg_overlap_mentioned_p (operands[0], operands[1]))
940 operands[1] = copy_to_mode_reg (SImode, operands[1]);
941 if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
944 /* By toggling what it to be bit31 before the shift, we get a chance to
945 use a short movt insn. */
946 rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
947 rtx tmp = gen_reg_rtx (SImode);
948 rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
950 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
952 op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
953 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
954 emit_insn (gen_subsi3_i (tmp, op1si, bit31));
955 emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
956 emit_insn (gen_cmpsi_cc_insn (op1si, limit));
957 emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
961 REAL_VALUE_TYPE offset;
963 rtx tmp = gen_reg_rtx (SFmode);
964 rtx label = gen_label_rtx ();
966 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
967 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
969 real_2expN (&offset, 31, SFmode);
970 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode);
971 limit = force_reg (SFmode, limit);
972 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
973 emit_insn (gen_subsf3_f (tmp, operands[1], limit));
974 emit_jump_insn (gen_branch_insn (label, cmp, cc1));
975 bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
976 emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
977 emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
983 (define_expand "iadd"
985 [(set (match_operand:SF 0 "gpr_operand" "")
986 (plus:SI (match_operand:SF 1 "gpr_operand" "")
987 (match_operand:SF 2 "gpr_operand" "")))
988 (clobber (reg:CC_FP CCFP_REGNUM))])])
990 (define_insn "*iadd_i"
991 [(match_parallel 3 "float_operation"
992 [(set (match_operand:SI 0 "gpr_operand" "=r")
993 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
994 (match_operand:SI 2 "gpr_operand" "r")))
995 (clobber (reg:CC_FP CCFP_REGNUM))])]
998 [(set_attr "type" "fp_int")])
1000 (define_expand "isub"
1002 [(set (match_operand:SF 0 "gpr_operand" "")
1003 (minus:SI (match_operand:SF 1 "gpr_operand" "")
1004 (match_operand:SF 2 "gpr_operand" "")))
1005 (clobber (reg:CC_FP CCFP_REGNUM))])])
1007 (define_insn "*isub_i"
1008 [(match_parallel 3 "float_operation"
1009 [(set (match_operand:SI 0 "gpr_operand" "=r")
1010 (minus:SI (match_operand:SI 1 "gpr_operand" "r")
1011 (match_operand:SI 2 "gpr_operand" "r")))
1012 (clobber (reg:CC_FP CCFP_REGNUM))])]
1015 [(set_attr "type" "fp_int")])
1017 ; Try to figure out if we over-committed the FPU, and if so, move
1018 ; some insns back over to the integer pipe.
1020 ; The peephole optimizer 'consumes' the insns that are explicitly
1021 ; mentioned. We do not want the preceding insn reconsidered, but
1022 ; we do want that for the following one, so that if we have a run
1023 ; of five fpu users, two of them get changed. Therefore, we
1024 ; use next_active_insn to look at the 'following' insn. That should
1025 ; exist, because peephole2 runs after reload, and there has to be
1026 ; a return after an fp_int insn.
1027 ; ??? However, we can not even ordinarily match the preceding insn;
1028 ; there is some bug in the generators such that then it leaves out
1029 ; the check for PARALLEL before the length check for the then-second
1030 ; main insn. Observed when compiling compatibility-atomic-c++0x.cc
1031 ; from libstdc++-v3.
1033 [(match_parallel 3 "float_operation"
1034 [(set (match_operand:SI 0 "gpr_operand" "")
1035 (match_operator:SI 4 "addsub_operator"
1036 [(match_operand:SI 1 "gpr_operand" "")
1037 (match_operand:SI 2 "gpr_operand" "")]))
1038 (clobber (reg:CC_FP CCFP_REGNUM))])]
1039 "get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1040 && peep2_regno_dead_p (1, CC_REGNUM)
1041 && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))"
1042 [(parallel [(set (match_dup 0) (match_dup 4))
1043 (clobber (reg:CC CC_REGNUM))])]
1046 (define_expand "mulsi3"
1048 [(set (match_operand:SI 0 "gpr_operand" "")
1049 (mult:SI (match_operand:SI 1 "gpr_operand" "")
1050 (match_operand:SI 2 "gpr_operand" "")))
1051 (clobber (reg:CC_FP CCFP_REGNUM))])])
1053 (define_insn "*imul"
1054 [(match_parallel 3 "float_operation"
1055 [(set (match_operand:SI 0 "gpr_operand" "=r")
1056 (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
1057 (match_operand:SI 2 "gpr_operand" "r")))
1058 (clobber (reg:CC_FP CCFP_REGNUM))])]
1061 [(set_attr "type" "fp_int")])
1063 ; combiner pattern, also used by vector combiner pattern
1064 (define_expand "maddsi"
1066 [(set (match_operand:SI 0 "gpr_operand" "=r")
1067 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1068 (match_operand:SI 2 "gpr_operand" "r"))
1069 (match_operand:SI 3 "gpr_operand" "0")))
1070 (clobber (reg:CC_FP CCFP_REGNUM))])]
1073 (define_insn "*maddsi_combine"
1074 [(match_parallel 4 "float_operation"
1075 [(set (match_operand:SI 0 "gpr_operand" "=r")
1076 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1077 (match_operand:SI 2 "gpr_operand" "r"))
1078 (match_operand:SI 3 "gpr_operand" "0")))
1079 (clobber (reg:CC_FP CCFP_REGNUM))])]
1082 [(set_attr "type" "fp_int")])
1084 (define_insn "*imsub"
1085 [(match_parallel 4 "float_operation"
1086 [(set (match_operand:SI 0 "gpr_operand" "=r")
1087 (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1088 (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1089 (match_operand:SI 2 "gpr_operand" "r"))))
1090 (clobber (reg:CC_FP CCFP_REGNUM))])]
1093 [(set_attr "type" "fp_int")])
1095 (define_expand "divsi3"
1097 [(set (match_operand:SI 0 "move_dest_operand" "")
1098 (div:SI (match_operand:SI 1 "move_src_operand" "")
1099 (match_operand:SI 2 "move_src_operand" "")))
1101 (clobber (reg:SI 0))
1102 (clobber (reg:SI 1))
1103 (clobber (reg:SI GPR_IP))
1104 (clobber (reg:DI GPR_16))
1105 (clobber (reg:DI GPR_18))
1106 (clobber (reg:SI GPR_20))
1107 (clobber (reg:SI GPR_LR))
1108 (clobber (reg:CC CC_REGNUM))
1109 (clobber (reg:CC_FP CCFP_REGNUM))])]
1111 "operands[3] = sfunc_symbol (\"__divsi3\");")
1113 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1114 ;; optimizers can more easily move this insn.
1115 (define_insn_and_split "*divsi3_1"
1116 [(match_parallel 4 "float_operation"
1117 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1118 (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1119 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1120 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1121 (clobber (reg:SI 0))
1122 (clobber (reg:SI 1))
1123 (clobber (reg:SI GPR_IP))
1124 (clobber (reg:DI GPR_16))
1125 (clobber (reg:DI GPR_18))
1126 (clobber (reg:SI GPR_20))
1127 (clobber (reg:SI GPR_LR))
1128 (clobber (reg:CC CC_REGNUM))
1129 (clobber (reg:CC_FP CCFP_REGNUM))])]
1132 "&& reload_completed"
1133 [(set (reg:SI 0) (match_dup 1))
1134 (set (reg:SI 1) (match_dup 2))
1136 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1138 (clobber (reg:SI 1))
1139 (clobber (reg:SI GPR_IP))
1140 (clobber (reg:DI GPR_16))
1141 (clobber (reg:DI GPR_18))
1142 (clobber (reg:SI GPR_20))
1143 (clobber (reg:SI GPR_LR))
1144 (clobber (reg:CC CC_REGNUM))
1145 (clobber (reg:CC_FP CCFP_REGNUM))
1148 (set (match_dup 0) (reg:SI 0))]
1149 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1150 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1151 [(set_attr "type" "fp_sfunc")
1152 (set_attr "length" "16,24")])
1154 (define_insn "*divsi3_2"
1155 [(match_parallel 1 "float_operation"
1156 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1157 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1158 (clobber (reg:SI 1))
1159 (clobber (reg:SI GPR_IP))
1160 (clobber (reg:DI GPR_16))
1161 (clobber (reg:DI GPR_18))
1162 (clobber (reg:SI GPR_20))
1163 (clobber (reg:SI GPR_LR))
1164 (clobber (reg:CC CC_REGNUM))
1165 (clobber (reg:CC_FP CCFP_REGNUM))])]
1168 [(set_attr "type" "fp_sfunc")])
1170 (define_expand "udivsi3"
1172 [(set (match_operand:SI 0 "move_dest_operand" "")
1173 (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1174 (match_operand:SI 2 "move_src_operand" "")))
1176 (clobber (reg:SI 0))
1177 (clobber (reg:SI 1))
1178 (clobber (reg:SI GPR_IP))
1179 (clobber (reg:DI GPR_16))
1180 (clobber (reg:SI GPR_18))
1181 (clobber (reg:SI GPR_LR))
1182 (clobber (reg:CC CC_REGNUM))
1183 (clobber (reg:CC_FP CCFP_REGNUM))])]
1185 "operands[3] = sfunc_symbol (\"__udivsi3\");")
1187 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1188 ;; optimizers can more easily move this insn.
1189 (define_insn_and_split "*udivsi3_1"
1190 [(match_parallel 4 "float_operation"
1191 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1192 (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1193 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1194 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1195 (clobber (reg:SI 0))
1196 (clobber (reg:SI 1))
1197 (clobber (reg:SI GPR_IP))
1198 (clobber (reg:DI GPR_16))
1199 (clobber (reg:SI GPR_18))
1200 (clobber (reg:SI GPR_LR))
1201 (clobber (reg:CC CC_REGNUM))
1202 (clobber (reg:CC_FP CCFP_REGNUM))])]
1205 "&& reload_completed"
1206 [(set (reg:SI 0) (match_dup 1))
1207 (set (reg:SI 1) (match_dup 2))
1209 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1211 (clobber (reg:SI 1))
1212 (clobber (reg:SI GPR_IP))
1213 (clobber (reg:DI GPR_16))
1214 (clobber (reg:SI GPR_18))
1215 (clobber (reg:SI GPR_LR))
1216 (clobber (reg:CC CC_REGNUM))
1217 (clobber (reg:CC_FP CCFP_REGNUM))
1220 (set (match_dup 0) (reg:SI 0))]
1221 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1222 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1223 [(set_attr "type" "fp_sfunc")
1224 (set_attr "length" "16,24")])
1226 (define_insn "*udivsi3_2"
1227 [(match_parallel 1 "float_operation"
1228 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1229 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1230 (clobber (reg:SI 1))
1231 (clobber (reg:SI GPR_IP))
1232 (clobber (reg:DI GPR_16))
1233 (clobber (reg:SI GPR_18))
1234 (clobber (reg:SI GPR_LR))
1235 (clobber (reg:CC CC_REGNUM))
1236 (clobber (reg:CC_FP CCFP_REGNUM))])]
1239 [(set_attr "type" "fp_sfunc")])
1241 (define_expand "modsi3"
1243 [(set (match_operand:SI 0 "move_dest_operand" "")
1244 (mod:SI (match_operand:SI 1 "move_src_operand" "")
1245 (match_operand:SI 2 "move_src_operand" "")))
1247 (clobber (reg:SI 0))
1248 (clobber (reg:SI 1))
1249 (clobber (reg:SI 2))
1250 (clobber (reg:SI GPR_IP))
1251 (clobber (reg:DI GPR_16))
1252 (clobber (reg:DI GPR_18))
1253 (clobber (reg:SI GPR_LR))
1254 (clobber (reg:CC CC_REGNUM))
1255 (clobber (reg:CC_FP CCFP_REGNUM))])]
1257 "operands[3] = sfunc_symbol (\"__modsi3\");")
1259 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1260 ;; optimizers can more easily move this insn.
1261 (define_insn_and_split "*modsi3_1"
1262 [(match_parallel 4 "float_operation"
1263 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1264 (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1265 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1266 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1267 (clobber (reg:SI 0))
1268 (clobber (reg:SI 1))
1269 (clobber (reg:SI 2))
1270 (clobber (reg:SI GPR_IP))
1271 (clobber (reg:DI GPR_16))
1272 (clobber (reg:DI GPR_18))
1273 (clobber (reg:SI GPR_LR))
1274 (clobber (reg:CC CC_REGNUM))
1275 (clobber (reg:CC_FP CCFP_REGNUM))])]
1278 "&& reload_completed"
1279 [(set (reg:SI 0) (match_dup 1))
1280 (set (reg:SI 1) (match_dup 2))
1282 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1284 (clobber (reg:SI 2))
1285 (clobber (reg:SI GPR_IP))
1286 (clobber (reg:DI GPR_16))
1287 (clobber (reg:DI GPR_18))
1288 (clobber (reg:SI GPR_LR))
1289 (clobber (reg:CC CC_REGNUM))
1290 (clobber (reg:CC_FP CCFP_REGNUM))
1293 (set (match_dup 0) (reg:SI 0))]
1294 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1295 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1296 [(set_attr "type" "fp_sfunc")
1297 (set_attr "length" "16,24")])
1299 (define_insn "*modsi3_2"
1300 [(match_parallel 1 "float_operation"
1301 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1302 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1303 (clobber (reg:SI 2))
1304 (clobber (reg:SI GPR_IP))
1305 (clobber (reg:DI GPR_16))
1306 (clobber (reg:DI GPR_18))
1307 (clobber (reg:SI GPR_LR))
1308 (clobber (reg:CC CC_REGNUM))
1309 (clobber (reg:CC_FP CCFP_REGNUM))])]
1312 [(set_attr "type" "fp_sfunc")])
1314 (define_expand "umodsi3"
1316 [(set (match_operand:SI 0 "move_dest_operand" "")
1317 (umod:SI (match_operand:SI 1 "move_src_operand" "")
1318 (match_operand:SI 2 "move_src_operand" "")))
1320 (clobber (reg:SI 0))
1321 (clobber (reg:SI 1))
1322 (clobber (reg:SI 2))
1323 (clobber (reg:SI GPR_IP))
1324 (clobber (reg:DI GPR_16))
1325 (clobber (reg:SI GPR_LR))
1326 (clobber (reg:CC CC_REGNUM))
1327 (clobber (reg:CC_FP CCFP_REGNUM))])]
1329 "operands[3] = sfunc_symbol (\"__umodsi3\");")
1331 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1332 ;; optimizers can more easily move this insn.
1333 (define_insn_and_split "*umodsi3_1"
1334 [(match_parallel 4 "float_operation"
1335 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1336 (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1337 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1338 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1339 (clobber (reg:SI 0))
1340 (clobber (reg:SI 1))
1341 (clobber (reg:SI 2))
1342 (clobber (reg:SI GPR_IP))
1343 (clobber (reg:DI GPR_16))
1344 (clobber (reg:SI GPR_LR))
1345 (clobber (reg:CC CC_REGNUM))
1346 (clobber (reg:CC_FP CCFP_REGNUM))])]
1349 "&& reload_completed"
1350 [(set (reg:SI 0) (match_dup 1))
1351 (set (reg:SI 1) (match_dup 2))
1353 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1355 (clobber (reg:SI 2))
1356 (clobber (reg:SI GPR_IP))
1357 (clobber (reg:DI GPR_16))
1358 (clobber (reg:SI GPR_LR))
1359 (clobber (reg:CC CC_REGNUM))
1360 (clobber (reg:CC_FP CCFP_REGNUM))
1363 (set (match_dup 0) (reg:SI 0))]
1364 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1365 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1366 [(set_attr "type" "fp_sfunc")
1367 (set_attr "length" "16,24")])
1369 (define_insn "*umodsi3_2"
1370 [(match_parallel 1 "float_operation"
1371 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1372 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1373 (clobber (reg:SI 2))
1374 (clobber (reg:SI GPR_IP))
1375 (clobber (reg:DI GPR_16))
1376 (clobber (reg:SI GPR_LR))
1377 (clobber (reg:CC CC_REGNUM))
1378 (clobber (reg:CC_FP CCFP_REGNUM))])]
1381 [(set_attr "type" "fp_sfunc")])
1383 ; Disable interrupts.
1384 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1385 ; might have changed settings that we do not want to mess with.
1387 [(set (reg:SI CONFIG_REGNUM)
1388 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1391 [(set_attr "type" "flow")])
1393 ; Enable interrupts.
1394 ; Present CONTROL_REGNUM here to make sure it is live before the
1395 ; actual uses in floating point insns / calls are inserted.
1396 ; FWIW, interrupts also do mind what is in the control register.
1398 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1401 [(set_attr "type" "flow")])
1403 ; Floating point instructions require manipulating the control register.
1404 ; Manipulating the control register needs aritmetic.
1405 ; Arithmetic clobbers flags.
1406 ; The flags are in the status register, which also contains the alternate
1407 ; flag and the interrupt enable/disable bits.
1408 ; saving/restoring status and mixing up the order with gid/gie could
1410 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1411 ; away. But when we really need it, we must make sure that we don't change
1412 ; anything but the flags.
1413 ; N.B.: We could make the constant easier to load by inverting it, but
1414 ; then we'd need to clobber the saved value - and that would make optimizing
1415 ; away unneeded saves/restores harder / less likely.
1416 (define_expand "movcc"
1417 [(parallel [(set (match_operand:CC 0 "cc_move_operand" "")
1418 (match_operand:CC 1 "cc_move_operand" ""))
1420 (clobber (match_scratch:SI 3 "=X, &r"))])]
1422 "operands[2] = gen_int_mode (~0x10f0, SImode);")
1424 (define_insn "*movcc_i"
1425 [(set (match_operand:CC 0 "cc_move_operand" "=r,Rcc")
1426 (match_operand:CC 1 "cc_move_operand" "Rcc, r"))
1427 (use (match_operand:SI 2 "nonmemory_operand" "X, r"))
1428 (clobber (match_scratch:SI 3 "=X, &r"))]
1432 movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1433 [(set_attr "type" "flow")
1434 (set_attr "length" "20,4")])
1436 (define_insn_and_split "set_fp_mode"
1437 [(set (reg:SI FP_NEAREST_REGNUM)
1438 (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1439 (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1440 (set (reg:SI FP_ANYFP_REGNUM)
1441 (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1442 (use (match_operand:SI 2 "gpr_operand" "r"))
1443 (clobber (reg:CC CC_REGNUM))
1444 (clobber (match_scratch:SI 3 "=&r"))]
1447 "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1450 if (!reload_completed)
1451 emit_note (NOTE_INSN_DELETED);
1453 epiphany_expand_set_fp_mode (operands);
1458 ;; Boolean instructions.
1460 ;; We don't define the DImode versions as expand_binop does a good enough job.
1462 (define_insn "andsi3"
1463 [(set (match_operand:SI 0 "gpr_operand" "=r")
1464 (and:SI (match_operand:SI 1 "gpr_operand" "r")
1465 (match_operand:SI 2 "gpr_operand" "r")))
1466 (clobber (reg:CC CC_REGNUM))]
1470 (define_insn "iorsi3"
1471 [(set (match_operand:SI 0 "gpr_operand" "=r")
1472 (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1473 (match_operand:SI 2 "gpr_operand" "r")))
1474 (clobber (reg:CC CC_REGNUM))]
1478 (define_insn "xorsi3"
1479 [(set (match_operand:SI 0 "gpr_operand" "=r")
1480 (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1481 (match_operand:SI 2 "gpr_operand" "r")))
1482 (clobber (reg:CC CC_REGNUM))]
1486 (define_expand "one_cmplsi2"
1487 [(set (match_operand:SI 0 "gpr_operand" "")
1488 (xor:SI (match_operand:SI 1 "gpr_operand" "")
1492 if (epiphany_m1reg >= 0)
1493 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1495 emit_insn (gen_xorsi3 (operands[0], operands[1],
1496 force_reg (SImode, GEN_INT (-1))));
1500 ; Note that folding this pattern into the xorsi3 pattern would make combine
1502 (define_insn "one_cmplsi2_i"
1503 [(set (match_operand:SI 0 "gpr_operand" "=r")
1504 (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1505 (clobber (reg:CC CC_REGNUM))]
1506 "epiphany_m1reg >= 0"
1509 ;; Shift instructions.
1510 ;; In principle we could support arbitrary symbolic values as shift constant
1511 ;; (truncating the value appropriately), but that would require a suitable
1512 ;; relocation and assembler & linker support.
1513 (define_insn "ashrsi3"
1514 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1515 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1516 (match_operand:SI 2 "arith_operand" "r,K")))
1517 (clobber (reg:CC CC_REGNUM))]
1520 [(set_attr "length" "4")
1521 (set_attr "type" "shift")])
1523 (define_insn "ashrsi3_tst"
1524 [(set (reg:CC CC_REGNUM)
1526 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1527 (match_operand:SI 2 "arith_operand" "r,K"))
1529 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1530 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1533 [(set_attr "length" "4")
1534 (set_attr "type" "shift")])
1536 ;; Logical Shift Right
1537 (define_insn "lshrsi3"
1538 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1539 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1540 (match_operand:SI 2 "arith_operand" "r,K")))
1541 (clobber (reg:CC CC_REGNUM))]
1544 [(set_attr "length" "4")
1545 (set_attr "type" "shift")])
1547 (define_insn "lshrsi3_tst"
1548 [(set (reg:CC CC_REGNUM)
1550 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1551 (match_operand:SI 2 "arith_operand" "r,K"))
1553 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1554 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1557 [(set_attr "length" "4")
1558 (set_attr "type" "shift")])
1560 ;; Logical/Arithmetic Shift Left
1561 (define_insn "ashlsi3"
1562 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1563 (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1564 (match_operand:SI 2 "arith_operand" "r,K")))
1565 (clobber (reg:CC CC_REGNUM))]
1568 [(set_attr "length" "4")
1569 (set_attr "type" "shift")])
1571 (define_insn "*ashlsi_btst"
1572 [(set (reg:CC_N_NE CC_REGNUM)
1574 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1576 (match_operand 2 "const_int_operand" "K"))
1578 (clobber (match_scratch:SI 0 "=r"))]
1583 xop[0] = operands[0];
1584 xop[1] = operands[1];
1585 xop[2] = GEN_INT (31-INTVAL (operands[2]));
1586 output_asm_insn ("lsl %0,%1,%2", xop);
1591 (define_insn_and_split "zero_extendqisi2"
1592 [(set (match_operand:SI 0 "register_operand" "=r,r")
1593 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1594 (clobber (reg:CC CC_REGNUM))]
1600 ? true_regnum (operands[1]) >= 0
1601 : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1602 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1603 (clobber (reg:CC CC_REGNUM))])
1604 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1605 (clobber (reg:CC CC_REGNUM))])]
1606 "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1608 (define_insn "zero_extendhisi2"
1609 [(set (match_operand:SI 0 "register_operand" "=r,r")
1610 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1617 ;; Compare instructions.
1619 (define_insn "cmpsi_cc_insn"
1620 [(set (reg:CC CC_REGNUM)
1621 (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1622 (match_operand:SI 1 "arith_operand" "r,L")))
1623 (clobber (match_scratch:SI 2 "=r,r"))]
1626 [(set_attr "type" "compare")])
1628 (define_insn "sub_f"
1629 [(set (reg:CC CC_REGNUM)
1630 (compare:CC (match_operand:SI 1 "gpr_operand" "r,r")
1631 (match_operand:SI 2 "arith_operand" "r,L")))
1632 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1633 (minus:SI (match_dup 1) (match_dup 2)))]
1636 [(set_attr "type" "compare")])
1638 (define_insn "*sub_f_add_imm"
1639 [(set (reg:CC CC_REGNUM)
1640 (compare:CC (match_operand:SI 1 "gpr_operand" "r")
1641 (match_operand:SI 2 "arith_int_operand" "L")))
1642 (set (match_operand:SI 0 "gpr_operand" "=r")
1643 (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "L")))]
1644 "INTVAL (operands[2]) == -INTVAL (operands[3])"
1646 [(set_attr "type" "compare")])
1648 (define_expand "abssi2"
1649 [(set (match_dup 2) (const_int 0))
1650 (parallel [(set (reg:CC CC_REGNUM)
1651 (compare:CC (match_dup 2)
1652 (match_operand:SI 1 "nonmemory_operand" "")))
1654 (minus:SI (match_dup 2) (match_dup 1)))])
1655 (set (match_operand:SI 0 "gpr_operand" "=r")
1656 (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1660 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1662 (define_insn "*add_c"
1663 [(set (reg:CC_C_LTU CC_REGNUM)
1665 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1666 (match_operand:SI 2 "arith_operand" "r,L"))
1668 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1669 (plus:SI (match_dup 1) (match_dup 2)))]
1672 [(set_attr "type" "compare")])
1674 (define_insn "*add_c_rev"
1675 [(set (reg:CC_C_LTU CC_REGNUM)
1677 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1678 (match_operand:SI 2 "arith_operand" "r,L"))
1680 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1681 (plus:SI (match_dup 2) (match_dup 1)))]
1684 [(set_attr "type" "compare")])
1686 (define_insn "*sub_c"
1687 [(set (reg:CC_C_GTU CC_REGNUM)
1689 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1690 (match_operand:SI 2 "arith_operand" "r,L"))
1692 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1693 (minus:SI (match_dup 1) (match_dup 2)))]
1696 [(set_attr "type" "compare")])
1698 (define_insn "*sub_c_void"
1699 [(set (reg:CC_C_GTU CC_REGNUM)
1701 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1702 (match_operand:SI 2 "arith_operand" "r,L"))
1704 (clobber (match_scratch:SI 0 "=r,r"))]
1707 [(set_attr "type" "compare")])
1709 ; floating point comparisons
1711 (define_insn "*cmpsf_cc_insn"
1712 [(match_parallel 3 "float_operation"
1713 [(set (reg:CC_FP CCFP_REGNUM)
1714 (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1715 (match_operand:SF 1 "gpr_operand" "r")))
1716 (clobber (match_scratch:SF 2 "=r"))])]
1717 "!TARGET_SOFT_CMPSF"
1719 [(set_attr "type" "fp")
1720 (set_attr "fp_mode" "round_unknown")])
1722 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1723 ;; to allow the rtl loop optimizer to generate comparisons? OTOH
1724 ;; we want call_address_operand to enforce valid operands so that
1725 ;; combine won't do silly things, allowing instruction scheduling to do
1727 (define_insn "*cmpsf_eq"
1728 [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (reg:SF 0) (reg:SF 1)))
1729 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1730 (clobber (reg:SI GPR_IP))
1731 (clobber (reg:SI GPR_LR))]
1734 [(set_attr "type" "sfunc")])
1736 (define_insn "*cmpsf_gte"
1737 [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (reg:SF 0) (reg:SF 1)))
1738 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1739 (clobber (reg:SI GPR_IP))
1740 (clobber (reg:SI GPR_LR))]
1743 [(set_attr "type" "sfunc")])
1745 (define_insn "*cmpsf_ord"
1746 [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1747 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1748 (clobber (reg:SI GPR_IP))
1749 (clobber (reg:SI GPR_16))
1750 (clobber (reg:SI GPR_LR))]
1753 [(set_attr "type" "sfunc")])
1755 (define_insn "*cmpsf_uneq"
1756 [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1757 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1758 (clobber (reg:SI GPR_IP))
1759 (clobber (reg:SI GPR_16))
1760 (clobber (reg:SI GPR_LR))]
1763 [(set_attr "type" "sfunc")])
1765 ;; conditional moves
1767 (define_expand "mov<mode>cc"
1768 [(set (match_operand:WMODE 0 "gpr_operand" "")
1769 (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1770 (match_operand:WMODE 2 "gpr_operand" "")
1771 (match_operand:WMODE 3 "gpr_operand" "")))]
1774 rtx cmp_op0 = XEXP (operands[1], 0);
1775 rtx cmp_op1 = XEXP (operands[1], 1);
1776 enum machine_mode cmp_in_mode;
1777 enum rtx_code code = GET_CODE (operands[1]);
1779 cmp_in_mode = GET_MODE (cmp_op0);
1780 if (cmp_in_mode == VOIDmode)
1781 cmp_in_mode = GET_MODE (cmp_op1);
1782 if (cmp_in_mode == VOIDmode)
1783 cmp_in_mode = SImode;
1784 /* If the operands are a better match when reversed, swap them now.
1785 This allows combine to see the proper comparison codes. */
1786 if (rtx_equal_p (operands[0], operands[2])
1787 && !rtx_equal_p (operands[0], operands[3]))
1789 rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1790 code = (FLOAT_MODE_P (GET_MODE (cmp_op0))
1791 ? reverse_condition_maybe_unordered (code)
1792 : reverse_condition (code));
1795 if (proper_comparison_operator (operands[1], VOIDmode))
1796 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1799 if (!currently_expanding_to_rtl)
1801 /* ??? It would seem safest to FAIL here, but that would defeat
1802 the purpose of having an if-conversion pass; its logic currently
1803 assumes that the backend should be safe to insert condition code
1804 setting instructions, as the same condition codes were presumably
1805 set by the if-conversion input code. */
1807 /* What mode to give as first operand to gen_compare_reg here is
1808 debatable. VOIDmode would be minimalist; telling gen_compare_reg
1809 to use the mode of CC_REGNUM (or putting it on the comparison
1810 operator afterwards) is also a logical choice. OTOH, by using
1811 <MODE>mode, we have mode combine opportunities with flag setting
1812 operations - if we get some. */
1814 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1818 (define_insn "*mov<mode>cc_insn"
1819 [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1820 (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1821 [(match_operand 4 "cc_operand") (const_int 0)])
1822 (match_operand:WMODE 1 "gpr_operand" "r")
1823 (match_operand:WMODE 2 "gpr_operand" "0")))]
1826 [(set_attr "type" "cmove")])
1829 [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
1830 (match_operand:WMODE 1 "" ""))
1831 (clobber (match_operand 8 "cc_operand"))])
1832 (match_operand 2 "" "")
1833 (set (match_operand:WMODE2 3 "gpr_operand" "")
1834 (match_operand:WMODE2 9 "gpr_operand" ""))
1836 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1837 [(match_operand 6 "cc_operand")
1838 (match_operand 7 "const0_operand")])
1839 (match_operand:WMODE2 4 "nonmemory_operand" "")
1841 "REGNO (operands[0]) == REGNO (operands[9])
1842 && peep2_reg_dead_p (3, operands[0])
1843 && !reg_set_p (operands[0], operands[2])
1844 && !reg_set_p (operands[3], operands[2])
1845 && !reg_overlap_mentioned_p (operands[3], operands[2])"
1846 [(parallel [(set (match_dup 10) (match_dup 1))
1847 (clobber (match_dup 8))])
1850 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1852 operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1853 <WMODE2:MODE>mode, 0);
1854 replace_rtx (operands[2], operands[9], operands[3]);
1855 replace_rtx (operands[2], operands[0], operands[10]);
1856 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
1860 [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
1861 (set (match_operand:WMODE 0 "gpr_operand" "")
1862 (match_operand:WMODE 1 "" ""))])
1863 (set (match_operand:WMODE2 3 "gpr_operand" "")
1864 (match_operand:WMODE2 4 "gpr_operand"))
1866 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1868 (match_operand:WMODE 7 "const0_operand")])
1869 (match_operand:WMODE2 8 "gpr_operand")
1871 "REGNO (operands[0]) == REGNO (operands[8])
1872 && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
1873 && peep2_reg_dead_p (3, operands[6])
1874 && peep2_reg_dead_p (3, operands[0])
1875 && !reg_overlap_mentioned_p (operands[4], operands[3])"
1876 [(parallel [(set (match_dup 6) (match_dup 2))
1877 (set (match_dup 9) (match_dup 1))])
1879 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1883 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
1884 GET_MODE (operands[6])),
1885 GET_MODE (operands[5]), operands[6], operands[7]);
1886 operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1887 <WMODE2:MODE>mode, 0);
1890 ;; These control RTL generation for conditional jump insns
1892 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
1893 ;; they must allow const0_rtx for both comparison operands
1894 (define_expand "cbranchsi4"
1895 [(set (reg CC_REGNUM)
1896 (compare (match_operand:SI 1 "add_operand" "")
1897 (match_operand:SI 2 "arith_operand" "")))
1900 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
1902 (label_ref (match_operand 3 "" ""))
1906 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
1907 operands[1], operands[2]);
1908 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1912 (define_expand "cbranchsf4"
1913 [(set (reg CC_REGNUM)
1914 (compare (match_operand:SF 1 "arith_operand" "")
1915 (match_operand:SF 2 "arith_operand" "")))
1918 (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
1920 (label_ref (match_operand 3 "" ""))
1924 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
1925 operands[1], operands[2]);
1926 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1930 ;; Now match both normal and inverted jump.
1932 (define_insn "branch_insn"
1934 (if_then_else (match_operator 1 "proper_comparison_operator"
1935 [(match_operand 2 "cc_operand")
1937 (label_ref (match_operand 0 "" ""))
1941 [(set_attr "type" "branch")])
1943 (define_insn "*rev_branch_insn"
1945 (if_then_else (match_operator 1 "proper_comparison_operator"
1946 [(reg CC_REGNUM) (const_int 0)])
1948 (label_ref (match_operand 0 "" ""))))]
1951 [(set_attr "type" "branch")])
1953 ;; Unconditional and other jump instructions.
1956 [(set (pc) (label_ref (match_operand 0 "" "")))]
1959 [(set_attr "type" "uncond_branch")])
1961 (define_insn "indirect_jump"
1962 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
1965 [(set_attr "type" "uncond_branch")])
1967 (define_expand "tablejump"
1968 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
1969 (use (label_ref (match_operand 1 "" "")))])]
1972 /* In PIC mode, the table entries are stored PC relative.
1973 Convert the relative address to an absolute address. */
1976 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1978 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1979 op1, NULL_RTX, 0, OPTAB_DIRECT);
1983 (define_insn "*tablejump_internal"
1984 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
1985 (use (label_ref (match_operand 1 "" "")))]
1988 [(set_attr "type" "uncond_branch")])
1990 (define_insn "*tablejump_hi_internal"
1991 [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
1992 (use (label_ref (match_operand 1 "" "")))]
1993 "optimize_size && TARGET_SMALL16"
1995 [(set_attr "type" "uncond_branch")])
1998 (define_expand "call"
1999 ;; operands[1] is stack_size_rtx
2000 ;; operands[2] is next_arg_register
2001 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2002 (match_operand 1 "" ""))
2003 (clobber (reg:SI GPR_LR))])]
2006 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2008 if (!call_operand (operands[1], VOIDmode))
2010 = change_address (operands[0], VOIDmode,
2011 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2012 if (epiphany_uninterruptible_p (current_function_decl)
2013 != target_uninterruptible)
2015 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2019 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2020 gen_rtx_CLOBBER (VOIDmode,
2021 gen_rtx_REG (SImode, GPR_LR)))));
2022 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2027 (define_insn "*call_i"
2028 [(match_parallel 2 "float_operation"
2029 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
2030 (match_operand 1 "" ""))
2031 (clobber (reg:SI GPR_LR))])]
2034 [(set_attr "type" "call")])
2036 (define_expand "sibcall"
2037 ;; operands[1] is stack_size_rtx
2038 ;; operands[2] is next_arg_register
2039 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2040 (match_operand 1 "" ""))
2044 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2046 if (!call_operand (operands[1], VOIDmode))
2048 = change_address (operands[0], VOIDmode,
2049 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2050 if (epiphany_uninterruptible_p (current_function_decl)
2051 != target_uninterruptible)
2053 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2057 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2059 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2064 (define_insn "*sibcall_i"
2065 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
2066 (match_operand 1 "" ""))
2072 [(set_attr "type" "call")])
2074 (define_expand "call_value"
2075 ;; operand 2 is stack_size_rtx
2076 ;; operand 3 is next_arg_register
2077 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2078 (call (match_operand:SI 1 "call_operand" "")
2079 (match_operand 2 "" "")))
2080 (clobber (reg:SI GPR_LR))])]
2083 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2085 if (!call_operand (operands[1], VOIDmode))
2087 = change_address (operands[1], VOIDmode,
2088 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2089 if (epiphany_uninterruptible_p (current_function_decl)
2090 != target_uninterruptible)
2092 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2096 gen_rtvec (2, gen_rtx_SET
2097 (VOIDmode, operands[0],
2098 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2099 gen_rtx_CLOBBER (VOIDmode,
2100 gen_rtx_REG (SImode, GPR_LR)))));
2101 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2106 (define_insn "*call_value_i"
2107 [(match_parallel 3 "float_operation"
2108 [(set (match_operand 0 "gpr_operand" "=r,r")
2109 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2110 (match_operand 2 "" "")))
2111 (clobber (reg:SI GPR_LR))])]
2114 [(set_attr "type" "call")
2115 (set_attr "length" "4")])
2117 (define_expand "sibcall_value"
2118 ;; operand 2 is stack_size_rtx
2119 ;; operand 3 is next_arg_register
2120 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2121 (call (match_operand:SI 1 "call_operand" "")
2122 (match_operand 2 "" "")))
2126 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2128 if (!call_operand (operands[1], VOIDmode))
2130 = change_address (operands[1], VOIDmode,
2131 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2132 if (epiphany_uninterruptible_p (current_function_decl)
2133 != target_uninterruptible)
2135 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2139 gen_rtvec (2, gen_rtx_SET
2140 (VOIDmode, operands[0],
2141 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2143 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2148 (define_insn "*sibcall_value_i"
2149 [(set (match_operand 0 "gpr_operand" "=r,r")
2150 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2151 (match_operand 2 "" "")))
2157 [(set_attr "type" "call")
2158 (set_attr "length" "4")])
2160 (define_expand "prologue"
2164 epiphany_expand_prologue ();
2168 (define_expand "epilogue"
2172 epiphany_expand_epilogue (0);
2176 (define_expand "sibcall_epilogue"
2180 epiphany_expand_epilogue (1);
2184 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2185 ; in the prologue / epilogue expanders how many times lr is set.
2186 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2187 ; any explicit use of lr will cause it to be saved; hence we cannot
2188 ; represent the blink use in return / sibcall instructions themselves, and
2189 ; instead have to show it in EPILOGUE_USES.
2190 (define_insn "return_i"
2194 [(set_attr "type" "uncond_branch")])
2196 (define_insn "return_internal_interrupt"
2198 (unspec_volatile [(const_int 0)] 1)]
2201 [(set_attr "type" "uncond_branch")])
2203 (define_insn "stack_adjust_add"
2204 [(set (reg:SI GPR_SP)
2205 (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2206 (clobber (reg:CC CC_REGNUM))
2207 (clobber (reg:SI STATUS_REGNUM))
2208 (clobber (match_operand:BLK 1 "memory_operand" "=m"))]
2212 (define_insn "stack_adjust_mov"
2213 [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2214 (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2217 [(set_attr "type" "move")])
2219 (define_insn "stack_adjust_str"
2220 [(set (match_operand 0 "stacktop_operand" "=m")
2221 (match_operand 1 "any_gpr_operand" "r"))
2222 (set (reg:SI GPR_SP)
2223 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2224 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2227 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2228 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2230 [(set_attr "type" "store")])
2232 (define_insn "stack_adjust_ldr"
2233 [(set (match_operand:SI 0 "gpr_operand" "=r")
2234 (match_operand:SI 1 "stacktop_operand" "m"))
2235 (set (reg:SI GPR_SP)
2236 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2237 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2240 [(set_attr "type" "load")])
2242 ;; Define some fake vector operations so that the vectorizer is happy to use
2243 ;; 64 bit loads/stores.
2244 (define_expand "vec_unpacks_lo_v4hi"
2245 [(match_operand:V2SI 0 "gpr_operand")
2246 (match_operand:V4HI 1 "gpr_operand")]
2249 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2250 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2252 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2254 if (reg_overlap_mentioned_p (outl, in))
2255 in = copy_to_mode_reg (SImode, in);
2256 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2257 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2258 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2262 (define_expand "vec_unpacks_hi_v4hi"
2263 [(match_operand:V2SI 0 "gpr_operand")
2264 (match_operand:V4HI 1 "gpr_operand")]
2267 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2268 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2270 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2272 if (reg_overlap_mentioned_p (outl, in))
2273 in = copy_to_mode_reg (SImode, in);
2274 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2275 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2276 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2280 (define_code_iterator addsub [plus minus])
2282 (define_code_iterator alu_binop
2283 [plus minus and ior xor])
2285 (define_code_attr insn_opname
2286 [(plus "add") (minus "sub") (mult "mul") (div "div")
2287 (and "and") (ior "ior") (xor "xor")])
2289 ; You might think that this would work better as a define_expand, but
2290 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2291 ; We need to keep inputs and outputs as register pairs if we want to
2292 ; get sensible register allocation for double-word load and store operations.
2293 (define_insn_and_split "<insn_opname>v2si3"
2294 [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2295 (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2296 (match_operand:V2SI 2 "gpr_operand" "r")))
2297 (clobber (reg:CC CC_REGNUM))]
2300 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2303 rtx o0l, o0h, o1l, o1h, o2l, o2h;
2305 o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2306 o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2307 o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2308 o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2309 o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2310 o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2311 if (reg_overlap_mentioned_p (o0l, o1h))
2312 o1h = copy_to_mode_reg (SImode, o1h);
2313 if (reg_overlap_mentioned_p (o0l, o2h))
2314 o2h = copy_to_mode_reg (SImode, o2h);
2315 emit_insn (gen_<insn_opname>si3 (o0l, o1l, o2l));
2316 emit_insn (gen_<insn_opname>si3 (o0h, o1h, o2h));
2319 [(set_attr "length" "8")])
2321 (define_expand "<insn_opname>v2sf3"
2323 [(set (match_operand:V2SF 0 "gpr_operand" "")
2324 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2325 (match_operand:V2SF 2 "gpr_operand" "")))
2326 (clobber (reg:CC_FP CCFP_REGNUM))])])
2328 (define_insn_and_split "<insn_opname>v2sf3_i"
2329 [(match_parallel 3 "float_operation"
2330 [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2331 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2332 (match_operand:V2SF 2 "gpr_operand" "r")))
2333 (clobber (reg:CC_FP CCFP_REGNUM))])]
2336 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2338 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2339 (clobber (reg:CC_FP CCFP_REGNUM))
2343 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2344 (clobber (reg:CC_FP CCFP_REGNUM))
2348 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2349 operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2350 operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2352 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2354 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2356 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2357 if (!reload_completed)
2359 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2360 operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2361 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2362 operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2363 emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2364 emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2367 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2368 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2369 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2370 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2372 [(set_attr "length" "8")
2373 (set_attr "type" "v2fp")])
2375 (define_expand "mul<mode>3"
2377 [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2378 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2379 (match_operand:DWV2MODE 2 "gpr_operand" "")))
2380 (clobber (reg:CC_FP CCFP_REGNUM))])])
2382 (define_insn_and_split "mul<mode>3_i"
2383 [(match_parallel 3 "float_operation"
2384 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2385 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2386 (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2387 (clobber (reg:CC_FP CCFP_REGNUM))])]
2390 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2392 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2393 (clobber (reg:CC_FP CCFP_REGNUM))
2397 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2398 (clobber (reg:CC_FP CCFP_REGNUM))
2403 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2405 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2407 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2408 operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2409 <MODE>mode, UNITS_PER_WORD);
2410 operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2411 <MODE>mode, UNITS_PER_WORD);
2412 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2413 <MODE>mode, UNITS_PER_WORD);
2414 if (!reload_completed)
2416 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2417 operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2418 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2419 operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2420 emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2421 emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2424 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2425 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2426 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2427 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2429 [(set_attr "length" "8")
2430 (set_attr "type" "<vmode_fp_type>")])
2432 (define_insn_and_split "*fmadd<mode>_combine"
2433 [(match_parallel 4 "float_operation"
2434 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2435 (plus:DWV2MODE (mult:<MODE>
2436 (match_operand:<MODE> 1 "gpr_operand" "r")
2437 (match_operand:<MODE> 2 "gpr_operand" "r"))
2438 (match_operand:<MODE> 3 "gpr_operand" "0")))
2439 (clobber (reg:CC_FP CCFP_REGNUM))])]
2440 "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2442 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2445 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2447 (clobber (reg:CC_FP CCFP_REGNUM))
2452 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2454 (clobber (reg:CC_FP CCFP_REGNUM))
2459 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2461 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2463 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2465 = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2466 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2467 <MODE>mode, UNITS_PER_WORD);
2468 operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2469 <MODE>mode, UNITS_PER_WORD);
2470 operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2471 <MODE>mode, UNITS_PER_WORD);
2472 operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2473 <MODE>mode, UNITS_PER_WORD);
2474 if (!reload_completed)
2476 if (reg_overlap_mentioned_p (operands[5], operands[10]))
2477 operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2478 if (reg_overlap_mentioned_p (operands[5], operands[11]))
2479 operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2480 if (reg_overlap_mentioned_p (operands[5], operands[12]))
2481 operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2482 emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2484 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2488 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2489 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2490 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2491 operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2492 operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2494 [(set_attr "length" "8")
2495 (set_attr "type" "<vmode_fp_type>")])
2497 (define_expand "vec_set<mode>"
2498 [(match_operand:DWV2MODE 0 "register_operand")
2499 (match_operand:<vmode_PART> 1 "register_operand")
2500 (match_operand 2 "const_int_operand" "")]
2504 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2505 UNITS_PER_WORD * INTVAL (operands[2]));
2506 emit_move_insn (operands[0], operands[1]);
2510 (define_expand "movmisalign<mode>"
2511 [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "")
2512 (match_operand:DWV2MODE 1 "general_operand" ""))]
2515 rtx op00, op01, op10, op11;
2517 op00 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2518 op01 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2520 op10 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2521 op11 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode,
2523 emit_move_insn (op00, op10);
2524 emit_move_insn (op01, op11);
2532 [(set_attr "type" "flow")])