1 ;; Machine description of the Adaptiva epiphany cpu for GNU C compiler
2 ;; Copyright (C) 1994-2013 Free Software Foundation, Inc.
3 ;; Contributed by Embecosm on behalf of Adapteva, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
32 (ARG_POINTER_REGNUM 64)
33 (FRAME_POINTER_REGNUM 65)
34 (CC_REGNUM 66) ;; 66 or 17
35 (CCFP_REGNUM 67) ;; 67 or 18
42 (FP_NEAREST_REGNUM 74)
43 (FP_TRUNCATE_REGNUM 75)
45 (UNKNOWN_REGNUM 77) ; used for addsi3_r and friends
46 ; We represent the return address as an unspec rather than a reg.
47 ; If we used a reg, we could use register elimination, but eliminating
48 ; to GPR_LR would make the latter visible to dataflow, thus making it
49 ; harder to determine when it must be saved.
50 (UNSPEC_RETURN_ADDR 0)
56 ;; Insn type. Used to default other attribute values.
59 "move,load,store,cmove,unary,compare,shift,mul,uncond_branch,branch,call,fp,fp_int,v2fp,misc,sfunc,fp_sfunc,flow"
60 (const_string "misc"))
62 ;; Length (in # bytes)
64 (define_attr "length" "" (const_int 4))
66 ;; The length here is the length of a single asm.
68 (define_asm_attributes
69 [(set_attr "length" "4")
70 (set_attr "type" "misc")])
72 ;; pipeline model; so far we have only one.
73 (define_attr "pipe_model" "epiphany" (const_string "epiphany"))
75 (define_attr "rounding" "trunc,nearest"
76 (cond [(ne (symbol_ref "TARGET_ROUND_NEAREST") (const_int 0))
77 (const_string "nearest")]
78 (const_string "trunc")))
80 (define_attr "fp_mode" "round_unknown,round_nearest,round_trunc,int,caller,none"
81 (cond [(eq_attr "type" "fp,v2fp,fp_sfunc")
82 (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_rounding")
83 (eq_attr "type" "call")
84 (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_mode")
85 (eq_attr "type" "fp_int")
87 (const_string "none")))
89 (include "epiphany-sched.md")
91 (include "predicates.md")
92 (include "constraints.md")
94 ;; modes that are held in a single register, and hence, a word.
95 (define_mode_iterator WMODE [SI SF HI QI V2HI V4QI])
96 (define_mode_iterator WMODE2 [SI SF HI QI V2HI V4QI])
98 ;; modes that are held in a two single registers
99 (define_mode_iterator DWMODE [DI DF V2SI V2SF V4HI V8QI])
101 ;; Double-word mode made up of two single-word mode values.
102 (define_mode_iterator DWV2MODE [V2SI V2SF])
103 (define_mode_attr vmode_part [(V2SI "si") (V2SF "sf")])
104 (define_mode_attr vmode_PART [(V2SI "SI") (V2SF "SF")])
105 (define_mode_attr vmode_fp_type [(V2SI "fp_int") (V2SF "fp")])
106 (define_mode_attr vmode_ccmode [(V2SI "CC") (V2SF "CC_FP")])
107 (define_mode_attr vmode_cc [(V2SI "CC_REGNUM") (V2SF "CCFP_REGNUM")])
109 ;; Move instructions.
111 (define_expand "mov<mode>"
112 [(set (match_operand:WMODE 0 "general_operand" "")
113 (match_operand:WMODE 1 "general_operand" ""))]
116 if (<MODE>mode == V4QImode || <MODE>mode == V2HImode)
118 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
119 operands[1] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
120 emit_insn (gen_movsi (operands[0], operands[1]));
123 if (GET_CODE (operands[0]) == MEM)
124 operands[1] = force_reg (<MODE>mode, operands[1]);
125 if (<MODE>mode == SImode
126 && (operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx))
128 rtx reg = operands[0];
131 reg = gen_reg_rtx (SImode);
132 emit_insn (gen_move_frame (reg, operands[1]));
134 if (operands[0] == reg)
139 (define_insn "*movqi_insn"
140 [(set (match_operand:QI 0 "move_dest_operand" "=Rcs, r, r,r,m")
141 (match_operand:QI 1 "move_src_operand" "Rcs,rU16,Cal,m,r"))]
143 "gpr_operand (operands[0], QImode)
144 || gpr_operand (operands[1], QImode)"
151 [(set_attr "type" "move,move,move,load,store")])
153 (define_insn_and_split "*movhi_insn"
154 [(set (match_operand:HI 0 "move_dest_operand" "=r, r,r,m")
155 (match_operand:HI 1 "move_src_operand""rU16,Cal,m,r"))]
156 "gpr_operand (operands[0], HImode)
157 || gpr_operand (operands[1], HImode)"
163 "reload_completed && CONSTANT_P (operands[1])
164 && !satisfies_constraint_U16 (operands[1]) && TARGET_SPLIT_LOHI"
165 [(set (match_dup 2) (match_dup 3))]
166 "operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
167 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);"
168 [(set_attr "type" "move,move,load,store")])
170 ;; We use a special pattern for a move from the frame pointer to
171 ;; show the flag clobber that is needed when this move is changed
172 ;; to an add by register elimination.
173 ;; ??? A pseudo register might be equivalent to a function invariant,
174 ;; and thus placed by reload into reg_equiv_invariant; if the pseudo
175 ;; does not get a hard register, we then end up with the function
176 ;; invariant in its place, i.e. an unexpected clobber of the flags
179 ;; N.B. operand 1 is an operand so that reload will perform elimination.
181 ;; The post-reload pattern recognition and splitting is done in frame_move_1.
182 (define_insn "move_frame"
183 [(set (match_operand:SI 0 "gpr_operand" "=r")
184 (match_operand:SI 1 "register_operand" "r"))
185 (clobber (reg:CC CC_REGNUM))]
186 "operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx"
189 (define_insn "movsi_high"
190 [(set (match_operand:SI 0 "gpr_operand" "+r")
191 (ior:SI (and:SI (match_dup 0) (const_int 65535))
192 (high:SI (match_operand:SI 1 "move_src_operand" "i"))))]
194 "movt %0, %%high(%1)"
195 [(set_attr "type" "move")
196 (set_attr "length" "4")])
198 (define_insn "movsi_lo_sum"
199 [(set (match_operand:SI 0 "gpr_operand" "=r")
200 (lo_sum:SI (const_int 0)
201 (match_operand:SI 1 "move_src_operand" "i")))]
204 [(set_attr "type" "move")
205 (set_attr "length" "4")])
207 (define_insn_and_split "*movsi_insn"
208 [(set (match_operand:SI 0 "move_dest_operand"
209 "= r, r, r, r, r, r, m, r, Rct")
210 (match_operand:SI 1 "move_src_operand"
211 "rU16Rra,Cm1,Cl1,Cr1,Cal,mSra,rRra,Rct,r"))]
212 "gpr_operand (operands[0], SImode)
213 || gpr_operand (operands[1], SImode)
214 || satisfies_constraint_Sra (operands[1])"
216 switch (which_alternative)
218 case 0: return "mov %0,%1";
219 case 1: return "add %0,%-,(1+%1)";
220 case 2: operands[1] = GEN_INT (exact_log2 (-INTVAL (operands[1])));
221 return "lsl %0,%-,%1";
222 case 3: operands[1] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
223 return "lsr %0,%-,%1";
224 case 4: return "mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1";
225 case 5: return "ldr %0,%C1";
226 case 6: return "str %1,%C0";
227 case 7: return "movfs %0,%1";
228 case 8: return "movts %0,%1";
229 default: gcc_unreachable ();
232 "reload_completed && CONSTANT_P (operands[1])
233 && !satisfies_constraint_U16 (operands[1])
234 && !satisfies_constraint_Cm1 (operands[1])
235 && !satisfies_constraint_Cl1 (operands[1])
236 && !satisfies_constraint_Cr1 (operands[1])
237 && TARGET_SPLIT_LOHI"
238 [(match_dup 2) (match_dup 3)]
239 "operands[2] = gen_movsi_lo_sum (operands[0], operands[1]);
240 operands[3] = gen_movsi_high (operands[0], operands[1]);"
241 [(set_attr "type" "move,misc,misc,misc,move,load,store,flow,flow")
242 (set_attr "length" "4,4,4,4,8,4,4,4,4")])
245 [(set (match_operand:SI 0 "nonimmediate_operand")
246 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
247 "reload_completed && !MACHINE_FUNCTION (cfun)->lr_clobbered"
248 [(set (match_dup 0) (reg:SI GPR_LR))])
251 [(set (match_operand:SI 0 "gpr_operand")
252 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
254 [(set (match_dup 0) (match_dup 1))]
256 emit_insn (gen_reload_insi_ra (operands[0], operands[1]));
260 (define_expand "reload_insi_ra"
261 [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))]
265 = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx);
267 addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
268 operands[1] = gen_frame_mem (SImode, addr);
271 ;; If the frame pointer elimination offset is zero, we'll use this pattern.
272 ;; Note that the splitter can accept any gpr in operands[1]; this is
273 ;; necessary, (e.g. for compile/20021015-1.c -O0,)
274 ;; because when register elimination cannot be done with the constant
275 ;; as an immediate operand of the add instruction, reload will resort to
276 ;; loading the constant into a reload register, using gen_add2_insn to add
277 ;; the stack pointer, and then use the reload register as new source in
278 ;; the move_frame pattern.
279 (define_insn_and_split "*move_frame_1"
280 [(set (match_operand:SI 0 "gpr_operand" "=r")
281 (match_operand:SI 1 "gpr_operand" "r"))
282 (clobber (reg:CC CC_REGNUM))]
283 "(reload_in_progress || reload_completed)
284 && (operands[1] == stack_pointer_rtx
285 || operands[1] == hard_frame_pointer_rtx)"
287 "reload_in_progress || reload_completed"
288 [(set (match_dup 0) (match_dup 1))])
290 (define_expand "mov<mode>"
291 [(set (match_operand:DWMODE 0 "general_operand" "")
292 (match_operand:DWMODE 1 "general_operand" ""))]
296 if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT
297 || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
299 if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)
301 rtx o0l, o0h, o1l, o1h;
303 o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
304 o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode,
306 o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
307 o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode,
309 if (reg_overlap_mentioned_p (o0l, o1h))
311 emit_move_insn (o0h, o1h);
312 emit_move_insn (o0l, o1l);
316 emit_move_insn (o0l, o1l);
317 emit_move_insn (o0h, o1h);
321 /* lower_subreg has a tendency to muck up vectorized code.
322 To protect the wide memory accesses, we must use same-size
324 if (epiphany_vect_align != 4 /* == 8 */
325 && !reload_in_progress
326 && (GET_CODE (operands[0]) == MEM || GET_CODE (operands[1]) == MEM)
327 && !misaligned_operand (operands[1], <MODE>mode)
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]) || misaligned_operand (operands[0], <MODE>mode))
359 && (!MEM_P (operands[1])
360 || misaligned_operand (operands[1], <MODE>mode)))
361 || epiphany_vect_align == 4)"
362 [(set (match_dup 2) (match_dup 3))
363 (set (match_dup 4) (match_dup 5))]
365 int word0 = 0, word1 = UNITS_PER_WORD;
367 if (post_modify_operand (operands[0], <MODE>mode)
368 || post_modify_operand (operands[1], <MODE>mode))
369 word0 = UNITS_PER_WORD, word1 = 0;
371 operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
372 operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
373 operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
374 operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
375 if (post_modify_operand (operands[0], <MODE>mode))
377 = change_address (operands[2], VOIDmode,
378 plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0),
380 if (post_modify_operand (operands[1], <MODE>mode))
382 = change_address (operands[3], VOIDmode,
383 plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0),
386 [(set_attr "type" "move,move,load,store")
387 (set_attr "length" "8,16,4,4")])
390 (define_insn_and_split "*movsf_insn"
391 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
392 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
393 "gpr_operand (operands[0], SFmode)
394 || gpr_operand (operands[1], SFmode)"
397 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
400 "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
401 [(set (match_dup 2) (match_dup 3))]
402 "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
403 operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
404 [(set_attr "type" "move,move,load,store")
405 (set_attr "length" "4,8,4,4")])
407 (define_expand "addsi3"
408 [(set (match_operand:SI 0 "add_reg_operand" "")
409 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
410 (match_operand:SI 2 "add_operand" "")))]
414 if (reload_in_progress || reload_completed)
415 emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
416 else if (TARGET_FP_IARITH && add_reg_operand (operands[2], SImode))
417 emit_insn (gen_iadd (operands[0], operands[1], operands[2]));
419 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
423 (define_insn "addsi3_i"
424 [(set (match_operand:SI 0 "add_reg_operand" "=r")
425 (plus:SI (match_operand:SI 1 "add_reg_operand" "%r")
426 (match_operand:SI 2 "add_operand" "rL")))
427 (clobber (reg:CC CC_REGNUM))]
430 [(set_attr "type" "misc")])
432 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
433 ; can identify the unresolved flags clobber problem, and also to
434 ; avoid unwanted matches.
436 ; At -O0 / -O1 we don't peephole all instances away. We could get better
437 ; debug unwinding through the emitted code if we added a splitter.
438 (define_insn "addsi3_r"
439 [(set (match_operand:SI 0 "gpr_operand" "=r")
440 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
441 (match_operand:SI 2 "nonmemory_operand" "rCar")))
442 (clobber (reg:CC UNKNOWN_REGNUM))]
443 "reload_in_progress || reload_completed"
446 ^ (true_regnum (operands[0]) & 1)
447 ^ (true_regnum (operands[1]) & 2)
448 ^ (true_regnum (operands[2]) & 4));
449 asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
450 asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
451 output_asm_insn ("add %0,%1,%2", operands);
452 asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
453 asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
456 [(set_attr "length" "20")
457 (set_attr "type" "misc")])
459 ;; reload uses gen_addsi2 because it doesn't understand the need for
462 [(set (match_operand:SI 0 "gpr_operand" "")
463 (match_operand:SI 1 "const_int_operand" ""))
464 (parallel [(set (match_dup 0)
465 (plus:SI (match_dup 0)
466 (match_operand:SI 2 "gpr_operand")))
467 (clobber (reg:CC UNKNOWN_REGNUM))])]
468 "satisfies_constraint_L (operands[1])
469 || ((operands[2] == stack_pointer_rtx
470 || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
471 && !peep2_regno_dead_p (2, CC_REGNUM)
472 && satisfies_constraint_Car (operands[1]))"
473 [(parallel [(set (match_dup 0)
474 (plus:SI (match_dup 2) (match_dup 1)))
475 (clobber (reg:CC UNKNOWN_REGNUM))])]
477 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
478 ;; "peep2_rescan = true;"
482 [(match_parallel 5 ""
483 [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
484 (parallel [(set (match_operand:SI 0 "gpr_operand" "")
485 (plus:SI (match_operand:SI 1 "gpr_operand" "")
486 (match_operand:SI 2 "nonmemory_operand" "")))
487 (clobber (reg:CC UNKNOWN_REGNUM))])]
488 "REGNO (operands[3]) == CC_REGNUM
489 && (gpr_operand (operands[2], SImode)
490 || satisfies_constraint_L (operands[2]))
491 && !reg_overlap_mentioned_p (operands[0], operands[5])
492 && !reg_set_p (operands[1], operands[5])
493 && !reg_set_p (operands[2], operands[5])"
494 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
495 (plus:SI (match_operand:SI 1 "gpr_operand" "")
496 (match_operand:SI 2 "nonmemory_operand" "")))
497 (clobber (reg:CC CC_REGNUM))])
502 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
503 (plus:SI (match_operand:SI 1 "gpr_operand" "")
504 (match_operand:SI 2 "nonmemory_operand" "")))
505 (clobber (reg:CC UNKNOWN_REGNUM))])]
506 "peep2_regno_dead_p (1, CC_REGNUM)
507 && (gpr_operand (operands[2], SImode)
508 || satisfies_constraint_L (operands[2]))"
509 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
510 (plus:SI (match_operand:SI 1 "gpr_operand" "")
511 (match_operand:SI 2 "nonmemory_operand" "")))
512 (clobber (reg:CC CC_REGNUM))])]
516 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
517 (plus:SI (reg:SI GPR_SP)
518 (match_operand:SI 1 "nonmemory_operand" "")))
519 (clobber (reg:CC UNKNOWN_REGNUM))])]
520 "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
521 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
522 [(set (match_dup 0) (reg:SI GPR_SP))
523 (set (mem:WMODE (post_modify (match_dup 0)
524 (plus:SI (match_dup 0) (match_dup 1))))
531 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
532 (plus:SI (reg:SI GPR_FP)
533 (match_operand:SI 1 "nonmemory_operand" "")))
534 (clobber (reg:CC UNKNOWN_REGNUM))])
535 (match_scratch:WMODE 2 "r")]
536 "frame_pointer_needed
537 && ((REG_P (operands[1])
538 && !reg_overlap_mentioned_p (operands[0], operands[1]))
539 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
540 [(set (match_dup 0) (reg:SI GPR_FP))
542 (mem:WMODE (post_modify (match_dup 0)
543 (plus:SI (match_dup 0) (match_dup 1)))))]
546 (define_expand "subsi3"
547 [(set (match_operand:SI 0 "gpr_operand" "")
548 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
549 (match_operand:SI 2 "arith_operand" "")))]
553 gcc_assert (!reload_in_progress && !reload_completed);
555 if (TARGET_FP_IARITH)
556 emit_insn (gen_isub (operands[0], operands[1], operands[2]));
558 emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2]));
562 (define_insn "subsi3_i"
563 [(set (match_operand:SI 0 "gpr_operand" "=r")
564 (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
565 (match_operand:SI 2 "arith_operand" "rL")))
566 (clobber (reg:CC CC_REGNUM))]
569 [(set_attr "type" "misc")])
571 ; After mode-switching, floating point operations, fp_sfuncs and calls
572 ; must exhibit the use of the control register, lest the setting of the
573 ; control register could be deleted or moved. OTOH a use of a hard register
574 ; greatly coundounds optimizers like the rtl loop optimizers or combine.
575 ; Therefore, we put an extra pass immediately after the mode switching pass
576 ; that inserts the USEs of the control registers, and sets a flag in struct
577 ; machine_function that float_operation can henceforth only match with that
581 (define_expand "addsf3"
583 [(set (match_operand:SF 0 "gpr_operand" "")
584 (plus:SF (match_operand:SF 1 "gpr_operand" "")
585 (match_operand:SF 2 "gpr_operand" "")))
586 (clobber (reg:CC_FP CCFP_REGNUM))])])
588 (define_insn "*addsf3_i"
589 [(match_parallel 3 "float_operation"
590 [(set (match_operand:SF 0 "gpr_operand" "=r")
591 (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
592 (match_operand:SF 2 "gpr_operand" "r")))
593 (clobber (reg:CC_FP CCFP_REGNUM))])]
596 [(set_attr "type" "fp")])
599 (define_expand "subsf3"
601 [(set (match_operand:SF 0 "gpr_operand" "")
602 (minus:SF (match_operand:SF 1 "gpr_operand" "")
603 (match_operand:SF 2 "gpr_operand" "")))
604 (clobber (reg:CC_FP CCFP_REGNUM))])])
606 (define_insn "*subsf3_i"
607 [(match_parallel 3 "float_operation"
608 [(set (match_operand:SF 0 "gpr_operand" "=r")
609 (minus:SF (match_operand:SF 1 "gpr_operand" "r")
610 (match_operand:SF 2 "gpr_operand" "r")))
611 (clobber (reg:CC_FP CCFP_REGNUM))])]
614 [(set_attr "type" "fp")])
616 (define_expand "subsf3_f"
618 [(set (reg:CC_FP CCFP_REGNUM)
619 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
620 (match_operand:SF 2 "gpr_operand" "r")))
621 (set (match_operand:SF 0 "gpr_operand" "=r")
622 (minus:SF (match_dup 1) (match_dup 2)))])]
623 "!TARGET_SOFT_CMPSF")
625 (define_insn "*subsf3_f_i"
626 [(match_parallel 3 "float_operation"
627 [(set (reg:CC_FP CCFP_REGNUM)
628 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
629 (match_operand:SF 2 "gpr_operand" "r")))
630 (set (match_operand:SF 0 "gpr_operand" "=r")
631 (minus:SF (match_dup 1) (match_dup 2)))])]
634 [(set_attr "type" "fp")])
636 ; There is an fabs instruction, but it has longer latency.
637 (define_expand "abssf2"
638 [(set (match_operand:SF 0 "gpr_operand" "")
639 (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
643 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
645 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
647 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
648 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
653 (define_expand "mulsf3"
655 [(set (match_operand:SF 0 "gpr_operand" "")
656 (mult:SF (match_operand:SF 1 "gpr_operand" "")
657 (match_operand:SF 2 "gpr_operand" "")))
658 (clobber (reg:CC_FP CCFP_REGNUM))])])
660 (define_insn "*mulsf3_i"
661 [(match_parallel 3 "float_operation"
662 [(set (match_operand:SF 0 "gpr_operand" "=r")
663 (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
664 (match_operand:SF 2 "gpr_operand" "r")))
665 (clobber (reg:CC_FP CCFP_REGNUM))])]
668 [(set_attr "type" "fp")])
671 (define_expand "divsf3"
672 [(set (match_operand:SF 0 "gpr_operand" "")
673 (div:SF (match_operand:SF 1 "gpr_operand" "")
674 (match_operand:SF 2 "gpr_operand" "")))]
675 "flag_reciprocal_math"
677 rtx one = CONST1_RTX (SFmode);
678 rtx dst = operands[0];
680 if (rtx_equal_p (dst, operands[1]))
682 emit_move_insn (dst, one);
685 else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
686 dst = gen_reg_rtx (SFmode);
687 emit_insn (gen_recipsf2 (dst, one, operands[2],
688 sfunc_symbol (\"__fast_recipsf2\")));
689 emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
693 ;; Before reload, keep the hard reg usage to clobbers so that the loop
694 ;; optimizers can more easily move this insn.
695 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
696 ;; but sched1 can still cause trouble then, and there is no guarantee of
697 ;; better register allocations.
698 ;; Neither is there when using the opposite strategy - putting explicit
699 ;; hard register references into pre-reload rtl.
700 (define_expand "recipsf2"
702 [(set (match_operand:SF 0 "gpr_operand" "")
703 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
704 (match_operand:SF 2 "move_src_operand" "")))
705 (use (match_operand:SI 3 "move_src_operand" ""))
708 (clobber (reg:SF GPR_IP))
709 (clobber (reg:DI GPR_16))
710 (clobber (reg:DI GPR_18))
711 (clobber (reg:SI GPR_20))
712 (clobber (reg:SI GPR_LR))
713 (clobber (reg:CC CC_REGNUM))
714 (clobber (reg:CC_FP CCFP_REGNUM))])])
716 (define_insn_and_split "*recipsf2_1"
717 [(match_parallel 4 "float_operation"
718 [(set (match_operand:SF 0 "gpr_operand" "=r,r")
719 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
720 (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
721 (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
724 (clobber (reg:SF GPR_IP))
725 (clobber (reg:DI GPR_16))
726 (clobber (reg:DI GPR_18))
727 (clobber (reg:SI GPR_20))
728 (clobber (reg:SI GPR_LR))
729 (clobber (reg:CC CC_REGNUM))
730 (clobber (reg:CC_FP CCFP_REGNUM))])]
731 "flag_reciprocal_math"
733 "&& reload_completed"
734 [(set (reg:SI 1) (match_dup 3))
735 (set (reg:SF 0) (match_dup 2))
738 (div:SF (match_dup 1)
741 (clobber (reg:SI GPR_IP))
742 (clobber (reg:DI GPR_16))
743 (clobber (reg:DI GPR_18))
744 (clobber (reg:SI GPR_20))
745 (clobber (reg:SI GPR_LR))
746 (clobber (reg:CC CC_REGNUM))
747 (clobber (reg:CC_FP CCFP_REGNUM))
750 (set (match_dup 0) (reg:SF 0))]
751 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
752 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
753 [(set_attr "type" "fp_sfunc")
754 (set_attr "length" "16,24")])
756 (define_insn "*recipsf2_2"
757 [(match_parallel 1 "float_operation"
759 (div:SF (match_operand:SF 0 "const_float_1_operand" "")
762 (clobber (reg:SI GPR_IP))
763 (clobber (reg:DI GPR_16))
764 (clobber (reg:DI GPR_18))
765 (clobber (reg:SI GPR_20))
766 (clobber (reg:SI GPR_LR))
767 (clobber (reg:CC CC_REGNUM))
768 (clobber (reg:CC_FP CCFP_REGNUM))])]
769 "flag_reciprocal_math"
771 [(set_attr "type" "fp_sfunc")])
774 ;; Fused multiply-add
775 (define_expand "fmasf4"
777 [(set (match_operand:SF 0 "gpr_operand" "")
778 (fma:SF (match_operand:SF 1 "gpr_operand" "")
779 (match_operand:SF 2 "gpr_operand" "")
780 (match_operand:SF 3 "gpr_operand" "")))
781 (clobber (reg:CC_FP CCFP_REGNUM))])]
784 ; The multiply operands are commutative, but since they have the
785 ; same constraints, there is no point in telling reload about this.
786 (define_insn "*fmadd"
787 [(match_parallel 4 "float_operation"
788 [(set (match_operand:SF 0 "gpr_operand" "=r")
789 (fma:SF (match_operand:SF 1 "gpr_operand" "r")
790 (match_operand:SF 2 "gpr_operand" "r")
791 (match_operand:SF 3 "gpr_operand" "0")))
792 (clobber (reg:CC_FP CCFP_REGNUM))])]
795 [(set_attr "type" "fp")])
797 ; Once vetorization consistently works for this port, should check
798 ; if the fmadd / fmsub patterns still serve a purpose. With the
799 ; introduction of fma / fnma handling by the SSA optimizers,
800 ; at least scalars should be handled by these optimizers, would
801 ; have to see how well they do on vectors from auto-vectorization.
803 ; combiner pattern, also used by vector combiner pattern
804 (define_expand "maddsf"
806 [(set (match_operand:SF 0 "gpr_operand" "=r")
807 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
808 (match_operand:SF 2 "gpr_operand" "r"))
809 (match_operand:SF 3 "gpr_operand" "0")))
810 (clobber (reg:CC_FP CCFP_REGNUM))])]
813 (define_insn "*maddsf_combine"
814 [(match_parallel 4 "float_operation"
815 [(set (match_operand:SF 0 "gpr_operand" "=r")
816 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
817 (match_operand:SF 2 "gpr_operand" "r"))
818 (match_operand:SF 3 "gpr_operand" "0")))
819 (clobber (reg:CC_FP CCFP_REGNUM))])]
822 [(set_attr "type" "fp")])
824 ;; Fused multiply-sub
825 (define_expand "fnmasf4"
827 [(set (match_operand:SF 0 "gpr_operand" "")
828 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
829 (match_operand:SF 2 "gpr_operand" "")
830 (match_operand:SF 3 "gpr_operand" "")))
831 (clobber (reg:CC_FP CCFP_REGNUM))])]
834 (define_insn "*fmsub"
835 [(match_parallel 4 "float_operation"
836 [(set (match_operand:SF 0 "gpr_operand" "=r")
837 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" "r"))
838 (match_operand:SF 2 "gpr_operand" "r")
839 (match_operand:SF 3 "gpr_operand" "0")))
840 (clobber (reg:CC_FP CCFP_REGNUM))])]
843 [(set_attr "type" "fp")])
845 (define_insn "*fmsub_combine"
846 [(match_parallel 4 "float_operation"
847 [(set (match_operand:SF 0 "gpr_operand" "=r")
848 (minus:SF (match_operand:SF 3 "gpr_operand" "0")
849 (mult:SF (match_operand:SF 1 "gpr_operand" "r")
850 (match_operand:SF 2 "gpr_operand" "r"))))
851 (clobber (reg:CC_FP CCFP_REGNUM))])]
854 [(set_attr "type" "fp")])
856 ;; float / integer conversions
858 (define_expand "floatsisf2"
860 [(set (match_operand:SF 0 "gpr_operand" "")
861 (float:SF (match_operand:SI 1 "gpr_operand" "")))
862 (clobber (reg:CC_FP CCFP_REGNUM))])])
864 (define_insn "*floatsisf2_i"
865 [(match_parallel 2 "float_operation"
866 [(set (match_operand:SF 0 "gpr_operand" "=r")
867 (float:SF (match_operand:SI 1 "gpr_operand" "r")))
868 (clobber (reg:CC_FP CCFP_REGNUM))])]
871 [(set_attr "type" "fp")])
873 (define_expand "floatsisf2_cmp"
875 [(set (reg:CC_FP CCFP_REGNUM)
876 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
878 (set (match_operand:SF 0 "gpr_operand" "=r")
879 (float:SF (match_dup 1)))])]
881 "operands[2] = CONST0_RTX (SFmode);")
883 (define_insn "*floatsisf2_cmp_i"
884 [(match_parallel 3 "float_operation"
885 [(set (reg:CC_FP CCFP_REGNUM)
886 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
887 (match_operand:SF 2 "const0_operand" "")))
888 (set (match_operand:SF 0 "gpr_operand" "=r")
889 (float:SF (match_dup 1)))])]
892 [(set_attr "type" "fp")])
894 (define_expand "floatunssisf2"
895 [(set (match_operand:SF 0 "gpr_operand" "")
896 (float:SF (match_operand:SI 1 "gpr_operand" "")))]
897 "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
899 rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
900 rtx tmp = gen_reg_rtx (SImode);
901 rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
903 if (reg_overlap_mentioned_p (operands[0], operands[1]))
904 operands[1] = copy_to_mode_reg (SImode, operands[1]);
905 emit_insn (gen_floatsisf2 (operands[0], operands[1]));
906 emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
907 emit_insn (gen_sub_f (tmp, tmp, cst));
908 emit_insn (gen_movsfcc (operands[0], cmp,
909 simplify_gen_subreg (SFmode, tmp, SImode, 0),
914 (define_expand "fix_truncsfsi2"
916 [(set (match_operand:SI 0 "gpr_operand" "")
917 (fix:SI (match_operand:SF 1 "gpr_operand" "")))
918 (clobber (reg:CC_FP CCFP_REGNUM))])])
920 (define_insn "*fix_truncsfsi2_i"
921 [(match_parallel 2 "float_operation"
922 [(set (match_operand:SI 0 "gpr_operand" "=r")
923 (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
924 (clobber (reg:CC_FP CCFP_REGNUM))])]
927 [(set_attr "type" "fp")
928 (set (attr "fp_mode")
929 (cond [(match_test "TARGET_MAY_ROUND_FOR_TRUNC")
930 (const_string "round_unknown")]
931 (const_string "round_trunc")))])
933 (define_expand "fixuns_truncsfsi2"
934 [(set (match_operand:SI 0 "gpr_operand" "")
935 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
938 if (reg_overlap_mentioned_p (operands[0], operands[1]))
939 operands[1] = copy_to_mode_reg (SImode, operands[1]);
940 if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
943 /* By toggling what it to be bit31 before the shift, we get a chance to
944 use a short movt insn. */
945 rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
946 rtx tmp = gen_reg_rtx (SImode);
947 rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
949 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
951 op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
952 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
953 emit_insn (gen_subsi3_i (tmp, op1si, bit31));
954 emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
955 emit_insn (gen_cmpsi_cc_insn (op1si, limit));
956 emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
960 REAL_VALUE_TYPE offset;
962 rtx tmp = gen_reg_rtx (SFmode);
963 rtx label = gen_label_rtx ();
965 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
966 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
968 real_2expN (&offset, 31, SFmode);
969 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode);
970 limit = force_reg (SFmode, limit);
971 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
972 emit_insn (gen_subsf3_f (tmp, operands[1], limit));
973 emit_jump_insn (gen_branch_insn (label, cmp, cc1));
974 bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
975 emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
976 emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
982 (define_expand "iadd"
984 [(set (match_operand:SF 0 "gpr_operand" "")
985 (plus:SI (match_operand:SF 1 "gpr_operand" "")
986 (match_operand:SF 2 "gpr_operand" "")))
987 (clobber (reg:CC_FP CCFP_REGNUM))])])
989 (define_insn "*iadd_i"
990 [(match_parallel 3 "float_operation"
991 [(set (match_operand:SI 0 "gpr_operand" "=r")
992 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
993 (match_operand:SI 2 "gpr_operand" "r")))
994 (clobber (reg:CC_FP CCFP_REGNUM))])]
997 [(set_attr "type" "fp_int")])
999 (define_expand "isub"
1001 [(set (match_operand:SF 0 "gpr_operand" "")
1002 (minus:SI (match_operand:SF 1 "gpr_operand" "")
1003 (match_operand:SF 2 "gpr_operand" "")))
1004 (clobber (reg:CC_FP CCFP_REGNUM))])])
1006 (define_insn "*isub_i"
1007 [(match_parallel 3 "float_operation"
1008 [(set (match_operand:SI 0 "gpr_operand" "=r")
1009 (minus:SI (match_operand:SI 1 "gpr_operand" "r")
1010 (match_operand:SI 2 "gpr_operand" "r")))
1011 (clobber (reg:CC_FP CCFP_REGNUM))])]
1014 [(set_attr "type" "fp_int")])
1016 ; Try to figure out if we over-committed the FPU, and if so, move
1017 ; some insns back over to the integer pipe.
1019 ; The peephole optimizer 'consumes' the insns that are explicitly
1020 ; mentioned. We do not want the preceding insn reconsidered, but
1021 ; we do want that for the following one, so that if we have a run
1022 ; of five fpu users, two of them get changed. Therefore, we
1023 ; use next_active_insn to look at the 'following' insn. That should
1024 ; exist, because peephole2 runs after reload, and there has to be
1025 ; a return after an fp_int insn.
1026 ; ??? However, we can not even ordinarily match the preceding insn;
1027 ; there is some bug in the generators such that then it leaves out
1028 ; the check for PARALLEL before the length check for the then-second
1029 ; main insn. Observed when compiling compatibility-atomic-c++0x.cc
1030 ; from libstdc++-v3.
1032 [(match_parallel 3 "float_operation"
1033 [(set (match_operand:SI 0 "gpr_operand" "")
1034 (match_operator:SI 4 "addsub_operator"
1035 [(match_operand:SI 1 "gpr_operand" "")
1036 (match_operand:SI 2 "gpr_operand" "")]))
1037 (clobber (reg:CC_FP CCFP_REGNUM))])]
1038 "get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1039 && peep2_regno_dead_p (1, CC_REGNUM)
1040 && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))"
1041 [(parallel [(set (match_dup 0) (match_dup 4))
1042 (clobber (reg:CC CC_REGNUM))])]
1045 (define_expand "mulsi3"
1047 [(set (match_operand:SI 0 "gpr_operand" "")
1048 (mult:SI (match_operand:SI 1 "gpr_operand" "")
1049 (match_operand:SI 2 "gpr_operand" "")))
1050 (clobber (reg:CC_FP CCFP_REGNUM))])])
1052 (define_insn "*imul"
1053 [(match_parallel 3 "float_operation"
1054 [(set (match_operand:SI 0 "gpr_operand" "=r")
1055 (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
1056 (match_operand:SI 2 "gpr_operand" "r")))
1057 (clobber (reg:CC_FP CCFP_REGNUM))])]
1060 [(set_attr "type" "fp_int")])
1062 ; combiner pattern, also used by vector combiner pattern
1063 (define_expand "maddsi"
1065 [(set (match_operand:SI 0 "gpr_operand" "=r")
1066 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1067 (match_operand:SI 2 "gpr_operand" "r"))
1068 (match_operand:SI 3 "gpr_operand" "0")))
1069 (clobber (reg:CC_FP CCFP_REGNUM))])]
1072 (define_insn "*maddsi_combine"
1073 [(match_parallel 4 "float_operation"
1074 [(set (match_operand:SI 0 "gpr_operand" "=r")
1075 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1076 (match_operand:SI 2 "gpr_operand" "r"))
1077 (match_operand:SI 3 "gpr_operand" "0")))
1078 (clobber (reg:CC_FP CCFP_REGNUM))])]
1081 [(set_attr "type" "fp_int")])
1083 (define_insn "*imsub"
1084 [(match_parallel 4 "float_operation"
1085 [(set (match_operand:SI 0 "gpr_operand" "=r")
1086 (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1087 (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1088 (match_operand:SI 2 "gpr_operand" "r"))))
1089 (clobber (reg:CC_FP CCFP_REGNUM))])]
1092 [(set_attr "type" "fp_int")])
1094 (define_expand "divsi3"
1096 [(set (match_operand:SI 0 "move_dest_operand" "")
1097 (div:SI (match_operand:SI 1 "move_src_operand" "")
1098 (match_operand:SI 2 "move_src_operand" "")))
1100 (clobber (reg:SI 0))
1101 (clobber (reg:SI 1))
1102 (clobber (reg:SI GPR_IP))
1103 (clobber (reg:DI GPR_16))
1104 (clobber (reg:DI GPR_18))
1105 (clobber (reg:SI GPR_20))
1106 (clobber (reg:SI GPR_LR))
1107 (clobber (reg:CC CC_REGNUM))
1108 (clobber (reg:CC_FP CCFP_REGNUM))])]
1110 "operands[3] = sfunc_symbol (\"__divsi3\");")
1112 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1113 ;; optimizers can more easily move this insn.
1114 (define_insn_and_split "*divsi3_1"
1115 [(match_parallel 4 "float_operation"
1116 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1117 (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1118 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1119 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1120 (clobber (reg:SI 0))
1121 (clobber (reg:SI 1))
1122 (clobber (reg:SI GPR_IP))
1123 (clobber (reg:DI GPR_16))
1124 (clobber (reg:DI GPR_18))
1125 (clobber (reg:SI GPR_20))
1126 (clobber (reg:SI GPR_LR))
1127 (clobber (reg:CC CC_REGNUM))
1128 (clobber (reg:CC_FP CCFP_REGNUM))])]
1131 "&& reload_completed"
1132 [(set (reg:SI 0) (match_dup 1))
1133 (set (reg:SI 1) (match_dup 2))
1135 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1137 (clobber (reg:SI 1))
1138 (clobber (reg:SI GPR_IP))
1139 (clobber (reg:DI GPR_16))
1140 (clobber (reg:DI GPR_18))
1141 (clobber (reg:SI GPR_20))
1142 (clobber (reg:SI GPR_LR))
1143 (clobber (reg:CC CC_REGNUM))
1144 (clobber (reg:CC_FP CCFP_REGNUM))
1147 (set (match_dup 0) (reg:SI 0))]
1148 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1149 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1150 [(set_attr "type" "fp_sfunc")
1151 (set_attr "length" "16,24")])
1153 (define_insn "*divsi3_2"
1154 [(match_parallel 1 "float_operation"
1155 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1156 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1157 (clobber (reg:SI 1))
1158 (clobber (reg:SI GPR_IP))
1159 (clobber (reg:DI GPR_16))
1160 (clobber (reg:DI GPR_18))
1161 (clobber (reg:SI GPR_20))
1162 (clobber (reg:SI GPR_LR))
1163 (clobber (reg:CC CC_REGNUM))
1164 (clobber (reg:CC_FP CCFP_REGNUM))])]
1167 [(set_attr "type" "fp_sfunc")])
1169 (define_expand "udivsi3"
1171 [(set (match_operand:SI 0 "move_dest_operand" "")
1172 (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1173 (match_operand:SI 2 "move_src_operand" "")))
1175 (clobber (reg:SI 0))
1176 (clobber (reg:SI 1))
1177 (clobber (reg:SI GPR_IP))
1178 (clobber (reg:DI GPR_16))
1179 (clobber (reg:SI GPR_18))
1180 (clobber (reg:SI GPR_LR))
1181 (clobber (reg:CC CC_REGNUM))
1182 (clobber (reg:CC_FP CCFP_REGNUM))])]
1184 "operands[3] = sfunc_symbol (\"__udivsi3\");")
1186 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1187 ;; optimizers can more easily move this insn.
1188 (define_insn_and_split "*udivsi3_1"
1189 [(match_parallel 4 "float_operation"
1190 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1191 (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1192 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1193 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1194 (clobber (reg:SI 0))
1195 (clobber (reg:SI 1))
1196 (clobber (reg:SI GPR_IP))
1197 (clobber (reg:DI GPR_16))
1198 (clobber (reg:SI GPR_18))
1199 (clobber (reg:SI GPR_LR))
1200 (clobber (reg:CC CC_REGNUM))
1201 (clobber (reg:CC_FP CCFP_REGNUM))])]
1204 "&& reload_completed"
1205 [(set (reg:SI 0) (match_dup 1))
1206 (set (reg:SI 1) (match_dup 2))
1208 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1210 (clobber (reg:SI 1))
1211 (clobber (reg:SI GPR_IP))
1212 (clobber (reg:DI GPR_16))
1213 (clobber (reg:SI GPR_18))
1214 (clobber (reg:SI GPR_LR))
1215 (clobber (reg:CC CC_REGNUM))
1216 (clobber (reg:CC_FP CCFP_REGNUM))
1219 (set (match_dup 0) (reg:SI 0))]
1220 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1221 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1222 [(set_attr "type" "fp_sfunc")
1223 (set_attr "length" "16,24")])
1225 (define_insn "*udivsi3_2"
1226 [(match_parallel 1 "float_operation"
1227 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1228 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1229 (clobber (reg:SI 1))
1230 (clobber (reg:SI GPR_IP))
1231 (clobber (reg:DI GPR_16))
1232 (clobber (reg:SI GPR_18))
1233 (clobber (reg:SI GPR_LR))
1234 (clobber (reg:CC CC_REGNUM))
1235 (clobber (reg:CC_FP CCFP_REGNUM))])]
1238 [(set_attr "type" "fp_sfunc")])
1240 (define_expand "modsi3"
1242 [(set (match_operand:SI 0 "move_dest_operand" "")
1243 (mod:SI (match_operand:SI 1 "move_src_operand" "")
1244 (match_operand:SI 2 "move_src_operand" "")))
1246 (clobber (reg:SI 0))
1247 (clobber (reg:SI 1))
1248 (clobber (reg:SI 2))
1249 (clobber (reg:SI GPR_IP))
1250 (clobber (reg:DI GPR_16))
1251 (clobber (reg:DI GPR_18))
1252 (clobber (reg:SI GPR_LR))
1253 (clobber (reg:CC CC_REGNUM))
1254 (clobber (reg:CC_FP CCFP_REGNUM))])]
1256 "operands[3] = sfunc_symbol (\"__modsi3\");")
1258 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1259 ;; optimizers can more easily move this insn.
1260 (define_insn_and_split "*modsi3_1"
1261 [(match_parallel 4 "float_operation"
1262 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1263 (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1264 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1265 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1266 (clobber (reg:SI 0))
1267 (clobber (reg:SI 1))
1268 (clobber (reg:SI 2))
1269 (clobber (reg:SI GPR_IP))
1270 (clobber (reg:DI GPR_16))
1271 (clobber (reg:DI GPR_18))
1272 (clobber (reg:SI GPR_LR))
1273 (clobber (reg:CC CC_REGNUM))
1274 (clobber (reg:CC_FP CCFP_REGNUM))])]
1277 "&& reload_completed"
1278 [(set (reg:SI 0) (match_dup 1))
1279 (set (reg:SI 1) (match_dup 2))
1281 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1283 (clobber (reg:SI 2))
1284 (clobber (reg:SI GPR_IP))
1285 (clobber (reg:DI GPR_16))
1286 (clobber (reg:DI GPR_18))
1287 (clobber (reg:SI GPR_LR))
1288 (clobber (reg:CC CC_REGNUM))
1289 (clobber (reg:CC_FP CCFP_REGNUM))
1292 (set (match_dup 0) (reg:SI 0))]
1293 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1294 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1295 [(set_attr "type" "fp_sfunc")
1296 (set_attr "length" "16,24")])
1298 (define_insn "*modsi3_2"
1299 [(match_parallel 1 "float_operation"
1300 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1301 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1302 (clobber (reg:SI 2))
1303 (clobber (reg:SI GPR_IP))
1304 (clobber (reg:DI GPR_16))
1305 (clobber (reg:DI GPR_18))
1306 (clobber (reg:SI GPR_LR))
1307 (clobber (reg:CC CC_REGNUM))
1308 (clobber (reg:CC_FP CCFP_REGNUM))])]
1311 [(set_attr "type" "fp_sfunc")])
1313 (define_expand "umodsi3"
1315 [(set (match_operand:SI 0 "move_dest_operand" "")
1316 (umod:SI (match_operand:SI 1 "move_src_operand" "")
1317 (match_operand:SI 2 "move_src_operand" "")))
1319 (clobber (reg:SI 0))
1320 (clobber (reg:SI 1))
1321 (clobber (reg:SI 2))
1322 (clobber (reg:SI GPR_IP))
1323 (clobber (reg:DI GPR_16))
1324 (clobber (reg:SI GPR_LR))
1325 (clobber (reg:CC CC_REGNUM))
1326 (clobber (reg:CC_FP CCFP_REGNUM))])]
1328 "operands[3] = sfunc_symbol (\"__umodsi3\");")
1330 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1331 ;; optimizers can more easily move this insn.
1332 (define_insn_and_split "*umodsi3_1"
1333 [(match_parallel 4 "float_operation"
1334 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1335 (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1336 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1337 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1338 (clobber (reg:SI 0))
1339 (clobber (reg:SI 1))
1340 (clobber (reg:SI 2))
1341 (clobber (reg:SI GPR_IP))
1342 (clobber (reg:DI GPR_16))
1343 (clobber (reg:SI GPR_LR))
1344 (clobber (reg:CC CC_REGNUM))
1345 (clobber (reg:CC_FP CCFP_REGNUM))])]
1348 "&& reload_completed"
1349 [(set (reg:SI 0) (match_dup 1))
1350 (set (reg:SI 1) (match_dup 2))
1352 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1354 (clobber (reg:SI 2))
1355 (clobber (reg:SI GPR_IP))
1356 (clobber (reg:DI GPR_16))
1357 (clobber (reg:SI GPR_LR))
1358 (clobber (reg:CC CC_REGNUM))
1359 (clobber (reg:CC_FP CCFP_REGNUM))
1362 (set (match_dup 0) (reg:SI 0))]
1363 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1364 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1365 [(set_attr "type" "fp_sfunc")
1366 (set_attr "length" "16,24")])
1368 (define_insn "*umodsi3_2"
1369 [(match_parallel 1 "float_operation"
1370 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1371 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1372 (clobber (reg:SI 2))
1373 (clobber (reg:SI GPR_IP))
1374 (clobber (reg:DI GPR_16))
1375 (clobber (reg:SI GPR_LR))
1376 (clobber (reg:CC CC_REGNUM))
1377 (clobber (reg:CC_FP CCFP_REGNUM))])]
1380 [(set_attr "type" "fp_sfunc")])
1382 ; Disable interrupts.
1383 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1384 ; might have changed settings that we do not want to mess with.
1386 [(set (reg:SI CONFIG_REGNUM)
1387 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1390 [(set_attr "type" "flow")])
1392 ; Enable interrupts.
1393 ; Present CONTROL_REGNUM here to make sure it is live before the
1394 ; actual uses in floating point insns / calls are inserted.
1395 ; FWIW, interrupts also do mind what is in the control register.
1397 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1400 [(set_attr "type" "flow")])
1402 ; Floating point instructions require manipulating the control register.
1403 ; Manipulating the control register needs aritmetic.
1404 ; Arithmetic clobbers flags.
1405 ; The flags are in the status register, which also contains the alternate
1406 ; flag and the interrupt enable/disable bits.
1407 ; saving/restoring status and mixing up the order with gid/gie could
1409 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1410 ; away. But when we really need it, we must make sure that we don't change
1411 ; anything but the flags.
1412 ; N.B.: We could make the constant easier to load by inverting it, but
1413 ; then we'd need to clobber the saved value - and that would make optimizing
1414 ; away unneeded saves/restores harder / less likely.
1415 (define_expand "movcc"
1416 [(parallel [(set (match_operand:CC 0 "cc_move_operand" "")
1417 (match_operand:CC 1 "cc_move_operand" ""))
1419 (clobber (match_scratch:SI 3 "=X, &r"))])]
1421 "operands[2] = gen_int_mode (~0x10f0, SImode);")
1423 (define_insn "*movcc_i"
1424 [(set (match_operand:CC 0 "cc_move_operand" "=r,Rcc")
1425 (match_operand:CC 1 "cc_move_operand" "Rcc, r"))
1426 (use (match_operand:SI 2 "nonmemory_operand" "X, r"))
1427 (clobber (match_scratch:SI 3 "=X, &r"))]
1431 movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1432 [(set_attr "type" "flow")
1433 (set_attr "length" "20,4")])
1435 (define_insn_and_split "save_config"
1436 [(set (match_operand:SI 0 "gpr_operand" "=r") (reg:SI CONFIG_REGNUM))
1437 (use (reg:SI FP_NEAREST_REGNUM))
1438 (use (reg:SI FP_TRUNCATE_REGNUM))
1439 (use (reg:SI FP_ANYFP_REGNUM))]
1443 [(set (match_dup 0) (reg:SI CONFIG_REGNUM))])
1445 (define_insn_and_split "set_fp_mode"
1446 [(set (reg:SI FP_NEAREST_REGNUM)
1447 (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1448 (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1449 (set (reg:SI FP_ANYFP_REGNUM)
1450 (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1451 (use (match_operand:SI 2 "gpr_operand" "r"))
1452 (clobber (reg:CC CC_REGNUM))
1453 (clobber (match_scratch:SI 3 "=&r"))]
1456 "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1459 if (!reload_completed)
1460 emit_note (NOTE_INSN_DELETED);
1462 epiphany_expand_set_fp_mode (operands);
1467 ;; Boolean instructions.
1469 ;; We don't define the DImode versions as expand_binop does a good enough job.
1471 (define_insn "andsi3"
1472 [(set (match_operand:SI 0 "gpr_operand" "=r")
1473 (and:SI (match_operand:SI 1 "gpr_operand" "r")
1474 (match_operand:SI 2 "gpr_operand" "r")))
1475 (clobber (reg:CC CC_REGNUM))]
1479 (define_insn "iorsi3"
1480 [(set (match_operand:SI 0 "gpr_operand" "=r")
1481 (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1482 (match_operand:SI 2 "gpr_operand" "r")))
1483 (clobber (reg:CC CC_REGNUM))]
1487 (define_insn "xorsi3"
1488 [(set (match_operand:SI 0 "gpr_operand" "=r")
1489 (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1490 (match_operand:SI 2 "gpr_operand" "r")))
1491 (clobber (reg:CC CC_REGNUM))]
1495 (define_expand "one_cmplsi2"
1496 [(set (match_operand:SI 0 "gpr_operand" "")
1497 (xor:SI (match_operand:SI 1 "gpr_operand" "")
1501 if (epiphany_m1reg >= 0)
1502 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1504 emit_insn (gen_xorsi3 (operands[0], operands[1],
1505 force_reg (SImode, GEN_INT (-1))));
1509 ; Note that folding this pattern into the xorsi3 pattern would make combine
1511 (define_insn "one_cmplsi2_i"
1512 [(set (match_operand:SI 0 "gpr_operand" "=r")
1513 (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1514 (clobber (reg:CC CC_REGNUM))]
1515 "epiphany_m1reg >= 0"
1518 ;; Shift instructions.
1519 ;; In principle we could support arbitrary symbolic values as shift constant
1520 ;; (truncating the value appropriately), but that would require a suitable
1521 ;; relocation and assembler & linker support.
1522 (define_insn "ashrsi3"
1523 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1524 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1525 (match_operand:SI 2 "arith_operand" "r,K")))
1526 (clobber (reg:CC CC_REGNUM))]
1529 [(set_attr "length" "4")
1530 (set_attr "type" "shift")])
1532 (define_insn "ashrsi3_tst"
1533 [(set (reg:CC CC_REGNUM)
1535 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1536 (match_operand:SI 2 "arith_operand" "r,K"))
1538 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1539 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1542 [(set_attr "length" "4")
1543 (set_attr "type" "shift")])
1545 ;; Logical Shift Right
1546 (define_insn "lshrsi3"
1547 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1548 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1549 (match_operand:SI 2 "arith_operand" "r,K")))
1550 (clobber (reg:CC CC_REGNUM))]
1553 [(set_attr "length" "4")
1554 (set_attr "type" "shift")])
1556 (define_insn "lshrsi3_tst"
1557 [(set (reg:CC CC_REGNUM)
1559 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1560 (match_operand:SI 2 "arith_operand" "r,K"))
1562 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1563 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1566 [(set_attr "length" "4")
1567 (set_attr "type" "shift")])
1569 ;; Logical/Arithmetic Shift Left
1570 (define_insn "ashlsi3"
1571 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1572 (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1573 (match_operand:SI 2 "arith_operand" "r,K")))
1574 (clobber (reg:CC CC_REGNUM))]
1577 [(set_attr "length" "4")
1578 (set_attr "type" "shift")])
1580 (define_insn "*ashlsi_btst"
1581 [(set (reg:CC_N_NE CC_REGNUM)
1583 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1585 (match_operand 2 "const_int_operand" "K"))
1587 (clobber (match_scratch:SI 0 "=r"))]
1592 xop[0] = operands[0];
1593 xop[1] = operands[1];
1594 xop[2] = GEN_INT (31-INTVAL (operands[2]));
1595 output_asm_insn ("lsl %0,%1,%2", xop);
1600 (define_insn_and_split "zero_extendqisi2"
1601 [(set (match_operand:SI 0 "register_operand" "=r,r")
1602 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1603 (clobber (reg:CC CC_REGNUM))]
1609 ? true_regnum (operands[1]) >= 0
1610 : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1611 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1612 (clobber (reg:CC CC_REGNUM))])
1613 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1614 (clobber (reg:CC CC_REGNUM))])]
1615 "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1617 (define_insn "zero_extendhisi2"
1618 [(set (match_operand:SI 0 "register_operand" "=r,r")
1619 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1626 ;; Compare instructions.
1628 (define_insn "cmpsi_cc_insn"
1629 [(set (reg:CC CC_REGNUM)
1630 (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1631 (match_operand:SI 1 "arith_operand" "r,L")))
1632 (clobber (match_scratch:SI 2 "=r,r"))]
1635 [(set_attr "type" "compare")])
1637 (define_insn "sub_f"
1638 [(set (reg:CC CC_REGNUM)
1639 (compare:CC (match_operand:SI 1 "gpr_operand" "r,r")
1640 (match_operand:SI 2 "arith_operand" "r,L")))
1641 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1642 (minus:SI (match_dup 1) (match_dup 2)))]
1645 [(set_attr "type" "compare")])
1647 (define_insn "*sub_f_add_imm"
1648 [(set (reg:CC CC_REGNUM)
1649 (compare:CC (match_operand:SI 1 "gpr_operand" "r")
1650 (match_operand:SI 2 "arith_int_operand" "L")))
1651 (set (match_operand:SI 0 "gpr_operand" "=r")
1652 (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "L")))]
1653 "INTVAL (operands[2]) == -INTVAL (operands[3])"
1655 [(set_attr "type" "compare")])
1657 (define_expand "abssi2"
1658 [(set (match_dup 2) (const_int 0))
1659 (parallel [(set (reg:CC CC_REGNUM)
1660 (compare:CC (match_dup 2)
1661 (match_operand:SI 1 "nonmemory_operand" "")))
1663 (minus:SI (match_dup 2) (match_dup 1)))])
1664 (set (match_operand:SI 0 "gpr_operand" "=r")
1665 (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1669 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1671 (define_insn "*add_c"
1672 [(set (reg:CC_C_LTU CC_REGNUM)
1674 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1675 (match_operand:SI 2 "arith_operand" "r,L"))
1677 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1678 (plus:SI (match_dup 1) (match_dup 2)))]
1681 [(set_attr "type" "compare")])
1683 (define_insn "*add_c_rev"
1684 [(set (reg:CC_C_LTU CC_REGNUM)
1686 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1687 (match_operand:SI 2 "arith_operand" "r,L"))
1689 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1690 (plus:SI (match_dup 2) (match_dup 1)))]
1693 [(set_attr "type" "compare")])
1695 (define_insn "*sub_c"
1696 [(set (reg:CC_C_GTU CC_REGNUM)
1698 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1699 (match_operand:SI 2 "arith_operand" "r,L"))
1701 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1702 (minus:SI (match_dup 1) (match_dup 2)))]
1705 [(set_attr "type" "compare")])
1707 (define_insn "*sub_c_void"
1708 [(set (reg:CC_C_GTU CC_REGNUM)
1710 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1711 (match_operand:SI 2 "arith_operand" "r,L"))
1713 (clobber (match_scratch:SI 0 "=r,r"))]
1716 [(set_attr "type" "compare")])
1718 ; floating point comparisons
1720 (define_insn "*cmpsf_cc_insn"
1721 [(match_parallel 3 "float_operation"
1722 [(set (reg:CC_FP CCFP_REGNUM)
1723 (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1724 (match_operand:SF 1 "gpr_operand" "r")))
1725 (clobber (match_scratch:SF 2 "=r"))])]
1726 "!TARGET_SOFT_CMPSF"
1728 [(set_attr "type" "fp")
1729 (set_attr "fp_mode" "round_unknown")])
1731 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1732 ;; to allow the rtl loop optimizer to generate comparisons? OTOH
1733 ;; we want call_address_operand to enforce valid operands so that
1734 ;; combine won't do silly things, allowing instruction scheduling to do
1736 (define_insn "*cmpsf_eq"
1737 [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (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_gte"
1746 [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (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_LR))]
1752 [(set_attr "type" "sfunc")])
1754 (define_insn "*cmpsf_ord"
1755 [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1756 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1757 (clobber (reg:SI GPR_IP))
1758 (clobber (reg:SI GPR_16))
1759 (clobber (reg:SI GPR_LR))]
1762 [(set_attr "type" "sfunc")])
1764 (define_insn "*cmpsf_uneq"
1765 [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1766 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1767 (clobber (reg:SI GPR_IP))
1768 (clobber (reg:SI GPR_16))
1769 (clobber (reg:SI GPR_LR))]
1772 [(set_attr "type" "sfunc")])
1774 ;; conditional moves
1776 (define_expand "mov<mode>cc"
1777 [(set (match_operand:WMODE 0 "gpr_operand" "")
1778 (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1779 (match_operand:WMODE 2 "gpr_operand" "")
1780 (match_operand:WMODE 3 "gpr_operand" "")))]
1783 rtx cmp_op0 = XEXP (operands[1], 0);
1784 rtx cmp_op1 = XEXP (operands[1], 1);
1785 enum machine_mode cmp_in_mode;
1786 enum rtx_code code = GET_CODE (operands[1]);
1788 cmp_in_mode = GET_MODE (cmp_op0);
1789 if (cmp_in_mode == VOIDmode)
1790 cmp_in_mode = GET_MODE (cmp_op1);
1791 if (cmp_in_mode == VOIDmode)
1792 cmp_in_mode = SImode;
1793 /* If the operands are a better match when reversed, swap them now.
1794 This allows combine to see the proper comparison codes. */
1795 if (rtx_equal_p (operands[0], operands[2])
1796 && !rtx_equal_p (operands[0], operands[3]))
1798 rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1799 code = (FLOAT_MODE_P (GET_MODE (cmp_op0))
1800 ? reverse_condition_maybe_unordered (code)
1801 : reverse_condition (code));
1804 if (proper_comparison_operator (operands[1], VOIDmode))
1805 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1808 if (!currently_expanding_to_rtl)
1810 /* ??? It would seem safest to FAIL here, but that would defeat
1811 the purpose of having an if-conversion pass; its logic currently
1812 assumes that the backend should be safe to insert condition code
1813 setting instructions, as the same condition codes were presumably
1814 set by the if-conversion input code. */
1816 /* What mode to give as first operand to gen_compare_reg here is
1817 debatable. VOIDmode would be minimalist; telling gen_compare_reg
1818 to use the mode of CC_REGNUM (or putting it on the comparison
1819 operator afterwards) is also a logical choice. OTOH, by using
1820 <MODE>mode, we have mode combine opportunities with flag setting
1821 operations - if we get some. */
1823 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1827 (define_insn "*mov<mode>cc_insn"
1828 [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1829 (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1830 [(match_operand 4 "cc_operand") (const_int 0)])
1831 (match_operand:WMODE 1 "gpr_operand" "r")
1832 (match_operand:WMODE 2 "gpr_operand" "0")))]
1835 [(set_attr "type" "cmove")])
1838 [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
1839 (match_operand:WMODE 1 "" ""))
1840 (clobber (match_operand 8 "cc_operand"))])
1841 (match_operand 2 "" "")
1842 (set (match_operand:WMODE2 3 "gpr_operand" "")
1843 (match_operand:WMODE2 9 "gpr_operand" ""))
1845 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1846 [(match_operand 6 "cc_operand")
1847 (match_operand 7 "const0_operand")])
1848 (match_operand:WMODE2 4 "nonmemory_operand" "")
1850 "REGNO (operands[0]) == REGNO (operands[9])
1851 && peep2_reg_dead_p (3, operands[0])
1852 && !reg_set_p (operands[0], operands[2])
1853 && !reg_set_p (operands[3], operands[2])
1854 && !reg_overlap_mentioned_p (operands[3], operands[2])"
1855 [(parallel [(set (match_dup 10) (match_dup 1))
1856 (clobber (match_dup 8))])
1859 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1861 operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1862 <WMODE2:MODE>mode, 0);
1863 replace_rtx (operands[2], operands[9], operands[3]);
1864 replace_rtx (operands[2], operands[0], operands[10]);
1865 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
1869 [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
1870 (set (match_operand:WMODE 0 "gpr_operand" "")
1871 (match_operand:WMODE 1 "" ""))])
1872 (set (match_operand:WMODE2 3 "gpr_operand" "")
1873 (match_operand:WMODE2 4 "gpr_operand"))
1875 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
1877 (match_operand:WMODE 7 "const0_operand")])
1878 (match_operand:WMODE2 8 "gpr_operand")
1880 "REGNO (operands[0]) == REGNO (operands[8])
1881 && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
1882 && peep2_reg_dead_p (3, operands[6])
1883 && peep2_reg_dead_p (3, operands[0])
1884 && !reg_overlap_mentioned_p (operands[4], operands[3])"
1885 [(parallel [(set (match_dup 6) (match_dup 2))
1886 (set (match_dup 9) (match_dup 1))])
1888 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
1892 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
1893 GET_MODE (operands[6])),
1894 GET_MODE (operands[5]), operands[6], operands[7]);
1895 operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
1896 <WMODE2:MODE>mode, 0);
1899 ;; These control RTL generation for conditional jump insns
1901 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
1902 ;; they must allow const0_rtx for both comparison operands
1903 (define_expand "cbranchsi4"
1904 [(set (reg CC_REGNUM)
1905 (compare (match_operand:SI 1 "add_operand" "")
1906 (match_operand:SI 2 "arith_operand" "")))
1909 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
1911 (label_ref (match_operand 3 "" ""))
1915 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
1916 operands[1], operands[2]);
1917 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1921 (define_expand "cbranchsf4"
1922 [(set (reg CC_REGNUM)
1923 (compare (match_operand:SF 1 "arith_operand" "")
1924 (match_operand:SF 2 "arith_operand" "")))
1927 (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
1929 (label_ref (match_operand 3 "" ""))
1933 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
1934 operands[1], operands[2]);
1935 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
1939 ;; Now match both normal and inverted jump.
1941 (define_insn "branch_insn"
1943 (if_then_else (match_operator 1 "proper_comparison_operator"
1944 [(match_operand 2 "cc_operand")
1946 (label_ref (match_operand 0 "" ""))
1950 [(set_attr "type" "branch")])
1952 (define_insn "*rev_branch_insn"
1954 (if_then_else (match_operator 1 "proper_comparison_operator"
1955 [(reg CC_REGNUM) (const_int 0)])
1957 (label_ref (match_operand 0 "" ""))))]
1960 [(set_attr "type" "branch")])
1962 ;; Unconditional and other jump instructions.
1965 [(set (pc) (label_ref (match_operand 0 "" "")))]
1968 [(set_attr "type" "uncond_branch")])
1970 (define_insn "indirect_jump"
1971 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
1974 [(set_attr "type" "uncond_branch")])
1976 (define_expand "tablejump"
1977 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
1978 (use (label_ref (match_operand 1 "" "")))])]
1981 /* In PIC mode, the table entries are stored PC relative.
1982 Convert the relative address to an absolute address. */
1985 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
1987 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1988 op1, NULL_RTX, 0, OPTAB_DIRECT);
1992 (define_insn "*tablejump_internal"
1993 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
1994 (use (label_ref (match_operand 1 "" "")))]
1997 [(set_attr "type" "uncond_branch")])
1999 (define_insn "*tablejump_hi_internal"
2000 [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
2001 (use (label_ref (match_operand 1 "" "")))]
2002 "optimize_size && TARGET_SMALL16"
2004 [(set_attr "type" "uncond_branch")])
2007 (define_expand "call"
2008 ;; operands[1] is stack_size_rtx
2009 ;; operands[2] is next_arg_register
2010 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2011 (match_operand 1 "" ""))
2012 (clobber (reg:SI GPR_LR))])]
2015 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2017 if (!call_operand (operands[1], VOIDmode))
2019 = change_address (operands[0], VOIDmode,
2020 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2021 if (epiphany_uninterruptible_p (current_function_decl)
2022 != target_uninterruptible)
2024 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2028 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2029 gen_rtx_CLOBBER (VOIDmode,
2030 gen_rtx_REG (SImode, GPR_LR)))));
2031 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2036 (define_insn "*call_i"
2037 [(match_parallel 2 "float_operation"
2038 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
2039 (match_operand 1 "" ""))
2040 (clobber (reg:SI GPR_LR))])]
2043 [(set_attr "type" "call")])
2045 (define_expand "sibcall"
2046 ;; operands[1] is stack_size_rtx
2047 ;; operands[2] is next_arg_register
2048 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2049 (match_operand 1 "" ""))
2053 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2055 if (!call_operand (operands[1], VOIDmode))
2057 = change_address (operands[0], VOIDmode,
2058 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2059 if (epiphany_uninterruptible_p (current_function_decl)
2060 != target_uninterruptible)
2062 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2066 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2068 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2073 (define_insn "*sibcall_i"
2074 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
2075 (match_operand 1 "" ""))
2081 [(set_attr "type" "call")])
2083 (define_expand "call_value"
2084 ;; operand 2 is stack_size_rtx
2085 ;; operand 3 is next_arg_register
2086 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2087 (call (match_operand:SI 1 "call_operand" "")
2088 (match_operand 2 "" "")))
2089 (clobber (reg:SI GPR_LR))])]
2092 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2094 if (!call_operand (operands[1], VOIDmode))
2096 = change_address (operands[1], VOIDmode,
2097 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2098 if (epiphany_uninterruptible_p (current_function_decl)
2099 != target_uninterruptible)
2101 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2105 gen_rtvec (2, gen_rtx_SET
2106 (VOIDmode, operands[0],
2107 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2108 gen_rtx_CLOBBER (VOIDmode,
2109 gen_rtx_REG (SImode, GPR_LR)))));
2110 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2115 (define_insn "*call_value_i"
2116 [(match_parallel 3 "float_operation"
2117 [(set (match_operand 0 "gpr_operand" "=r,r")
2118 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2119 (match_operand 2 "" "")))
2120 (clobber (reg:SI GPR_LR))])]
2123 [(set_attr "type" "call")
2124 (set_attr "length" "4")])
2126 (define_expand "sibcall_value"
2127 ;; operand 2 is stack_size_rtx
2128 ;; operand 3 is next_arg_register
2129 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2130 (call (match_operand:SI 1 "call_operand" "")
2131 (match_operand 2 "" "")))
2135 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2137 if (!call_operand (operands[1], VOIDmode))
2139 = change_address (operands[1], VOIDmode,
2140 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2141 if (epiphany_uninterruptible_p (current_function_decl)
2142 != target_uninterruptible)
2144 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2148 gen_rtvec (2, gen_rtx_SET
2149 (VOIDmode, operands[0],
2150 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2152 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2157 (define_insn "*sibcall_value_i"
2158 [(set (match_operand 0 "gpr_operand" "=r,r")
2159 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2160 (match_operand 2 "" "")))
2166 [(set_attr "type" "call")
2167 (set_attr "length" "4")])
2169 (define_expand "prologue"
2173 epiphany_expand_prologue ();
2177 (define_expand "epilogue"
2181 epiphany_expand_epilogue (0);
2185 (define_expand "sibcall_epilogue"
2189 epiphany_expand_epilogue (1);
2193 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2194 ; in the prologue / epilogue expanders how many times lr is set.
2195 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2196 ; any explicit use of lr will cause it to be saved; hence we cannot
2197 ; represent the blink use in return / sibcall instructions themselves, and
2198 ; instead have to show it in EPILOGUE_USES.
2199 (define_insn "return_i"
2203 [(set_attr "type" "uncond_branch")])
2205 (define_insn "return_internal_interrupt"
2207 (unspec_volatile [(const_int 0)] 1)]
2210 [(set_attr "type" "uncond_branch")])
2212 (define_insn "stack_adjust_add"
2213 [(set (reg:SI GPR_SP)
2214 (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2215 (clobber (reg:CC CC_REGNUM))
2216 (clobber (reg:SI STATUS_REGNUM))
2217 (clobber (match_operand:BLK 1 "memory_operand" "=m"))]
2221 (define_insn "stack_adjust_mov"
2222 [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2223 (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2226 [(set_attr "type" "move")])
2228 (define_insn "stack_adjust_str"
2229 [(set (match_operand 0 "stacktop_operand" "=m")
2230 (match_operand 1 "any_gpr_operand" "r"))
2231 (set (reg:SI GPR_SP)
2232 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2233 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2236 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2237 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2239 [(set_attr "type" "store")])
2241 (define_insn "stack_adjust_ldr"
2242 [(set (match_operand:SI 0 "gpr_operand" "=r")
2243 (match_operand:SI 1 "stacktop_operand" "m"))
2244 (set (reg:SI GPR_SP)
2245 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2246 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2249 [(set_attr "type" "load")])
2251 ;; Define some fake vector operations so that the vectorizer is happy to use
2252 ;; 64 bit loads/stores.
2253 (define_expand "vec_unpacks_lo_v4hi"
2254 [(match_operand:V2SI 0 "gpr_operand")
2255 (match_operand:V4HI 1 "gpr_operand")]
2258 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2259 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2261 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2263 if (reg_overlap_mentioned_p (outl, in))
2264 in = copy_to_mode_reg (SImode, in);
2265 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2266 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2267 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2271 (define_expand "vec_unpacks_hi_v4hi"
2272 [(match_operand:V2SI 0 "gpr_operand")
2273 (match_operand:V4HI 1 "gpr_operand")]
2276 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2277 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2279 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2281 if (reg_overlap_mentioned_p (outl, in))
2282 in = copy_to_mode_reg (SImode, in);
2283 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2284 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2285 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2289 (define_code_iterator addsub [plus minus])
2291 (define_code_iterator alu_binop
2292 [plus minus and ior xor])
2294 (define_code_attr insn_opname
2295 [(plus "add") (minus "sub") (mult "mul") (div "div")
2296 (and "and") (ior "ior") (xor "xor")])
2298 ; You might think that this would work better as a define_expand, but
2299 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2300 ; We need to keep inputs and outputs as register pairs if we want to
2301 ; get sensible register allocation for double-word load and store operations.
2302 (define_insn_and_split "<insn_opname>v2si3"
2303 [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2304 (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2305 (match_operand:V2SI 2 "gpr_operand" "r")))
2306 (clobber (reg:CC CC_REGNUM))]
2309 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2312 rtx o0l, o0h, o1l, o1h, o2l, o2h;
2314 o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2315 o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2316 o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2317 o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2318 o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2319 o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2320 if (reg_overlap_mentioned_p (o0l, o1h))
2321 o1h = copy_to_mode_reg (SImode, o1h);
2322 if (reg_overlap_mentioned_p (o0l, o2h))
2323 o2h = copy_to_mode_reg (SImode, o2h);
2324 emit_insn (gen_<insn_opname>si3 (o0l, o1l, o2l));
2325 emit_insn (gen_<insn_opname>si3 (o0h, o1h, o2h));
2328 [(set_attr "length" "8")])
2330 (define_expand "<insn_opname>v2sf3"
2332 [(set (match_operand:V2SF 0 "gpr_operand" "")
2333 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2334 (match_operand:V2SF 2 "gpr_operand" "")))
2335 (clobber (reg:CC_FP CCFP_REGNUM))])])
2337 (define_insn_and_split "<insn_opname>v2sf3_i"
2338 [(match_parallel 3 "float_operation"
2339 [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2340 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2341 (match_operand:V2SF 2 "gpr_operand" "r")))
2342 (clobber (reg:CC_FP CCFP_REGNUM))])]
2345 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2347 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2348 (clobber (reg:CC_FP CCFP_REGNUM))
2352 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2353 (clobber (reg:CC_FP CCFP_REGNUM))
2357 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2358 operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2359 operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2361 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2363 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2365 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2366 if (!reload_completed)
2368 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2369 operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2370 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2371 operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2372 emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2373 emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2376 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2377 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2378 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2379 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2381 [(set_attr "length" "8")
2382 (set_attr "type" "v2fp")])
2384 (define_expand "mul<mode>3"
2386 [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2387 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2388 (match_operand:DWV2MODE 2 "gpr_operand" "")))
2389 (clobber (reg:CC_FP CCFP_REGNUM))])])
2391 (define_insn_and_split "mul<mode>3_i"
2392 [(match_parallel 3 "float_operation"
2393 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2394 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2395 (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2396 (clobber (reg:CC_FP CCFP_REGNUM))])]
2399 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2401 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2402 (clobber (reg:CC_FP CCFP_REGNUM))
2406 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2407 (clobber (reg:CC_FP CCFP_REGNUM))
2412 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2414 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2416 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2417 operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2418 <MODE>mode, UNITS_PER_WORD);
2419 operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2420 <MODE>mode, UNITS_PER_WORD);
2421 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2422 <MODE>mode, UNITS_PER_WORD);
2423 if (!reload_completed)
2425 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2426 operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2427 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2428 operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2429 emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2430 emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2433 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2434 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2435 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2436 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2438 [(set_attr "length" "8")
2439 (set_attr "type" "<vmode_fp_type>")])
2441 (define_insn_and_split "*fmadd<mode>_combine"
2442 [(match_parallel 4 "float_operation"
2443 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2444 (plus:DWV2MODE (mult:<MODE>
2445 (match_operand:<MODE> 1 "gpr_operand" "r")
2446 (match_operand:<MODE> 2 "gpr_operand" "r"))
2447 (match_operand:<MODE> 3 "gpr_operand" "0")))
2448 (clobber (reg:CC_FP CCFP_REGNUM))])]
2449 "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2451 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2454 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2456 (clobber (reg:CC_FP CCFP_REGNUM))
2461 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2463 (clobber (reg:CC_FP CCFP_REGNUM))
2468 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2470 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2472 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2474 = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2475 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2476 <MODE>mode, UNITS_PER_WORD);
2477 operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2478 <MODE>mode, UNITS_PER_WORD);
2479 operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2480 <MODE>mode, UNITS_PER_WORD);
2481 operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2482 <MODE>mode, UNITS_PER_WORD);
2483 if (!reload_completed)
2485 if (reg_overlap_mentioned_p (operands[5], operands[10]))
2486 operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2487 if (reg_overlap_mentioned_p (operands[5], operands[11]))
2488 operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2489 if (reg_overlap_mentioned_p (operands[5], operands[12]))
2490 operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2491 emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2493 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2497 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2498 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2499 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2500 operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2501 operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2503 [(set_attr "length" "8")
2504 (set_attr "type" "<vmode_fp_type>")])
2506 (define_expand "vec_set<mode>"
2507 [(match_operand:DWV2MODE 0 "register_operand")
2508 (match_operand:<vmode_PART> 1 "register_operand")
2509 (match_operand 2 "const_int_operand" "")]
2513 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2514 UNITS_PER_WORD * INTVAL (operands[2]));
2515 emit_move_insn (operands[0], operands[1]);
2519 (define_expand "movmisalign<mode>"
2520 [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "")
2521 (match_operand:DWV2MODE 1 "general_operand" ""))]
2524 rtx op00, op01, op10, op11;
2526 op00 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2527 op01 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2529 op10 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2530 op11 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode,
2532 emit_move_insn (op00, op10);
2533 emit_move_insn (op01, op11);
2541 [(set_attr "type" "flow")])