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 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,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,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 (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 && (GET_CODE (operands[0]) != SUBREG
329 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
330 != GET_MODE_SIZE (<MODE>mode)
331 && GET_CODE (operands[1]) != SUBREG)))
334 = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0);
336 = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0);
337 emit_insn (gen_movdi (operands[0], operands[1]));
341 /* Everything except mem = const or mem = mem can be done easily. */
343 if (GET_CODE (operands[0]) == MEM)
344 operands[1] = force_reg (<MODE>mode, operands[1]);
347 (define_insn_and_split "*mov<mode>_insn"
348 [(set (match_operand:DWMODE 0 "move_dest_operand" "=r, r,r,m")
349 (match_operand:DWMODE 1 "move_double_src_operand" "r,CalE,m,r"))]
350 "(gpr_operand (operands[0], <MODE>mode)
351 || gpr_operand (operands[1], <MODE>mode))"
358 && ((!MEM_P (operands[0]) && !MEM_P (operands[1]))
359 || epiphany_vect_align == 4)"
360 [(set (match_dup 2) (match_dup 3))
361 (set (match_dup 4) (match_dup 5))]
363 int word0 = 0, word1 = UNITS_PER_WORD;
365 if (post_modify_operand (operands[0], <MODE>mode)
366 || post_modify_operand (operands[1], <MODE>mode))
367 word0 = UNITS_PER_WORD, word1 = 0;
369 operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
370 operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
371 operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
372 operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
373 if (post_modify_operand (operands[0], <MODE>mode))
375 = change_address (operands[2], VOIDmode,
376 plus_constant (XEXP (XEXP (operands[0], 0), 0),
378 if (post_modify_operand (operands[1], <MODE>mode))
380 = change_address (operands[3], VOIDmode,
381 plus_constant (XEXP (XEXP (operands[1], 0), 0),
384 [(set_attr "type" "move,move,load,store")
385 (set_attr "length" "8,16,4,4")])
388 (define_insn_and_split "*movsf_insn"
389 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
390 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
391 "gpr_operand (operands[0], SFmode)
392 || gpr_operand (operands[1], SFmode)"
395 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
398 "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
399 [(set (match_dup 2) (match_dup 3))]
400 "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
401 operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
402 [(set_attr "type" "move,move,load,store")
403 (set_attr "length" "4,8,4,4")])
405 (define_expand "addsi3"
406 [(set (match_operand:SI 0 "add_reg_operand" "")
407 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
408 (match_operand:SI 2 "add_operand" "")))]
412 if (reload_in_progress || reload_completed)
413 emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
415 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
419 (define_insn "addsi3_i"
420 [(set (match_operand:SI 0 "add_reg_operand" "=r")
421 (plus:SI (match_operand:SI 1 "add_reg_operand" "%r")
422 (match_operand:SI 2 "add_operand" "rL")))
423 (clobber (reg:CC CC_REGNUM))]
426 [(set_attr "type" "misc")])
428 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
429 ; can identify the unresolved flags clobber problem, and also to
430 ; avoid unwanted matches.
432 ; At -O0 / -O1 we don't peephole all instances away. We could get better
433 ; debug unwinding through the emitted code if we added a splitter.
434 (define_insn "addsi3_r"
435 [(set (match_operand:SI 0 "gpr_operand" "=r")
436 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
437 (match_operand:SI 2 "nonmemory_operand" "rCar")))
438 (clobber (reg:CC UNKNOWN_REGNUM))]
439 "reload_in_progress || reload_completed"
442 ^ (true_regnum (operands[0]) & 1)
443 ^ (true_regnum (operands[1]) & 2)
444 ^ (true_regnum (operands[2]) & 4));
445 asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
446 asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
447 output_asm_insn ("add %0,%1,%2", operands);
448 asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
449 asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
452 [(set_attr "length" "20")
453 (set_attr "type" "misc")])
455 ;; reload uses gen_addsi2 because it doesn't understand the need for
458 [(set (match_operand:SI 0 "gpr_operand" "")
459 (match_operand:SI 1 "const_int_operand" ""))
460 (parallel [(set (match_dup 0)
461 (plus:SI (match_dup 0)
462 (match_operand:SI 2 "gpr_operand")))
463 (clobber (reg:CC UNKNOWN_REGNUM))])]
464 "satisfies_constraint_L (operands[1])
465 || ((operands[2] == stack_pointer_rtx
466 || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
467 && !peep2_regno_dead_p (2, CC_REGNUM)
468 && satisfies_constraint_Car (operands[1]))"
469 [(parallel [(set (match_dup 0)
470 (plus:SI (match_dup 2) (match_dup 1)))
471 (clobber (reg:CC UNKNOWN_REGNUM))])]
473 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
474 ;; "peep2_rescan = true;"
478 [(match_parallel 5 ""
479 [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
480 (parallel [(set (match_operand:SI 0 "gpr_operand" "")
481 (plus:SI (match_operand:SI 1 "gpr_operand" "")
482 (match_operand:SI 2 "nonmemory_operand" "")))
483 (clobber (reg:CC UNKNOWN_REGNUM))])]
484 "REGNO (operands[3]) == CC_REGNUM
485 && (gpr_operand (operands[2], SImode)
486 || satisfies_constraint_L (operands[2]))
487 && !reg_overlap_mentioned_p (operands[0], operands[5])
488 && !reg_set_p (operands[1], operands[5])
489 && !reg_set_p (operands[2], operands[5])"
490 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
491 (plus:SI (match_operand:SI 1 "gpr_operand" "")
492 (match_operand:SI 2 "nonmemory_operand" "")))
493 (clobber (reg:CC CC_REGNUM))])
498 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
499 (plus:SI (match_operand:SI 1 "gpr_operand" "")
500 (match_operand:SI 2 "nonmemory_operand" "")))
501 (clobber (reg:CC UNKNOWN_REGNUM))])]
502 "peep2_regno_dead_p (1, CC_REGNUM)
503 && (gpr_operand (operands[2], SImode)
504 || satisfies_constraint_L (operands[2]))"
505 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
506 (plus:SI (match_operand:SI 1 "gpr_operand" "")
507 (match_operand:SI 2 "nonmemory_operand" "")))
508 (clobber (reg:CC CC_REGNUM))])]
512 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
513 (plus:SI (reg:SI GPR_SP)
514 (match_operand:SI 1 "nonmemory_operand" "")))
515 (clobber (reg:CC UNKNOWN_REGNUM))])]
516 "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
517 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
518 [(set (match_dup 0) (reg:SI GPR_SP))
519 (set (mem:WMODE (post_modify (match_dup 0)
520 (plus:SI (match_dup 0) (match_dup 1))))
527 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
528 (plus:SI (reg:SI GPR_FP)
529 (match_operand:SI 1 "nonmemory_operand" "")))
530 (clobber (reg:CC UNKNOWN_REGNUM))])
531 (match_scratch:WMODE 2 "r")]
532 "frame_pointer_needed
533 && ((REG_P (operands[1])
534 && !reg_overlap_mentioned_p (operands[0], operands[1]))
535 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
536 [(set (match_dup 0) (reg:SI GPR_FP))
538 (mem:WMODE (post_modify (match_dup 0)
539 (plus:SI (match_dup 0) (match_dup 1)))))]
542 (define_insn "subsi3"
543 [(set (match_operand:SI 0 "gpr_operand" "=r")
544 (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
545 (match_operand:SI 2 "arith_operand" "rL")))
546 (clobber (reg:CC CC_REGNUM))]
549 [(set_attr "type" "misc")])
551 ; After mode-switching, floating point operations, fp_sfuncs and calls
552 ; must exhibit the use of the control register, lest the setting of the
553 ; control register could be deleted or moved. OTOH a use of a hard register
554 ; greatly coundounds optimizers like the rtl loop optimizers or combine.
555 ; Therefore, we put an extra pass immediately after the mode switching pass
556 ; that inserts the USEs of the control registers, and sets a flag in struct
557 ; machine_function that float_operation can henceforth only match with that
561 (define_expand "addsf3"
563 [(set (match_operand:SF 0 "gpr_operand" "")
564 (plus:SF (match_operand:SF 1 "gpr_operand" "")
565 (match_operand:SF 2 "gpr_operand" "")))
566 (clobber (reg:CC_FP CCFP_REGNUM))])])
568 (define_insn "*addsf3_i"
569 [(match_parallel 3 "float_operation"
570 [(set (match_operand:SF 0 "gpr_operand" "=r")
571 (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
572 (match_operand:SF 2 "gpr_operand" "r")))
573 (clobber (reg:CC_FP CCFP_REGNUM))])]
576 [(set_attr "type" "fp")])
579 (define_expand "subsf3"
581 [(set (match_operand:SF 0 "gpr_operand" "")
582 (minus:SF (match_operand:SF 1 "gpr_operand" "")
583 (match_operand:SF 2 "gpr_operand" "")))
584 (clobber (reg:CC_FP CCFP_REGNUM))])])
586 (define_insn "*subsf3_i"
587 [(match_parallel 3 "float_operation"
588 [(set (match_operand:SF 0 "gpr_operand" "=r")
589 (minus:SF (match_operand:SF 1 "gpr_operand" "r")
590 (match_operand:SF 2 "gpr_operand" "r")))
591 (clobber (reg:CC_FP CCFP_REGNUM))])]
594 [(set_attr "type" "fp")])
596 (define_expand "subsf3_f"
598 [(set (reg:CC_FP CCFP_REGNUM)
599 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
600 (match_operand:SF 2 "gpr_operand" "r")))
601 (set (match_operand:SF 0 "gpr_operand" "=r")
602 (minus:SF (match_dup 1) (match_dup 2)))])]
603 "!TARGET_SOFT_CMPSF")
605 (define_insn "*subsf3_f_i"
606 [(match_parallel 3 "float_operation"
607 [(set (reg:CC_FP CCFP_REGNUM)
608 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
609 (match_operand:SF 2 "gpr_operand" "r")))
610 (set (match_operand:SF 0 "gpr_operand" "=r")
611 (minus:SF (match_dup 1) (match_dup 2)))])]
614 [(set_attr "type" "fp")])
616 ; There is an fabs instruction, but it has longer latency.
617 (define_expand "abssf2"
618 [(set (match_operand:SF 0 "gpr_operand" "")
619 (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
623 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
625 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
627 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
628 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
633 (define_expand "mulsf3"
635 [(set (match_operand:SF 0 "gpr_operand" "")
636 (mult:SF (match_operand:SF 1 "gpr_operand" "")
637 (match_operand:SF 2 "gpr_operand" "")))
638 (clobber (reg:CC_FP CCFP_REGNUM))])])
640 (define_insn "*mulsf3_i"
641 [(match_parallel 3 "float_operation"
642 [(set (match_operand:SF 0 "gpr_operand" "=r")
643 (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
644 (match_operand:SF 2 "gpr_operand" "r")))
645 (clobber (reg:CC_FP CCFP_REGNUM))])]
648 [(set_attr "type" "fp")])
651 (define_expand "divsf3"
652 [(set (match_operand:SF 0 "gpr_operand" "")
653 (div:SF (match_operand:SF 1 "gpr_operand" "")
654 (match_operand:SF 2 "gpr_operand" "")))]
655 "flag_reciprocal_math"
657 rtx one = CONST1_RTX (SFmode);
658 rtx dst = operands[0];
660 if (rtx_equal_p (dst, operands[1]))
662 emit_move_insn (dst, one);
665 else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
666 dst = gen_reg_rtx (SFmode);
667 emit_insn (gen_recipsf2 (dst, one, operands[2],
668 sfunc_symbol (\"__fast_recipsf2\")));
669 emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
673 ;; Before reload, keep the hard reg usage to clobbers so that the loop
674 ;; optimizers can more easily move this insn.
675 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
676 ;; but sched1 can still cause trouble then, and there is no guarantee of
677 ;; better register allocations.
678 ;; Neither is there when using the opposite strategy - putting explicit
679 ;; hard register references into pre-reload rtl.
680 (define_expand "recipsf2"
682 [(set (match_operand:SF 0 "gpr_operand" "")
683 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
684 (match_operand:SF 2 "move_src_operand" "")))
685 (use (match_operand:SI 3 "move_src_operand" ""))
688 (clobber (reg:SF GPR_IP))
689 (clobber (reg:DI GPR_16))
690 (clobber (reg:DI GPR_18))
691 (clobber (reg:SI GPR_20))
692 (clobber (reg:SI GPR_LR))
693 (clobber (reg:CC CC_REGNUM))
694 (clobber (reg:CC_FP CCFP_REGNUM))])])
696 (define_insn_and_split "*recipsf2_1"
697 [(match_parallel 4 "float_operation"
698 [(set (match_operand:SF 0 "gpr_operand" "=r,r")
699 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
700 (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
701 (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
704 (clobber (reg:SF GPR_IP))
705 (clobber (reg:DI GPR_16))
706 (clobber (reg:DI GPR_18))
707 (clobber (reg:SI GPR_20))
708 (clobber (reg:SI GPR_LR))
709 (clobber (reg:CC CC_REGNUM))
710 (clobber (reg:CC_FP CCFP_REGNUM))])]
711 "flag_reciprocal_math"
713 "&& reload_completed"
714 [(set (reg:SI 1) (match_dup 3))
715 (set (reg:SF 0) (match_dup 2))
718 (div:SF (match_dup 1)
721 (clobber (reg:SI GPR_IP))
722 (clobber (reg:DI GPR_16))
723 (clobber (reg:DI GPR_18))
724 (clobber (reg:SI GPR_20))
725 (clobber (reg:SI GPR_LR))
726 (clobber (reg:CC CC_REGNUM))
727 (clobber (reg:CC_FP CCFP_REGNUM))
730 (set (match_dup 0) (reg:SF 0))]
731 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
732 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
733 [(set_attr "type" "fp_sfunc")
734 (set_attr "length" "16,24")])
736 (define_insn "*recipsf2_2"
737 [(match_parallel 1 "float_operation"
739 (div:SF (match_operand:SF 0 "const_float_1_operand" "")
742 (clobber (reg:SI GPR_IP))
743 (clobber (reg:DI GPR_16))
744 (clobber (reg:DI GPR_18))
745 (clobber (reg:SI GPR_20))
746 (clobber (reg:SI GPR_LR))
747 (clobber (reg:CC CC_REGNUM))
748 (clobber (reg:CC_FP CCFP_REGNUM))])]
749 "flag_reciprocal_math"
751 [(set_attr "type" "fp_sfunc")])
754 ;; Fused multiply-add
755 (define_expand "fmasf4"
757 [(set (match_operand:SF 0 "gpr_operand" "")
758 (fma:SF (match_operand:SF 1 "gpr_operand" "")
759 (match_operand:SF 2 "gpr_operand" "")
760 (match_operand:SF 3 "gpr_operand" "")))
761 (clobber (reg:CC_FP CCFP_REGNUM))])]
764 ; The multiply operands are commutative, but since they have the
765 ; same constraints, there is no point in telling reload about this.
766 (define_insn "*fmadd"
767 [(match_parallel 4 "float_operation"
768 [(set (match_operand:SF 0 "gpr_operand" "=r")
769 (fma:SF (match_operand:SF 1 "gpr_operand" "r")
770 (match_operand:SF 2 "gpr_operand" "r")
771 (match_operand:SF 3 "gpr_operand" "0")))
772 (clobber (reg:CC_FP CCFP_REGNUM))])]
775 [(set_attr "type" "fp")])
777 ; Once vetorization consistently works for this port, should check
778 ; if the fmadd / fmsub patterns still serve a purpose. With the
779 ; introduction of fma / fnma handling by the SSA optimizers,
780 ; at least scalars should be handled by these optimizers, would
781 ; have to see how well they do on vectors from auto-vectorization.
783 ; combiner pattern, also used by vector combiner pattern
784 (define_expand "maddsf"
786 [(set (match_operand:SF 0 "gpr_operand" "=r")
787 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
788 (match_operand:SF 2 "gpr_operand" "r"))
789 (match_operand:SF 3 "gpr_operand" "0")))
790 (clobber (reg:CC_FP CCFP_REGNUM))])]
793 (define_insn "*maddsf_combine"
794 [(match_parallel 4 "float_operation"
795 [(set (match_operand:SF 0 "gpr_operand" "=r")
796 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
797 (match_operand:SF 2 "gpr_operand" "r"))
798 (match_operand:SF 3 "gpr_operand" "0")))
799 (clobber (reg:CC_FP CCFP_REGNUM))])]
802 [(set_attr "type" "fp")])
804 ;; Fused multiply-sub
805 (define_expand "fnmasf4"
807 [(set (match_operand:SF 0 "gpr_operand" "")
808 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
809 (match_operand:SF 2 "gpr_operand" "")
810 (match_operand:SF 3 "gpr_operand" "")))
811 (clobber (reg:CC_FP CCFP_REGNUM))])]
814 (define_insn "*fmsub"
815 [(match_parallel 4 "float_operation"
816 [(set (match_operand:SF 0 "gpr_operand" "=r")
817 (fma:SF (neg: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 (define_insn "*fmsub_combine"
826 [(match_parallel 4 "float_operation"
827 [(set (match_operand:SF 0 "gpr_operand" "=r")
828 (minus:SF (match_operand:SF 3 "gpr_operand" "0")
829 (mult:SF (match_operand:SF 1 "gpr_operand" "r")
830 (match_operand:SF 2 "gpr_operand" "r"))))
831 (clobber (reg:CC_FP CCFP_REGNUM))])]
834 [(set_attr "type" "fp")])
836 ;; float / integer conversions
838 (define_expand "floatsisf2"
840 [(set (match_operand:SF 0 "gpr_operand" "")
841 (float:SF (match_operand:SI 1 "gpr_operand" "")))
842 (clobber (reg:CC_FP CCFP_REGNUM))])])
844 (define_insn "*floatsisf2_i"
845 [(match_parallel 2 "float_operation"
846 [(set (match_operand:SF 0 "gpr_operand" "=r")
847 (float:SF (match_operand:SI 1 "gpr_operand" "r")))
848 (clobber (reg:CC_FP CCFP_REGNUM))])]
851 [(set_attr "type" "fp")])
853 (define_expand "floatsisf2_cmp"
855 [(set (reg:CC_FP CCFP_REGNUM)
856 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
858 (set (match_operand:SF 0 "gpr_operand" "=r")
859 (float:SF (match_dup 1)))])]
861 "operands[2] = CONST0_RTX (SFmode);")
863 (define_insn "*floatsisf2_cmp_i"
864 [(match_parallel 3 "float_operation"
865 [(set (reg:CC_FP CCFP_REGNUM)
866 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
867 (match_operand:SF 2 "const0_operand" "")))
868 (set (match_operand:SF 0 "gpr_operand" "=r")
869 (float:SF (match_dup 1)))])]
872 [(set_attr "type" "fp")])
874 (define_expand "floatunssisf2"
875 [(set (match_operand:SF 0 "gpr_operand" "")
876 (float:SF (match_operand:SI 1 "gpr_operand" "")))]
877 "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
879 rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
880 rtx tmp = gen_reg_rtx (SImode);
881 rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
883 if (reg_overlap_mentioned_p (operands[0], operands[1]))
884 operands[1] = copy_to_mode_reg (SImode, operands[1]);
885 emit_insn (gen_floatsisf2 (operands[0], operands[1]));
886 emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
887 emit_insn (gen_sub_f (tmp, tmp, cst));
888 emit_insn (gen_movsfcc (operands[0], cmp,
889 simplify_gen_subreg (SFmode, tmp, SImode, 0),
894 (define_expand "fix_truncsfsi2"
896 [(set (match_operand:SI 0 "gpr_operand" "")
897 (fix:SI (match_operand:SF 1 "gpr_operand" "")))
898 (clobber (reg:CC_FP CCFP_REGNUM))])])
900 (define_insn "*fix_truncsfsi2_i"
901 [(match_parallel 2 "float_operation"
902 [(set (match_operand:SI 0 "gpr_operand" "=r")
903 (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
904 (clobber (reg:CC_FP CCFP_REGNUM))])]
907 [(set_attr "type" "fp")
908 (set_attr "fp_mode" "round_trunc")])
910 (define_expand "fixuns_truncsfsi2"
911 [(set (match_operand:SI 0 "gpr_operand" "")
912 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
915 if (reg_overlap_mentioned_p (operands[0], operands[1]))
916 operands[1] = copy_to_mode_reg (SImode, operands[1]);
917 if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
920 /* By toggling what it to be bit31 before the shift, we get a chance to
921 use a short movt insn. */
922 rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
923 rtx tmp = gen_reg_rtx (SImode);
924 rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
926 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
928 op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
929 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
930 emit_insn (gen_subsi3 (tmp, op1si, bit31));
931 emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
932 emit_insn (gen_cmpsi_cc_insn (op1si, limit));
933 emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
937 REAL_VALUE_TYPE offset;
939 rtx tmp = gen_reg_rtx (SFmode);
940 rtx label = gen_label_rtx ();
942 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
943 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
945 real_2expN (&offset, 31, SFmode);
946 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode);
947 limit = force_reg (SFmode, limit);
948 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
949 emit_insn (gen_subsf3_f (tmp, operands[1], limit));
950 emit_jump_insn (gen_branch_insn (label, cmp, cc1));
951 bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
952 emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
953 emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
960 [(match_parallel 3 "float_operation"
961 [(set (match_operand:SI 0 "gpr_operand" "=r")
962 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
963 (match_operand:SI 2 "gpr_operand" "r")))
964 (clobber (reg:CC_FP CCFP_REGNUM))])]
967 [(set_attr "type" "fp_int")])
970 [(match_parallel 3 "float_operation"
971 [(set (match_operand:SI 0 "gpr_operand" "=r")
972 (minus:SI (match_operand:SI 1 "gpr_operand" "r")
973 (match_operand:SI 2 "gpr_operand" "r")))
974 (clobber (reg:CC_FP CCFP_REGNUM))])]
977 [(set_attr "type" "fp_int")])
979 (define_expand "mulsi3"
981 [(set (match_operand:SI 0 "gpr_operand" "")
982 (mult:SI (match_operand:SI 1 "gpr_operand" "")
983 (match_operand:SI 2 "gpr_operand" "")))
984 (clobber (reg:CC_FP CCFP_REGNUM))])])
987 [(match_parallel 3 "float_operation"
988 [(set (match_operand:SI 0 "gpr_operand" "=r")
989 (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
990 (match_operand:SI 2 "gpr_operand" "r")))
991 (clobber (reg:CC_FP CCFP_REGNUM))])]
994 [(set_attr "type" "fp_int")])
996 ; combiner pattern, also used by vector combiner pattern
997 (define_expand "maddsi"
999 [(set (match_operand:SI 0 "gpr_operand" "=r")
1000 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1001 (match_operand:SI 2 "gpr_operand" "r"))
1002 (match_operand:SI 3 "gpr_operand" "0")))
1003 (clobber (reg:CC_FP CCFP_REGNUM))])]
1006 (define_insn "*maddsi_combine"
1007 [(match_parallel 4 "float_operation"
1008 [(set (match_operand:SI 0 "gpr_operand" "=r")
1009 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1010 (match_operand:SI 2 "gpr_operand" "r"))
1011 (match_operand:SI 3 "gpr_operand" "0")))
1012 (clobber (reg:CC_FP CCFP_REGNUM))])]
1015 [(set_attr "type" "fp_int")])
1017 (define_insn "*imsub"
1018 [(match_parallel 4 "float_operation"
1019 [(set (match_operand:SI 0 "gpr_operand" "=r")
1020 (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1021 (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1022 (match_operand:SI 2 "gpr_operand" "r"))))
1023 (clobber (reg:CC_FP CCFP_REGNUM))])]
1026 [(set_attr "type" "fp_int")])
1028 (define_expand "divsi3"
1030 [(set (match_operand:SI 0 "move_dest_operand" "")
1031 (div:SI (match_operand:SI 1 "move_src_operand" "")
1032 (match_operand:SI 2 "move_src_operand" "")))
1034 (clobber (reg:SI 0))
1035 (clobber (reg:SI 1))
1036 (clobber (reg:SI GPR_IP))
1037 (clobber (reg:DI GPR_16))
1038 (clobber (reg:DI GPR_18))
1039 (clobber (reg:SI GPR_20))
1040 (clobber (reg:SI GPR_LR))
1041 (clobber (reg:CC CC_REGNUM))
1042 (clobber (reg:CC_FP CCFP_REGNUM))])]
1044 "operands[3] = sfunc_symbol (\"__divsi3\");")
1046 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1047 ;; optimizers can more easily move this insn.
1048 (define_insn_and_split "*divsi3_1"
1049 [(match_parallel 4 "float_operation"
1050 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1051 (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1052 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1053 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1054 (clobber (reg:SI 0))
1055 (clobber (reg:SI 1))
1056 (clobber (reg:SI GPR_IP))
1057 (clobber (reg:DI GPR_16))
1058 (clobber (reg:DI GPR_18))
1059 (clobber (reg:SI GPR_20))
1060 (clobber (reg:SI GPR_LR))
1061 (clobber (reg:CC CC_REGNUM))
1062 (clobber (reg:CC_FP CCFP_REGNUM))])]
1065 "&& reload_completed"
1066 [(set (reg:SI 0) (match_dup 1))
1067 (set (reg:SI 1) (match_dup 2))
1069 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1071 (clobber (reg:SI 1))
1072 (clobber (reg:SI GPR_IP))
1073 (clobber (reg:DI GPR_16))
1074 (clobber (reg:DI GPR_18))
1075 (clobber (reg:SI GPR_20))
1076 (clobber (reg:SI GPR_LR))
1077 (clobber (reg:CC CC_REGNUM))
1078 (clobber (reg:CC_FP CCFP_REGNUM))
1081 (set (match_dup 0) (reg:SI 0))]
1082 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1083 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1084 [(set_attr "type" "fp_sfunc")
1085 (set_attr "length" "16,24")])
1087 (define_insn "*divsi3_2"
1088 [(match_parallel 1 "float_operation"
1089 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1090 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1091 (clobber (reg:SI 1))
1092 (clobber (reg:SI GPR_IP))
1093 (clobber (reg:DI GPR_16))
1094 (clobber (reg:DI GPR_18))
1095 (clobber (reg:SI GPR_20))
1096 (clobber (reg:SI GPR_LR))
1097 (clobber (reg:CC CC_REGNUM))
1098 (clobber (reg:CC_FP CCFP_REGNUM))])]
1101 [(set_attr "type" "fp_sfunc")])
1103 (define_expand "udivsi3"
1105 [(set (match_operand:SI 0 "move_dest_operand" "")
1106 (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1107 (match_operand:SI 2 "move_src_operand" "")))
1109 (clobber (reg:SI 0))
1110 (clobber (reg:SI 1))
1111 (clobber (reg:SI GPR_IP))
1112 (clobber (reg:DI GPR_16))
1113 (clobber (reg:SI GPR_18))
1114 (clobber (reg:SI GPR_LR))
1115 (clobber (reg:CC CC_REGNUM))
1116 (clobber (reg:CC_FP CCFP_REGNUM))])]
1118 "operands[3] = sfunc_symbol (\"__udivsi3\");")
1120 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1121 ;; optimizers can more easily move this insn.
1122 (define_insn_and_split "*udivsi3_1"
1123 [(match_parallel 4 "float_operation"
1124 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1125 (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1126 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1127 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1128 (clobber (reg:SI 0))
1129 (clobber (reg:SI 1))
1130 (clobber (reg:SI GPR_IP))
1131 (clobber (reg:DI GPR_16))
1132 (clobber (reg:SI GPR_18))
1133 (clobber (reg:SI GPR_LR))
1134 (clobber (reg:CC CC_REGNUM))
1135 (clobber (reg:CC_FP CCFP_REGNUM))])]
1138 "&& reload_completed"
1139 [(set (reg:SI 0) (match_dup 1))
1140 (set (reg:SI 1) (match_dup 2))
1142 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1144 (clobber (reg:SI 1))
1145 (clobber (reg:SI GPR_IP))
1146 (clobber (reg:DI GPR_16))
1147 (clobber (reg:SI GPR_18))
1148 (clobber (reg:SI GPR_LR))
1149 (clobber (reg:CC CC_REGNUM))
1150 (clobber (reg:CC_FP CCFP_REGNUM))
1153 (set (match_dup 0) (reg:SI 0))]
1154 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1155 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1156 [(set_attr "type" "fp_sfunc")
1157 (set_attr "length" "16,24")])
1159 (define_insn "*udivsi3_2"
1160 [(match_parallel 1 "float_operation"
1161 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1162 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1163 (clobber (reg:SI 1))
1164 (clobber (reg:SI GPR_IP))
1165 (clobber (reg:DI GPR_16))
1166 (clobber (reg:SI GPR_18))
1167 (clobber (reg:SI GPR_LR))
1168 (clobber (reg:CC CC_REGNUM))
1169 (clobber (reg:CC_FP CCFP_REGNUM))])]
1172 [(set_attr "type" "fp_sfunc")])
1174 (define_expand "modsi3"
1176 [(set (match_operand:SI 0 "move_dest_operand" "")
1177 (mod:SI (match_operand:SI 1 "move_src_operand" "")
1178 (match_operand:SI 2 "move_src_operand" "")))
1180 (clobber (reg:SI 0))
1181 (clobber (reg:SI 1))
1182 (clobber (reg:SI 2))
1183 (clobber (reg:SI GPR_IP))
1184 (clobber (reg:DI GPR_16))
1185 (clobber (reg:DI GPR_18))
1186 (clobber (reg:SI GPR_LR))
1187 (clobber (reg:CC CC_REGNUM))
1188 (clobber (reg:CC_FP CCFP_REGNUM))])]
1190 "operands[3] = sfunc_symbol (\"__modsi3\");")
1192 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1193 ;; optimizers can more easily move this insn.
1194 (define_insn_and_split "*modsi3_1"
1195 [(match_parallel 4 "float_operation"
1196 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1197 (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1198 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1199 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1200 (clobber (reg:SI 0))
1201 (clobber (reg:SI 1))
1202 (clobber (reg:SI 2))
1203 (clobber (reg:SI GPR_IP))
1204 (clobber (reg:DI GPR_16))
1205 (clobber (reg:DI GPR_18))
1206 (clobber (reg:SI GPR_LR))
1207 (clobber (reg:CC CC_REGNUM))
1208 (clobber (reg:CC_FP CCFP_REGNUM))])]
1211 "&& reload_completed"
1212 [(set (reg:SI 0) (match_dup 1))
1213 (set (reg:SI 1) (match_dup 2))
1215 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1217 (clobber (reg:SI 2))
1218 (clobber (reg:SI GPR_IP))
1219 (clobber (reg:DI GPR_16))
1220 (clobber (reg:DI GPR_18))
1221 (clobber (reg:SI GPR_LR))
1222 (clobber (reg:CC CC_REGNUM))
1223 (clobber (reg:CC_FP CCFP_REGNUM))
1226 (set (match_dup 0) (reg:SI 0))]
1227 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1228 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1229 [(set_attr "type" "fp_sfunc")
1230 (set_attr "length" "16,24")])
1232 (define_insn "*modsi3_2"
1233 [(match_parallel 1 "float_operation"
1234 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1235 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1236 (clobber (reg:SI 2))
1237 (clobber (reg:SI GPR_IP))
1238 (clobber (reg:DI GPR_16))
1239 (clobber (reg:DI GPR_18))
1240 (clobber (reg:SI GPR_LR))
1241 (clobber (reg:CC CC_REGNUM))
1242 (clobber (reg:CC_FP CCFP_REGNUM))])]
1245 [(set_attr "type" "fp_sfunc")])
1247 (define_expand "umodsi3"
1249 [(set (match_operand:SI 0 "move_dest_operand" "")
1250 (umod:SI (match_operand:SI 1 "move_src_operand" "")
1251 (match_operand:SI 2 "move_src_operand" "")))
1253 (clobber (reg:SI 0))
1254 (clobber (reg:SI 1))
1255 (clobber (reg:SI 2))
1256 (clobber (reg:SI GPR_IP))
1257 (clobber (reg:DI GPR_16))
1258 (clobber (reg:SI GPR_LR))
1259 (clobber (reg:CC CC_REGNUM))
1260 (clobber (reg:CC_FP CCFP_REGNUM))])]
1262 "operands[3] = sfunc_symbol (\"__umodsi3\");")
1264 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1265 ;; optimizers can more easily move this insn.
1266 (define_insn_and_split "*umodsi3_1"
1267 [(match_parallel 4 "float_operation"
1268 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1269 (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1270 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1271 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1272 (clobber (reg:SI 0))
1273 (clobber (reg:SI 1))
1274 (clobber (reg:SI 2))
1275 (clobber (reg:SI GPR_IP))
1276 (clobber (reg:DI GPR_16))
1277 (clobber (reg:SI GPR_LR))
1278 (clobber (reg:CC CC_REGNUM))
1279 (clobber (reg:CC_FP CCFP_REGNUM))])]
1282 "&& reload_completed"
1283 [(set (reg:SI 0) (match_dup 1))
1284 (set (reg:SI 1) (match_dup 2))
1286 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1288 (clobber (reg:SI 2))
1289 (clobber (reg:SI GPR_IP))
1290 (clobber (reg:DI GPR_16))
1291 (clobber (reg:SI GPR_LR))
1292 (clobber (reg:CC CC_REGNUM))
1293 (clobber (reg:CC_FP CCFP_REGNUM))
1296 (set (match_dup 0) (reg:SI 0))]
1297 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1298 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1299 [(set_attr "type" "fp_sfunc")
1300 (set_attr "length" "16,24")])
1302 (define_insn "*umodsi3_2"
1303 [(match_parallel 1 "float_operation"
1304 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1305 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1306 (clobber (reg:SI 2))
1307 (clobber (reg:SI GPR_IP))
1308 (clobber (reg:DI GPR_16))
1309 (clobber (reg:SI GPR_LR))
1310 (clobber (reg:CC CC_REGNUM))
1311 (clobber (reg:CC_FP CCFP_REGNUM))])]
1314 [(set_attr "type" "fp_sfunc")])
1316 ; Disable interrupts.
1317 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1318 ; might have changed settings that we do not want to mess with.
1320 [(set (reg:SI CONFIG_REGNUM)
1321 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1324 [(set_attr "type" "flow")])
1326 ; Enable interrupts.
1327 ; Present CONTROL_REGNUM here to make sure it is live before the
1328 ; actual uses in floating point insns / calls are inserted.
1329 ; FWIW, interrupts also do mind what is in the control register.
1331 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1334 [(set_attr "type" "flow")])
1336 ; Floating point instructions require manipulating the control register.
1337 ; Manipulating the control register needs aritmetic.
1338 ; Arithmetic clobbers flags.
1339 ; The flags are in the status register, which also contains the alternate
1340 ; flag and the interrupt enable/disable bits.
1341 ; saving/restoring status and mixing up the order with gid/gie could
1343 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1344 ; away. But when we really need it, we must make sure that we don't change
1345 ; anything but the flags.
1346 ; N.B.: We could make the constant easier to load by inverting it, but
1347 ; then we'd need to clobber the saved value - and that would make optimizing
1348 ; away unneeded saves/restores harder / less likely.
1349 (define_expand "movcc"
1350 [(parallel [(set (match_operand:CC 0 "cc_move_operand" "")
1351 (match_operand:CC 1 "cc_move_operand" ""))
1353 (clobber (match_scratch:SI 3 "=X, &r"))])]
1355 "operands[2] = gen_int_mode (~0x10f0, SImode);")
1357 (define_insn "*movcc_i"
1358 [(set (match_operand:CC 0 "cc_move_operand" "=r,Rcc")
1359 (match_operand:CC 1 "cc_move_operand" "Rcc, r"))
1360 (use (match_operand:SI 2 "nonmemory_operand" "X, r"))
1361 (clobber (match_scratch:SI 3 "=X, &r"))]
1365 movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1366 [(set_attr "type" "flow")
1367 (set_attr "length" "20,4")])
1369 (define_insn_and_split "set_fp_mode"
1370 [(set (reg:SI FP_NEAREST_REGNUM)
1371 (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1372 (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1373 (set (reg:SI FP_ANYFP_REGNUM)
1374 (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1375 (use (match_operand:SI 2 "gpr_operand" "r"))
1376 (clobber (reg:CC CC_REGNUM))
1377 (clobber (match_scratch:SI 3 "=&r"))]
1380 "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1383 if (!reload_completed)
1384 emit_note (NOTE_INSN_DELETED);
1386 epiphany_expand_set_fp_mode (operands);
1391 ;; Boolean instructions.
1393 ;; We don't define the DImode versions as expand_binop does a good enough job.
1395 (define_insn "andsi3"
1396 [(set (match_operand:SI 0 "gpr_operand" "=r")
1397 (and:SI (match_operand:SI 1 "gpr_operand" "r")
1398 (match_operand:SI 2 "gpr_operand" "r")))
1399 (clobber (reg:CC CC_REGNUM))]
1403 (define_insn "iorsi3"
1404 [(set (match_operand:SI 0 "gpr_operand" "=r")
1405 (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1406 (match_operand:SI 2 "gpr_operand" "r")))
1407 (clobber (reg:CC CC_REGNUM))]
1411 (define_insn "xorsi3"
1412 [(set (match_operand:SI 0 "gpr_operand" "=r")
1413 (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1414 (match_operand:SI 2 "gpr_operand" "r")))
1415 (clobber (reg:CC CC_REGNUM))]
1419 (define_expand "one_cmplsi2"
1420 [(set (match_operand:SI 0 "gpr_operand" "")
1421 (xor:SI (match_operand:SI 1 "gpr_operand" "")
1425 if (epiphany_m1reg >= 0)
1426 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1428 emit_insn (gen_xorsi3 (operands[0], operands[1],
1429 force_reg (SImode, GEN_INT (-1))));
1433 ; Note that folding this pattern into the xorsi3 pattern would make combine
1435 (define_insn "one_cmplsi2_i"
1436 [(set (match_operand:SI 0 "gpr_operand" "=r")
1437 (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1438 (clobber (reg:CC CC_REGNUM))]
1439 "epiphany_m1reg >= 0"
1442 ;; Shift instructions.
1443 ;; In principle we could support arbitrary symbolic values as shift constant
1444 ;; (truncating the value appropriately), but that would require a suitable
1445 ;; relocation and assembler & linker support.
1446 (define_insn "ashrsi3"
1447 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1448 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1449 (match_operand:SI 2 "arith_operand" "r,K")))
1450 (clobber (reg:CC CC_REGNUM))]
1453 [(set_attr "length" "4")
1454 (set_attr "type" "shift")])
1456 (define_insn "ashrsi3_tst"
1457 [(set (reg:CC CC_REGNUM)
1459 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1460 (match_operand:SI 2 "arith_operand" "r,K"))
1462 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1463 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1466 [(set_attr "length" "4")
1467 (set_attr "type" "shift")])
1469 ;; Logical Shift Right
1470 (define_insn "lshrsi3"
1471 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1472 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1473 (match_operand:SI 2 "arith_operand" "r,K")))
1474 (clobber (reg:CC CC_REGNUM))]
1477 [(set_attr "length" "4")
1478 (set_attr "type" "shift")])
1480 (define_insn "lshrsi3_tst"
1481 [(set (reg:CC CC_REGNUM)
1483 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1484 (match_operand:SI 2 "arith_operand" "r,K"))
1486 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1487 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1490 [(set_attr "length" "4")
1491 (set_attr "type" "shift")])
1493 ;; Logical/Arithmetic Shift Left
1494 (define_insn "ashlsi3"
1495 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1496 (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1497 (match_operand:SI 2 "arith_operand" "r,K")))
1498 (clobber (reg:CC CC_REGNUM))]
1501 [(set_attr "length" "4")
1502 (set_attr "type" "shift")])
1504 (define_insn "*ashlsi_btst"
1505 [(set (reg:CC_N_NE CC_REGNUM)
1507 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1509 (match_operand 2 "const_int_operand" "K"))
1511 (clobber (match_scratch:SI 0 "=r"))]
1516 xop[0] = operands[0];
1517 xop[1] = operands[1];
1518 xop[2] = GEN_INT (31-INTVAL (operands[2]));
1519 output_asm_insn ("lsl %0,%1,%2", xop);
1524 (define_insn_and_split "zero_extendqisi2"
1525 [(set (match_operand:SI 0 "register_operand" "=r,r")
1526 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1527 (clobber (reg:CC CC_REGNUM))]
1533 ? true_regnum (operands[1]) >= 0
1534 : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1535 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1536 (clobber (reg:CC CC_REGNUM))])
1537 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1538 (clobber (reg:CC CC_REGNUM))])]
1539 "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1541 (define_insn "zero_extendhisi2"
1542 [(set (match_operand:SI 0 "register_operand" "=r,r")
1543 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1550 ;; Compare instructions.
1552 (define_insn "cmpsi_cc_insn"
1553 [(set (reg:CC CC_REGNUM)
1554 (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1555 (match_operand:SI 1 "arith_operand" "r,L")))
1556 (clobber (match_scratch:SI 2 "=r,r"))]
1559 [(set_attr "type" "compare")])
1561 (define_insn "sub_f"
1562 [(set (reg:CC CC_REGNUM)
1563 (compare:CC (match_operand:SI 1 "gpr_operand" "r,r")
1564 (match_operand:SI 2 "arith_operand" "r,L")))
1565 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1566 (minus:SI (match_dup 1) (match_dup 2)))]
1569 [(set_attr "type" "compare")])
1571 (define_insn "*sub_f_add_imm"
1572 [(set (reg:CC CC_REGNUM)
1573 (compare:CC (match_operand:SI 1 "gpr_operand" "r")
1574 (match_operand:SI 2 "arith_int_operand" "L")))
1575 (set (match_operand:SI 0 "gpr_operand" "=r")
1576 (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "L")))]
1577 "INTVAL (operands[2]) == -INTVAL (operands[3])"
1579 [(set_attr "type" "compare")])
1581 (define_expand "abssi2"
1582 [(set (match_dup 2) (const_int 0))
1583 (parallel [(set (reg:CC CC_REGNUM)
1584 (compare:CC (match_dup 2)
1585 (match_operand:SI 1 "nonmemory_operand" "")))
1587 (minus:SI (match_dup 2) (match_dup 1)))])
1588 (set (match_operand:SI 0 "gpr_operand" "=r")
1589 (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1593 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1595 (define_insn "*add_c"
1596 [(set (reg:CC_C_LTU CC_REGNUM)
1598 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1599 (match_operand:SI 2 "arith_operand" "r,L"))
1601 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1602 (plus:SI (match_dup 1) (match_dup 2)))]
1605 [(set_attr "type" "compare")])
1607 (define_insn "*add_c_rev"
1608 [(set (reg:CC_C_LTU CC_REGNUM)
1610 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1611 (match_operand:SI 2 "arith_operand" "r,L"))
1613 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1614 (plus:SI (match_dup 2) (match_dup 1)))]
1617 [(set_attr "type" "compare")])
1619 (define_insn "*sub_c"
1620 [(set (reg:CC_C_GTU CC_REGNUM)
1622 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1623 (match_operand:SI 2 "arith_operand" "r,L"))
1625 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1626 (minus:SI (match_dup 1) (match_dup 2)))]
1629 [(set_attr "type" "compare")])
1631 (define_insn "*sub_c_void"
1632 [(set (reg:CC_C_GTU CC_REGNUM)
1634 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1635 (match_operand:SI 2 "arith_operand" "r,L"))
1637 (clobber (match_scratch:SI 0 "=r,r"))]
1640 [(set_attr "type" "compare")])
1642 ; floating point comparisons
1644 (define_insn "*cmpsf_cc_insn"
1645 [(match_parallel 3 "float_operation"
1646 [(set (reg:CC_FP CCFP_REGNUM)
1647 (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1648 (match_operand:SF 1 "gpr_operand" "r")))
1649 (clobber (match_scratch:SF 2 "=r"))])]
1650 "!TARGET_SOFT_CMPSF"
1652 [(set_attr "type" "fp")
1653 (set_attr "fp_mode" "round_unknown")])
1655 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1656 ;; to allow the rtl loop optimizer to generate comparisons? OTOH
1657 ;; we want call_address_operand to enforce valid operands so that
1658 ;; combine won't do silly things, allowing instruction scheduling to do
1660 (define_insn "*cmpsf_eq"
1661 [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (reg:SF 0) (reg:SF 1)))
1662 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1663 (clobber (reg:SI GPR_IP))
1664 (clobber (reg:SI GPR_LR))]
1667 [(set_attr "type" "sfunc")])
1669 (define_insn "*cmpsf_gte"
1670 [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (reg:SF 0) (reg:SF 1)))
1671 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1672 (clobber (reg:SI GPR_IP))
1673 (clobber (reg:SI GPR_LR))]
1676 [(set_attr "type" "sfunc")])
1678 (define_insn "*cmpsf_ord"
1679 [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1680 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1681 (clobber (reg:SI GPR_IP))
1682 (clobber (reg:SI GPR_16))
1683 (clobber (reg:SI GPR_LR))]
1686 [(set_attr "type" "sfunc")])
1688 (define_insn "*cmpsf_uneq"
1689 [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1690 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1691 (clobber (reg:SI GPR_IP))
1692 (clobber (reg:SI GPR_16))
1693 (clobber (reg:SI GPR_LR))]
1696 [(set_attr "type" "sfunc")])
1698 ;; conditional moves
1700 (define_expand "mov<mode>cc"
1701 [(set (match_operand:WMODE 0 "gpr_operand" "")
1702 (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1703 (match_operand:WMODE 2 "gpr_operand" "")
1704 (match_operand:WMODE 3 "gpr_operand" "")))]
1707 rtx cmp_op0 = XEXP (operands[1], 0);
1708 rtx cmp_op1 = XEXP (operands[1], 1);
1709 enum machine_mode cmp_in_mode;
1710 enum rtx_code code = GET_CODE (operands[1]);
1712 cmp_in_mode = GET_MODE (cmp_op0);
1713 if (cmp_in_mode == VOIDmode)
1714 cmp_in_mode = GET_MODE (cmp_op0);
1715 if (cmp_in_mode == VOIDmode)
1716 cmp_in_mode = SImode;
1717 /* If the operands are a better match when reversed, swap them now.
1718 This allows combine to see the proper comparison codes. */
1719 if (rtx_equal_p (operands[0], operands[2])
1720 && !rtx_equal_p (operands[0], operands[3]))
1722 rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1723 code = (FLOAT_MODE_P (GET_MODE (cmp_op0))
1724 ? reverse_condition_maybe_unordered (code)
1725 : reverse_condition (code));
1728 if (proper_comparison_operator (operands[1], VOIDmode))
1729 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1732 if (!currently_expanding_to_rtl)
1734 /* ??? It would seem safest to FAIL here, but that would defeat
1735 the purpose of having an if-conversion pass; its logic currently
1736 assumes that the backend should be safe to insert condition code
1737 setting instructions, as the same condition codes were presumably
1738 set by the if-conversion input code. */
1740 /* What mode to give as first operand to gen_compare_reg here is
1741 debatable. VOIDmode would be minimalist; telling gen_compare_reg
1742 to use the mode of CC_REGNUM (or putting it on the comparison
1743 operator afterwards) is also a logical choice. OTOH, by using
1744 <MODE>mode, we have mode combine opportunities with flag setting
1745 operations - if we get some. */
1747 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1751 (define_insn "*mov<mode>cc_insn"
1752 [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1753 (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1754 [(match_operand 4 "cc_operand") (const_int 0)])
1755 (match_operand:WMODE 1 "gpr_operand" "r")
1756 (match_operand:WMODE 2 "gpr_operand" "0")))]
1759 [(set_attr "type" "cmove")])
1762 [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
1763 (match_operand:WMODE 1 "" ""))
1764 (clobber (match_operand 8 "cc_operand"))])
1765 (match_operand 2 "" "")
1766 (set (match_operand:WMODE2 3 "gpr_operand" "")
1767 (match_operand:WMODE2 9 "gpr_operand" ""))
1769 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1770 [(match_operand 6 "cc_operand")
1771 (match_operand 7 "const0_operand")])
1772 (match_operand:WMODE2 4 "nonmemory_operand" "")
1774 "REGNO (operands[0]) == REGNO (operands[9])
1775 && peep2_reg_dead_p (3, operands[0])
1776 && !reg_set_p (operands[0], operands[2])
1777 && !reg_set_p (operands[3], operands[2])
1778 && !reg_overlap_mentioned_p (operands[3], operands[2])"
1779 [(parallel [(set (match_dup 10) (match_dup 1))
1780 (clobber (match_dup 8))])
1783 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1785 operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1786 <WMODE2:MODE>mode, 0);
1787 replace_rtx (operands[2], operands[9], operands[3]);
1788 replace_rtx (operands[2], operands[0], operands[10]);
1789 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
1793 [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
1794 (set (match_operand:WMODE 0 "gpr_operand" "")
1795 (match_operand:WMODE 1 "" ""))])
1796 (set (match_operand:WMODE2 3 "gpr_operand" "")
1797 (match_operand:WMODE2 4 "gpr_operand"))
1799 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1801 (match_operand:WMODE 7 "const0_operand")])
1802 (match_operand:WMODE2 8 "gpr_operand")
1804 "REGNO (operands[0]) == REGNO (operands[8])
1805 && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
1806 && peep2_reg_dead_p (3, operands[6])
1807 && peep2_reg_dead_p (3, operands[0])
1808 && !reg_overlap_mentioned_p (operands[4], operands[3])"
1809 [(parallel [(set (match_dup 6) (match_dup 2))
1810 (set (match_dup 9) (match_dup 1))])
1812 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1816 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
1817 GET_MODE (operands[6])),
1818 GET_MODE (operands[5]), operands[6], operands[7]);
1819 operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1820 <WMODE2:MODE>mode, 0);
1823 ;; These control RTL generation for conditional jump insns
1825 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
1826 ;; they must allow const0_rtx for both comparison operands
1827 (define_expand "cbranchsi4"
1828 [(set (reg CC_REGNUM)
1829 (compare (match_operand:SI 1 "add_operand" "")
1830 (match_operand:SI 2 "arith_operand" "")))
1833 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
1835 (label_ref (match_operand 3 "" ""))
1839 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
1840 operands[1], operands[2]);
1841 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1845 (define_expand "cbranchsf4"
1846 [(set (reg CC_REGNUM)
1847 (compare (match_operand:SF 1 "arith_operand" "")
1848 (match_operand:SF 2 "arith_operand" "")))
1851 (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
1853 (label_ref (match_operand 3 "" ""))
1857 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
1858 operands[1], operands[2]);
1859 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1863 ;; Now match both normal and inverted jump.
1865 (define_insn "branch_insn"
1867 (if_then_else (match_operator 1 "proper_comparison_operator"
1868 [(match_operand 2 "cc_operand")
1870 (label_ref (match_operand 0 "" ""))
1874 [(set_attr "type" "branch")])
1876 (define_insn "*rev_branch_insn"
1878 (if_then_else (match_operator 1 "proper_comparison_operator"
1879 [(reg CC_REGNUM) (const_int 0)])
1881 (label_ref (match_operand 0 "" ""))))]
1884 [(set_attr "type" "branch")])
1886 ;; Unconditional and other jump instructions.
1889 [(set (pc) (label_ref (match_operand 0 "" "")))]
1892 [(set_attr "type" "uncond_branch")])
1894 (define_insn "indirect_jump"
1895 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
1898 [(set_attr "type" "uncond_branch")])
1900 (define_expand "tablejump"
1901 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
1902 (use (label_ref (match_operand 1 "" "")))])]
1905 /* In PIC mode, the table entries are stored PC relative.
1906 Convert the relative address to an absolute address. */
1909 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1911 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1912 op1, NULL_RTX, 0, OPTAB_DIRECT);
1916 (define_insn "*tablejump_internal"
1917 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
1918 (use (label_ref (match_operand 1 "" "")))]
1921 [(set_attr "type" "uncond_branch")])
1923 (define_insn "*tablejump_hi_internal"
1924 [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
1925 (use (label_ref (match_operand 1 "" "")))]
1926 "optimize_size && TARGET_SMALL16"
1928 [(set_attr "type" "uncond_branch")])
1931 (define_expand "call"
1932 ;; operands[1] is stack_size_rtx
1933 ;; operands[2] is next_arg_register
1934 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1935 (match_operand 1 "" ""))
1936 (clobber (reg:SI GPR_LR))])]
1939 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
1941 if (!call_operand (operands[1], VOIDmode))
1943 = change_address (operands[0], VOIDmode,
1944 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
1945 if (epiphany_uninterruptible_p (current_function_decl)
1946 != target_uninterruptible)
1948 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
1952 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
1953 gen_rtx_CLOBBER (VOIDmode,
1954 gen_rtx_REG (SImode, GPR_LR)))));
1955 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
1960 (define_insn "*call_i"
1961 [(match_parallel 2 "float_operation"
1962 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
1963 (match_operand 1 "" ""))
1964 (clobber (reg:SI GPR_LR))])]
1967 [(set_attr "type" "call")])
1969 (define_expand "sibcall"
1970 ;; operands[1] is stack_size_rtx
1971 ;; operands[2] is next_arg_register
1972 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1973 (match_operand 1 "" ""))
1977 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
1979 if (!call_operand (operands[1], VOIDmode))
1981 = change_address (operands[0], VOIDmode,
1982 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
1983 if (epiphany_uninterruptible_p (current_function_decl)
1984 != target_uninterruptible)
1986 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
1990 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
1992 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
1997 (define_insn "*sibcall_i"
1998 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
1999 (match_operand 1 "" ""))
2005 [(set_attr "type" "call")])
2007 (define_expand "call_value"
2008 ;; operand 2 is stack_size_rtx
2009 ;; operand 3 is next_arg_register
2010 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2011 (call (match_operand:SI 1 "call_operand" "")
2012 (match_operand 2 "" "")))
2013 (clobber (reg:SI GPR_LR))])]
2016 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2018 if (!call_operand (operands[1], VOIDmode))
2020 = change_address (operands[1], VOIDmode,
2021 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2022 if (epiphany_uninterruptible_p (current_function_decl)
2023 != target_uninterruptible)
2025 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2029 gen_rtvec (2, gen_rtx_SET
2030 (VOIDmode, operands[0],
2031 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2032 gen_rtx_CLOBBER (VOIDmode,
2033 gen_rtx_REG (SImode, GPR_LR)))));
2034 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2039 (define_insn "*call_value_i"
2040 [(match_parallel 3 "float_operation"
2041 [(set (match_operand 0 "gpr_operand" "=r,r")
2042 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2043 (match_operand 2 "" "")))
2044 (clobber (reg:SI GPR_LR))])]
2047 [(set_attr "type" "call")
2048 (set_attr "length" "4")])
2050 (define_expand "sibcall_value"
2051 ;; operand 2 is stack_size_rtx
2052 ;; operand 3 is next_arg_register
2053 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2054 (call (match_operand:SI 1 "call_operand" "")
2055 (match_operand 2 "" "")))
2059 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2061 if (!call_operand (operands[1], VOIDmode))
2063 = change_address (operands[1], VOIDmode,
2064 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2065 if (epiphany_uninterruptible_p (current_function_decl)
2066 != target_uninterruptible)
2068 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2072 gen_rtvec (2, gen_rtx_SET
2073 (VOIDmode, operands[0],
2074 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2076 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2081 (define_insn "*sibcall_value_i"
2082 [(set (match_operand 0 "gpr_operand" "=r,r")
2083 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2084 (match_operand 2 "" "")))
2090 [(set_attr "type" "call")
2091 (set_attr "length" "4")])
2093 (define_expand "prologue"
2097 epiphany_expand_prologue ();
2101 (define_expand "epilogue"
2105 epiphany_expand_epilogue (0);
2109 (define_expand "sibcall_epilogue"
2113 epiphany_expand_epilogue (1);
2117 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2118 ; in the prologue / epilogue expanders how many times lr is set.
2119 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2120 ; any explicit use of lr will cause it to be saved; hence we cannot
2121 ; represent the blink use in return / sibcall instructions themselves, and
2122 ; instead have to show it in EPILOGUE_USES.
2123 (define_insn "return_i"
2127 [(set_attr "type" "uncond_branch")])
2129 (define_insn "return_internal_interrupt"
2131 (unspec_volatile [(const_int 0)] 1)]
2134 [(set_attr "type" "uncond_branch")])
2136 (define_insn "stack_adjust_add"
2137 [(set (reg:SI GPR_SP)
2138 (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2139 (clobber (reg:CC CC_REGNUM))
2140 (clobber (reg:SI STATUS_REGNUM))
2141 (clobber (match_operand:BLK 1 "memory_operand" "=m"))]
2145 (define_insn "stack_adjust_mov"
2146 [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2147 (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2150 [(set_attr "type" "move")])
2152 (define_insn "stack_adjust_str"
2153 [(set (match_operand 0 "stacktop_operand" "=m")
2154 (match_operand 1 "any_gpr_operand" "r"))
2155 (set (reg:SI GPR_SP)
2156 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2157 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2160 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2161 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2163 [(set_attr "type" "store")])
2165 (define_insn "stack_adjust_ldr"
2166 [(set (match_operand:SI 0 "gpr_operand" "=r")
2167 (match_operand:SI 1 "stacktop_operand" "m"))
2168 (set (reg:SI GPR_SP)
2169 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2170 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2173 [(set_attr "type" "load")])
2175 ;; Define some fake vector operations so that the vectorizer is happy to use
2176 ;; 64 bit loads/stores.
2177 (define_expand "vec_unpacks_lo_v4hi"
2178 [(match_operand:V2SI 0 "gpr_operand")
2179 (match_operand:V4HI 1 "gpr_operand")]
2182 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2183 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2185 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2187 if (reg_overlap_mentioned_p (outl, in))
2188 in = copy_to_mode_reg (SImode, in);
2189 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2190 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2191 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2195 (define_expand "vec_unpacks_hi_v4hi"
2196 [(match_operand:V2SI 0 "gpr_operand")
2197 (match_operand:V4HI 1 "gpr_operand")]
2200 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2201 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2203 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2205 if (reg_overlap_mentioned_p (outl, in))
2206 in = copy_to_mode_reg (SImode, in);
2207 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2208 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2209 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2213 (define_code_iterator addsub [plus minus])
2215 (define_code_iterator alu_binop
2216 [plus minus and ior xor])
2218 (define_code_attr insn_opname
2219 [(plus "add") (minus "sub") (mult "mul") (div "div")
2220 (and "and") (ior "ior") (xor "xor")])
2222 ; You might think that this would work better as a define_expand, but
2223 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2224 ; We need to keep inputs and outputs as register pairs if we want to
2225 ; get sensible register allocation for double-word load and store operations.
2226 (define_insn_and_split "<insn_opname>v2si3"
2227 [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2228 (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2229 (match_operand:V2SI 2 "gpr_operand" "r")))
2230 (clobber (reg:CC CC_REGNUM))]
2233 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2236 rtx o0l, o0h, o1l, o1h, o2l, o2h;
2238 o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2239 o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2240 o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2241 o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2242 o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2243 o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2244 if (reg_overlap_mentioned_p (o0l, o1h))
2245 o1h = copy_to_mode_reg (SImode, o1h);
2246 if (reg_overlap_mentioned_p (o0l, o2h))
2247 o2h = copy_to_mode_reg (SImode, o2h);
2248 emit_insn (gen_<insn_opname>si3 (o0l, o1l, o2l));
2249 emit_insn (gen_<insn_opname>si3 (o0h, o1h, o2h));
2252 [(set_attr "length" "8")])
2254 (define_expand "<insn_opname>v2sf3"
2256 [(set (match_operand:V2SF 0 "gpr_operand" "")
2257 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2258 (match_operand:V2SF 2 "gpr_operand" "")))
2259 (clobber (reg:CC_FP CCFP_REGNUM))])])
2261 (define_insn_and_split "<insn_opname>v2sf3_i"
2262 [(match_parallel 3 "float_operation"
2263 [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2264 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2265 (match_operand:V2SF 2 "gpr_operand" "r")))
2266 (clobber (reg:CC_FP CCFP_REGNUM))])]
2269 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2271 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2272 (clobber (reg:CC_FP CCFP_REGNUM))
2276 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2277 (clobber (reg:CC_FP CCFP_REGNUM))
2281 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2282 operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2283 operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2285 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2287 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2289 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2290 if (!reload_completed)
2292 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2293 operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2294 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2295 operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2296 emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2297 emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2300 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2301 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2302 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2303 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2305 [(set_attr "length" "8")
2306 (set_attr "type" "fp")])
2308 (define_expand "mul<mode>3"
2310 [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2311 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2312 (match_operand:DWV2MODE 2 "gpr_operand" "")))
2313 (clobber (reg:CC_FP CCFP_REGNUM))])])
2315 (define_insn_and_split "mul<mode>3_i"
2316 [(match_parallel 3 "float_operation"
2317 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2318 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2319 (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2320 (clobber (reg:CC_FP CCFP_REGNUM))])]
2323 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2325 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2326 (clobber (reg:CC_FP CCFP_REGNUM))
2330 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2331 (clobber (reg:CC_FP CCFP_REGNUM))
2336 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2338 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2340 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2341 operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2342 <MODE>mode, UNITS_PER_WORD);
2343 operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2344 <MODE>mode, UNITS_PER_WORD);
2345 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2346 <MODE>mode, UNITS_PER_WORD);
2347 if (!reload_completed)
2349 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2350 operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2351 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2352 operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2353 emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2354 emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2357 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2358 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2359 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2360 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2362 [(set_attr "length" "8")
2363 (set_attr "type" "<vmode_fp_type>")])
2365 (define_insn_and_split "*fmadd<mode>_combine"
2366 [(match_parallel 4 "float_operation"
2367 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2368 (plus:DWV2MODE (mult:<MODE>
2369 (match_operand:<MODE> 1 "gpr_operand" "r")
2370 (match_operand:<MODE> 2 "gpr_operand" "r"))
2371 (match_operand:<MODE> 3 "gpr_operand" "0")))
2372 (clobber (reg:CC_FP CCFP_REGNUM))])]
2373 "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2375 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2378 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2380 (clobber (reg:CC_FP CCFP_REGNUM))
2385 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2387 (clobber (reg:CC_FP CCFP_REGNUM))
2392 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2394 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2396 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2398 = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2399 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2400 <MODE>mode, UNITS_PER_WORD);
2401 operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2402 <MODE>mode, UNITS_PER_WORD);
2403 operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2404 <MODE>mode, UNITS_PER_WORD);
2405 operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2406 <MODE>mode, UNITS_PER_WORD);
2407 if (!reload_completed)
2409 if (reg_overlap_mentioned_p (operands[5], operands[10]))
2410 operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2411 if (reg_overlap_mentioned_p (operands[5], operands[11]))
2412 operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2413 if (reg_overlap_mentioned_p (operands[5], operands[12]))
2414 operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2415 emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2417 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2421 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2422 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2423 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2424 operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2425 operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2427 [(set_attr "length" "8")
2428 (set_attr "type" "<vmode_fp_type>")])
2430 (define_expand "vec_set<mode>"
2431 [(match_operand:DWV2MODE 0 "register_operand")
2432 (match_operand:<vmode_PART> 1 "register_operand")
2433 (match_operand 2 "const_int_operand" "")]
2437 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2438 UNITS_PER_WORD * INTVAL (operands[2]));
2439 emit_move_insn (operands[0], operands[1]);
2447 [(set_attr "type" "flow")])