1 ;; Machine description of the Adaptiva epiphany cpu for GNU C compiler
2 ;; Copyright (C) 1994-2014 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.
33 (ARG_POINTER_REGNUM 64)
34 (FRAME_POINTER_REGNUM 65)
35 (CC_REGNUM 66) ;; 66 or 17
36 (CCFP_REGNUM 67) ;; 67 or 18
43 (FP_NEAREST_REGNUM 74)
44 (FP_TRUNCATE_REGNUM 75)
46 (UNKNOWN_REGNUM 77) ; used for addsi3_r and friends
47 ; We represent the return address as an unspec rather than a reg.
48 ; If we used a reg, we could use register elimination, but eliminating
49 ; to GPR_LR would make the latter visible to dataflow, thus making it
50 ; harder to determine when it must be saved.
51 (UNSPEC_RETURN_ADDR 0)
57 ;; Insn type. Used to default other attribute values.
60 "move,load,store,cmove,unary,compare,shift,mul,uncond_branch,branch,call,fp,fp_int,v2fp,misc,sfunc,fp_sfunc,flow"
61 (const_string "misc"))
63 ;; Length (in # bytes)
65 (define_attr "length" "" (const_int 4))
67 ;; The length here is the length of a single asm.
69 (define_asm_attributes
70 [(set_attr "length" "4")
71 (set_attr "type" "misc")])
73 ;; pipeline model; so far we have only one.
74 (define_attr "pipe_model" "epiphany" (const_string "epiphany"))
76 (define_attr "rounding" "trunc,nearest"
77 (cond [(ne (symbol_ref "TARGET_ROUND_NEAREST") (const_int 0))
78 (const_string "nearest")]
79 (const_string "trunc")))
81 (define_attr "fp_mode" "round_unknown,round_nearest,round_trunc,int,caller,none"
82 (cond [(eq_attr "type" "fp,v2fp,fp_sfunc")
83 (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_rounding")
84 (eq_attr "type" "call")
85 (symbol_ref "(enum attr_fp_mode) epiphany_normal_fp_mode")
86 (eq_attr "type" "fp_int")
88 (const_string "none")))
90 (include "epiphany-sched.md")
92 (include "predicates.md")
93 (include "constraints.md")
95 ;; modes that are held in a single register, and hence, a word.
96 (define_mode_iterator WMODE [SI SF HI QI V2HI V4QI])
97 (define_mode_iterator WMODE2 [SI SF HI QI V2HI V4QI])
99 ;; modes that are held in a two single registers
100 (define_mode_iterator DWMODE [DI DF V2SI V2SF V4HI V8QI])
102 ;; Double-word mode made up of two single-word mode values.
103 (define_mode_iterator DWV2MODE [V2SI V2SF])
104 (define_mode_attr vmode_part [(V2SI "si") (V2SF "sf")])
105 (define_mode_attr vmode_PART [(V2SI "SI") (V2SF "SF")])
106 (define_mode_attr vmode_fp_type [(V2SI "fp_int") (V2SF "fp")])
107 (define_mode_attr vmode_ccmode [(V2SI "CC") (V2SF "CC_FP")])
108 (define_mode_attr vmode_cc [(V2SI "CC_REGNUM") (V2SF "CCFP_REGNUM")])
110 ;; Move instructions.
112 (define_expand "mov<mode>"
113 [(set (match_operand:WMODE 0 "general_operand" "")
114 (match_operand:WMODE 1 "general_operand" ""))]
117 if (<MODE>mode == V4QImode || <MODE>mode == V2HImode)
119 operands[0] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
120 operands[1] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
121 emit_insn (gen_movsi (operands[0], operands[1]));
124 if (GET_CODE (operands[0]) == MEM)
125 operands[1] = force_reg (<MODE>mode, operands[1]);
126 if (<MODE>mode == SImode
127 && (operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx))
129 rtx reg = operands[0];
132 reg = gen_reg_rtx (SImode);
133 emit_insn (gen_move_frame (reg, operands[1]));
135 if (operands[0] == reg)
140 (define_insn "*movqi_insn"
141 [(set (match_operand:QI 0 "move_dest_operand" "=Rcs, r, r,r,m")
142 (match_operand:QI 1 "move_src_operand" "Rcs,rU16,Cal,m,r"))]
144 "gpr_operand (operands[0], QImode)
145 || gpr_operand (operands[1], QImode)"
152 [(set_attr "type" "move,move,move,load,store")])
154 (define_insn_and_split "*movhi_insn"
155 [(set (match_operand:HI 0 "move_dest_operand" "=r, r,r,m")
156 (match_operand:HI 1 "move_src_operand""rU16,Cal,m,r"))]
157 "gpr_operand (operands[0], HImode)
158 || gpr_operand (operands[1], HImode)"
164 "reload_completed && CONSTANT_P (operands[1])
165 && !satisfies_constraint_U16 (operands[1]) && TARGET_SPLIT_LOHI"
166 [(set (match_dup 2) (match_dup 3))]
167 "operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
168 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);"
169 [(set_attr "type" "move,move,load,store")])
171 ;; We use a special pattern for a move from the frame pointer to
172 ;; show the flag clobber that is needed when this move is changed
173 ;; to an add by register elimination.
174 ;; ??? A pseudo register might be equivalent to a function invariant,
175 ;; and thus placed by reload into reg_equiv_invariant; if the pseudo
176 ;; does not get a hard register, we then end up with the function
177 ;; invariant in its place, i.e. an unexpected clobber of the flags
180 ;; N.B. operand 1 is an operand so that reload will perform elimination.
182 ;; The post-reload pattern recognition and splitting is done in frame_move_1.
183 (define_insn "move_frame"
184 [(set (match_operand:SI 0 "gpr_operand" "=r")
185 (match_operand:SI 1 "register_operand" "r"))
186 (clobber (reg:CC CC_REGNUM))]
187 "operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx"
190 (define_insn "movsi_high"
191 [(set (match_operand:SI 0 "gpr_operand" "+r")
192 (ior:SI (and:SI (match_dup 0) (const_int 65535))
193 (high:SI (match_operand:SI 1 "move_src_operand" "i"))))]
195 "movt %0, %%high(%1)"
196 [(set_attr "type" "move")
197 (set_attr "length" "4")])
199 (define_insn "movsi_lo_sum"
200 [(set (match_operand:SI 0 "gpr_operand" "=r")
201 (lo_sum:SI (const_int 0)
202 (match_operand:SI 1 "move_src_operand" "i")))]
205 [(set_attr "type" "move")
206 (set_attr "length" "4")])
208 (define_insn_and_split "*movsi_insn"
209 [(set (match_operand:SI 0 "move_dest_operand"
210 "= r, r, r, r, r, r, m, r, Rct")
211 (match_operand:SI 1 "move_src_operand"
212 "rU16Rra,Cm1,Cl1,Cr1,Cal,mSra,rRra,Rct,r"))]
213 "gpr_operand (operands[0], SImode)
214 || gpr_operand (operands[1], SImode)
215 || satisfies_constraint_Sra (operands[1])"
217 switch (which_alternative)
219 case 0: return "mov %0,%1";
220 case 1: return "add %0,%-,(1+%1)";
221 case 2: operands[1] = GEN_INT (exact_log2 (-INTVAL (operands[1])));
222 return "lsl %0,%-,%1";
223 case 3: operands[1] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
224 return "lsr %0,%-,%1";
225 case 4: return "mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1";
226 case 5: return "ldr %0,%C1";
227 case 6: return "str %1,%C0";
228 case 7: return "movfs %0,%1";
229 case 8: return "movts %0,%1";
230 default: gcc_unreachable ();
233 "reload_completed && CONSTANT_P (operands[1])
234 && !satisfies_constraint_U16 (operands[1])
235 && !satisfies_constraint_Cm1 (operands[1])
236 && !satisfies_constraint_Cl1 (operands[1])
237 && !satisfies_constraint_Cr1 (operands[1])
238 && TARGET_SPLIT_LOHI"
239 [(match_dup 2) (match_dup 3)]
240 "operands[2] = gen_movsi_lo_sum (operands[0], operands[1]);
241 operands[3] = gen_movsi_high (operands[0], operands[1]);"
242 [(set_attr "type" "move,misc,misc,misc,move,load,store,flow,flow")
243 (set_attr "length" "4,4,4,4,8,4,4,4,4")])
246 [(set (match_operand:SI 0 "nonimmediate_operand")
247 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
248 "reload_completed && !MACHINE_FUNCTION (cfun)->lr_clobbered"
249 [(set (match_dup 0) (reg:SI GPR_LR))])
252 [(set (match_operand:SI 0 "gpr_operand")
253 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))]
255 [(set (match_dup 0) (match_dup 1))]
257 emit_insn (gen_reload_insi_ra (operands[0], operands[1]));
261 (define_expand "reload_insi_ra"
262 [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))]
266 = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx);
268 if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
271 epiphany_expand_prologue ();
272 if (!MACHINE_FUNCTION (cfun)->lr_slot_known)
273 epiphany_expand_epilogue (0);
275 gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_known);
277 addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset);
278 operands[1] = gen_frame_mem (SImode, addr);
281 ;; If the frame pointer elimination offset is zero, we'll use this pattern.
282 ;; Note that the splitter can accept any gpr in operands[1]; this is
283 ;; necessary, (e.g. for compile/20021015-1.c -O0,)
284 ;; because when register elimination cannot be done with the constant
285 ;; as an immediate operand of the add instruction, reload will resort to
286 ;; loading the constant into a reload register, using gen_add2_insn to add
287 ;; the stack pointer, and then use the reload register as new source in
288 ;; the move_frame pattern.
289 (define_insn_and_split "*move_frame_1"
290 [(set (match_operand:SI 0 "gpr_operand" "=r")
291 (match_operand:SI 1 "gpr_operand" "r"))
292 (clobber (reg:CC CC_REGNUM))]
293 "(reload_in_progress || reload_completed)
294 && (operands[1] == stack_pointer_rtx
295 || operands[1] == hard_frame_pointer_rtx)"
297 "reload_in_progress || reload_completed"
298 [(set (match_dup 0) (match_dup 1))])
300 (define_expand "mov<mode>"
301 [(set (match_operand:DWMODE 0 "general_operand" "")
302 (match_operand:DWMODE 1 "general_operand" ""))]
306 if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT
307 || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
309 if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)
311 rtx o0l, o0h, o1l, o1h;
313 o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0);
314 o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode,
316 o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0);
317 o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode,
319 if (reg_overlap_mentioned_p (o0l, o1h))
321 emit_move_insn (o0h, o1h);
322 emit_move_insn (o0l, o1l);
326 emit_move_insn (o0l, o1l);
327 emit_move_insn (o0h, o1h);
331 /* lower_subreg has a tendency to muck up vectorized code.
332 To protect the wide memory accesses, we must use same-size
334 if (epiphany_vect_align != 4 /* == 8 */
335 && !reload_in_progress
336 && (GET_CODE (operands[0]) == MEM || GET_CODE (operands[1]) == MEM)
337 && !misaligned_operand (operands[1], <MODE>mode)
338 && (GET_CODE (operands[0]) != SUBREG
339 || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
340 != GET_MODE_SIZE (<MODE>mode)
341 && GET_CODE (operands[1]) != SUBREG)))
344 = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0);
346 = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0);
347 emit_insn (gen_movdi (operands[0], operands[1]));
351 /* Everything except mem = const or mem = mem can be done easily. */
353 if (GET_CODE (operands[0]) == MEM)
354 operands[1] = force_reg (<MODE>mode, operands[1]);
357 (define_insn_and_split "*mov<mode>_insn"
358 [(set (match_operand:DWMODE 0 "move_dest_operand" "=r, r,r,m")
359 (match_operand:DWMODE 1 "move_double_src_operand" "r,CalE,m,r"))]
360 "(gpr_operand (operands[0], <MODE>mode)
361 || gpr_operand (operands[1], <MODE>mode))"
368 && (((!MEM_P (operands[0]) || misaligned_operand (operands[0], <MODE>mode))
369 && (!MEM_P (operands[1])
370 || misaligned_operand (operands[1], <MODE>mode)))
371 || epiphany_vect_align == 4)"
372 [(set (match_dup 2) (match_dup 3))
373 (set (match_dup 4) (match_dup 5))]
375 int word0 = 0, word1 = UNITS_PER_WORD;
377 if (post_modify_operand (operands[0], <MODE>mode)
378 || post_modify_operand (operands[1], <MODE>mode))
379 word0 = UNITS_PER_WORD, word1 = 0;
381 operands[2] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word0);
382 operands[3] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word0);
383 operands[4] = simplify_gen_subreg (SImode, operands[0], <MODE>mode, word1);
384 operands[5] = simplify_gen_subreg (SImode, operands[1], <MODE>mode, word1);
385 if (post_modify_operand (operands[0], <MODE>mode))
387 = change_address (operands[2], VOIDmode,
388 plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0),
390 if (post_modify_operand (operands[1], <MODE>mode))
392 = change_address (operands[3], VOIDmode,
393 plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0),
396 [(set_attr "type" "move,move,load,store")
397 (set_attr "length" "8,16,4,4")])
400 (define_insn_and_split "*movsf_insn"
401 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
402 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
403 "gpr_operand (operands[0], SFmode)
404 || gpr_operand (operands[1], SFmode)"
407 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1
410 "reload_completed && CONSTANT_P (operands[1]) && TARGET_SPLIT_LOHI"
411 [(set (match_dup 2) (match_dup 3))]
412 "operands[2] = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
413 operands[3] = simplify_gen_subreg (SImode, operands[1], SFmode, 0);"
414 [(set_attr "type" "move,move,load,store")
415 (set_attr "length" "4,8,4,4")])
417 (define_expand "addsi3"
418 [(set (match_operand:SI 0 "add_reg_operand" "")
419 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
420 (match_operand:SI 2 "add_operand" "")))]
424 if (reload_in_progress || reload_completed)
425 emit_insn (gen_addsi3_r (operands[0], operands[1], operands[2]));
426 else if (TARGET_FP_IARITH && add_reg_operand (operands[2], SImode))
427 emit_insn (gen_iadd (operands[0], operands[1], operands[2]));
429 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2]));
433 ; The default case of epiphany_print_operand emits IMMEDIATE_PREFIX
434 ; where appropriate; however, 'n' is processed by output_asm_insn
435 ; which doesn't, so we have to explicitly emit the '# in the
436 ; r/r/CnL output template alternative.
437 (define_insn "addsi3_i"
438 [(set (match_operand:SI 0 "add_reg_operand" "=r,r")
439 (plus:SI (match_operand:SI 1 "add_reg_operand" "%r,r")
440 (match_operand:SI 2 "add_operand" "rL,CnL")))
441 (clobber (reg:CC CC_REGNUM))]
446 [(set_attr "type" "misc")])
448 ; We use a clobber of UNKNOWN_REGNUM here so that the peephole optimizers
449 ; can identify the unresolved flags clobber problem, and also to
450 ; avoid unwanted matches.
452 ; At -O0 / -O1 we don't peephole all instances away. We could get better
453 ; debug unwinding through the emitted code if we added a splitter.
454 (define_insn "addsi3_r"
455 [(set (match_operand:SI 0 "gpr_operand" "=r")
456 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
457 (match_operand:SI 2 "nonmemory_operand" "rCar")))
458 (clobber (reg:CC UNKNOWN_REGNUM))]
459 "reload_in_progress || reload_completed"
462 ^ (true_regnum (operands[0]) & 1)
463 ^ (true_regnum (operands[1]) & 2)
464 ^ (true_regnum (operands[2]) & 4));
465 asm_fprintf (asm_out_file, "\tstr r%d,[sp,#0]\n", scratch);
466 asm_fprintf (asm_out_file, "\tmovfs r%d,status\n", scratch);
467 output_asm_insn ("add %0,%1,%2", operands);
468 asm_fprintf (asm_out_file, "\tmovts status,r%d\n", scratch);
469 asm_fprintf (asm_out_file, "\tldr r%d,[sp,#0]\n", scratch);
472 [(set_attr "length" "20")
473 (set_attr "type" "misc")])
475 ;; reload uses gen_addsi2 because it doesn't understand the need for
478 [(set (match_operand:SI 0 "gpr_operand" "")
479 (match_operand:SI 1 "const_int_operand" ""))
480 (parallel [(set (match_dup 0)
481 (plus:SI (match_dup 0)
482 (match_operand:SI 2 "gpr_operand")))
483 (clobber (reg:CC UNKNOWN_REGNUM))])]
484 "satisfies_constraint_L (operands[1])
485 || ((operands[2] == stack_pointer_rtx
486 || (operands[2] == hard_frame_pointer_rtx && frame_pointer_needed))
487 && !peep2_regno_dead_p (2, CC_REGNUM)
488 && satisfies_constraint_Car (operands[1]))"
489 [(parallel [(set (match_dup 0)
490 (plus:SI (match_dup 2) (match_dup 1)))
491 (clobber (reg:CC UNKNOWN_REGNUM))])]
493 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html
494 ;; "peep2_rescan = true;"
498 [(match_parallel 5 ""
499 [(set (match_operand 3 "cc_operand" "") (match_operand 4 "" ""))])
500 (parallel [(set (match_operand:SI 0 "gpr_operand" "")
501 (plus:SI (match_operand:SI 1 "gpr_operand" "")
502 (match_operand:SI 2 "nonmemory_operand" "")))
503 (clobber (reg:CC UNKNOWN_REGNUM))])]
504 "REGNO (operands[3]) == CC_REGNUM
505 && (gpr_operand (operands[2], SImode)
506 || satisfies_constraint_L (operands[2]))
507 && !reg_overlap_mentioned_p (operands[0], operands[5])
508 && !reg_set_p (operands[1], operands[5])
509 && !reg_set_p (operands[2], operands[5])"
510 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
511 (plus:SI (match_operand:SI 1 "gpr_operand" "")
512 (match_operand:SI 2 "nonmemory_operand" "")))
513 (clobber (reg:CC CC_REGNUM))])
518 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
519 (plus:SI (match_operand:SI 1 "gpr_operand" "")
520 (match_operand:SI 2 "nonmemory_operand" "")))
521 (clobber (reg:CC UNKNOWN_REGNUM))])]
522 "peep2_regno_dead_p (1, CC_REGNUM)
523 && (gpr_operand (operands[2], SImode)
524 || satisfies_constraint_L (operands[2]))"
525 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
526 (plus:SI (match_operand:SI 1 "gpr_operand" "")
527 (match_operand:SI 2 "nonmemory_operand" "")))
528 (clobber (reg:CC CC_REGNUM))])]
532 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
533 (plus:SI (reg:SI GPR_SP)
534 (match_operand:SI 1 "nonmemory_operand" "")))
535 (clobber (reg:CC UNKNOWN_REGNUM))])]
536 "(REG_P (operands[1]) && !reg_overlap_mentioned_p (operands[0], operands[1]))
537 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1])"
538 [(set (match_dup 0) (reg:SI GPR_SP))
539 (set (mem:WMODE (post_modify (match_dup 0)
540 (plus:SI (match_dup 0) (match_dup 1))))
547 [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
548 (plus:SI (reg:SI GPR_FP)
549 (match_operand:SI 1 "nonmemory_operand" "")))
550 (clobber (reg:CC UNKNOWN_REGNUM))])
551 (match_scratch:WMODE 2 "r")]
552 "frame_pointer_needed
553 && ((REG_P (operands[1])
554 && !reg_overlap_mentioned_p (operands[0], operands[1]))
555 || RTX_OK_FOR_OFFSET_P (<MODE>mode, operands[1]))"
556 [(set (match_dup 0) (reg:SI GPR_FP))
558 (mem:WMODE (post_modify (match_dup 0)
559 (plus:SI (match_dup 0) (match_dup 1)))))]
562 (define_expand "subsi3"
563 [(set (match_operand:SI 0 "gpr_operand" "")
564 (plus:SI (match_operand:SI 1 "add_reg_operand" "")
565 (match_operand:SI 2 "arith_operand" "")))]
569 gcc_assert (!reload_in_progress && !reload_completed);
571 if (TARGET_FP_IARITH)
572 emit_insn (gen_isub (operands[0], operands[1], operands[2]));
574 emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2]));
578 (define_insn "subsi3_i"
579 [(set (match_operand:SI 0 "gpr_operand" "=r")
580 (minus:SI (match_operand:SI 1 "add_reg_operand" "r")
581 (match_operand:SI 2 "arith_operand" "rL")))
582 (clobber (reg:CC CC_REGNUM))]
585 [(set_attr "type" "misc")])
587 ; After mode-switching, floating point operations, fp_sfuncs and calls
588 ; must exhibit the use of the control register, lest the setting of the
589 ; control register could be deleted or moved. OTOH a use of a hard register
590 ; greatly counfounds optimizers like the rtl loop optimizers or combine.
591 ; Therefore, we put an extra pass immediately after the mode switching pass
592 ; that inserts the USEs of the control registers, and sets a flag in struct
593 ; machine_function that float_operation can henceforth only match with that
597 (define_expand "addsf3"
599 [(set (match_operand:SF 0 "gpr_operand" "")
600 (plus:SF (match_operand:SF 1 "gpr_operand" "")
601 (match_operand:SF 2 "gpr_operand" "")))
602 (clobber (reg:CC_FP CCFP_REGNUM))])])
604 (define_insn "*addsf3_i"
605 [(match_parallel 3 "float_operation"
606 [(set (match_operand:SF 0 "gpr_operand" "=r")
607 (plus:SF (match_operand:SF 1 "gpr_operand" "%r")
608 (match_operand:SF 2 "gpr_operand" "r")))
609 (clobber (reg:CC_FP CCFP_REGNUM))])]
612 [(set_attr "type" "fp")])
615 (define_expand "subsf3"
617 [(set (match_operand:SF 0 "gpr_operand" "")
618 (minus:SF (match_operand:SF 1 "gpr_operand" "")
619 (match_operand:SF 2 "gpr_operand" "")))
620 (clobber (reg:CC_FP CCFP_REGNUM))])])
622 (define_insn "*subsf3_i"
623 [(match_parallel 3 "float_operation"
624 [(set (match_operand:SF 0 "gpr_operand" "=r")
625 (minus:SF (match_operand:SF 1 "gpr_operand" "r")
626 (match_operand:SF 2 "gpr_operand" "r")))
627 (clobber (reg:CC_FP CCFP_REGNUM))])]
630 [(set_attr "type" "fp")])
632 (define_expand "subsf3_f"
634 [(set (reg:CC_FP CCFP_REGNUM)
635 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
636 (match_operand:SF 2 "gpr_operand" "r")))
637 (set (match_operand:SF 0 "gpr_operand" "=r")
638 (minus:SF (match_dup 1) (match_dup 2)))])]
639 "!TARGET_SOFT_CMPSF")
641 (define_insn "*subsf3_f_i"
642 [(match_parallel 3 "float_operation"
643 [(set (reg:CC_FP CCFP_REGNUM)
644 (compare:CC_FP (match_operand:SF 1 "gpr_operand" "r")
645 (match_operand:SF 2 "gpr_operand" "r")))
646 (set (match_operand:SF 0 "gpr_operand" "=r")
647 (minus:SF (match_dup 1) (match_dup 2)))])]
650 [(set_attr "type" "fp")])
652 ; There is an fabs instruction, but it has longer latency.
653 (define_expand "abssf2"
654 [(set (match_operand:SF 0 "gpr_operand" "")
655 (abs:SF (match_operand:SF 1 "gpr_operand" "")))]
659 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1],
661 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
663 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx));
664 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx));
669 (define_expand "mulsf3"
671 [(set (match_operand:SF 0 "gpr_operand" "")
672 (mult:SF (match_operand:SF 1 "gpr_operand" "")
673 (match_operand:SF 2 "gpr_operand" "")))
674 (clobber (reg:CC_FP CCFP_REGNUM))])])
676 (define_insn "*mulsf3_i"
677 [(match_parallel 3 "float_operation"
678 [(set (match_operand:SF 0 "gpr_operand" "=r")
679 (mult:SF (match_operand:SF 1 "gpr_operand" "%r")
680 (match_operand:SF 2 "gpr_operand" "r")))
681 (clobber (reg:CC_FP CCFP_REGNUM))])]
684 [(set_attr "type" "fp")])
687 (define_expand "divsf3"
688 [(set (match_operand:SF 0 "gpr_operand" "")
689 (div:SF (match_operand:SF 1 "gpr_operand" "")
690 (match_operand:SF 2 "gpr_operand" "")))]
691 "flag_reciprocal_math"
693 rtx one = CONST1_RTX (SFmode);
694 rtx dst = operands[0];
696 if (rtx_equal_p (dst, operands[1]))
698 emit_move_insn (dst, one);
701 else if (!register_operand (dst, SFmode) && can_create_pseudo_p ())
702 dst = gen_reg_rtx (SFmode);
703 emit_insn (gen_recipsf2 (dst, one, operands[2],
704 sfunc_symbol (\"__fast_recipsf2\")));
705 emit_insn (gen_mulsf3 (operands[0], operands[1], dst));
709 ;; Before reload, keep the hard reg usage to clobbers so that the loop
710 ;; optimizers can more easily move this insn.
711 ;; It would be nicer to use a constraint for a GPR_0 - only register class,
712 ;; but sched1 can still cause trouble then, and there is no guarantee of
713 ;; better register allocations.
714 ;; Neither is there when using the opposite strategy - putting explicit
715 ;; hard register references into pre-reload rtl.
716 (define_expand "recipsf2"
718 [(set (match_operand:SF 0 "gpr_operand" "")
719 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
720 (match_operand:SF 2 "move_src_operand" "")))
721 (use (match_operand:SI 3 "move_src_operand" ""))
724 (clobber (reg:SF GPR_IP))
725 (clobber (reg:DI GPR_16))
726 (clobber (reg:DI GPR_18))
727 (clobber (reg:SI GPR_20))
728 (clobber (reg:SI GPR_LR))
729 (clobber (reg:CC CC_REGNUM))
730 (clobber (reg:CC_FP CCFP_REGNUM))])])
732 (define_insn_and_split "*recipsf2_1"
733 [(match_parallel 4 "float_operation"
734 [(set (match_operand:SF 0 "gpr_operand" "=r,r")
735 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
736 (match_operand:SF 2 "move_src_operand" "rU16m,rU16mCal")))
737 (use (match_operand:SI 3 "move_src_operand" "rU16m,rU16mCal"))
740 (clobber (reg:SF GPR_IP))
741 (clobber (reg:DI GPR_16))
742 (clobber (reg:DI GPR_18))
743 (clobber (reg:SI GPR_20))
744 (clobber (reg:SI GPR_LR))
745 (clobber (reg:CC CC_REGNUM))
746 (clobber (reg:CC_FP CCFP_REGNUM))])]
747 "flag_reciprocal_math"
749 "&& reload_completed"
750 [(set (reg:SI 1) (match_dup 3))
751 (set (reg:SF 0) (match_dup 2))
754 (div:SF (match_dup 1)
757 (clobber (reg:SI GPR_IP))
758 (clobber (reg:DI GPR_16))
759 (clobber (reg:DI GPR_18))
760 (clobber (reg:SI GPR_20))
761 (clobber (reg:SI GPR_LR))
762 (clobber (reg:CC CC_REGNUM))
763 (clobber (reg:CC_FP CCFP_REGNUM))
766 (set (match_dup 0) (reg:SF 0))]
767 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
768 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
769 [(set_attr "type" "fp_sfunc")
770 (set_attr "length" "16,24")])
772 (define_insn "*recipsf2_2"
773 [(match_parallel 1 "float_operation"
775 (div:SF (match_operand:SF 0 "const_float_1_operand" "")
778 (clobber (reg:SI GPR_IP))
779 (clobber (reg:DI GPR_16))
780 (clobber (reg:DI GPR_18))
781 (clobber (reg:SI GPR_20))
782 (clobber (reg:SI GPR_LR))
783 (clobber (reg:CC CC_REGNUM))
784 (clobber (reg:CC_FP CCFP_REGNUM))])]
785 "flag_reciprocal_math"
787 [(set_attr "type" "fp_sfunc")])
790 ;; Fused multiply-add
791 (define_expand "fmasf4"
793 [(set (match_operand:SF 0 "gpr_operand" "")
794 (fma:SF (match_operand:SF 1 "gpr_operand" "")
795 (match_operand:SF 2 "gpr_operand" "")
796 (match_operand:SF 3 "gpr_operand" "")))
797 (clobber (reg:CC_FP CCFP_REGNUM))])]
800 ; The multiply operands are commutative, but since they have the
801 ; same constraints, there is no point in telling reload about this.
802 (define_insn "*fmadd"
803 [(match_parallel 4 "float_operation"
804 [(set (match_operand:SF 0 "gpr_operand" "=r")
805 (fma:SF (match_operand:SF 1 "gpr_operand" "r")
806 (match_operand:SF 2 "gpr_operand" "r")
807 (match_operand:SF 3 "gpr_operand" "0")))
808 (clobber (reg:CC_FP CCFP_REGNUM))])]
811 [(set_attr "type" "fp")])
813 ; Once vetorization consistently works for this port, should check
814 ; if the fmadd / fmsub patterns still serve a purpose. With the
815 ; introduction of fma / fnma handling by the SSA optimizers,
816 ; at least scalars should be handled by these optimizers, would
817 ; have to see how well they do on vectors from auto-vectorization.
819 ; combiner pattern, also used by vector combiner pattern
820 (define_expand "maddsf"
822 [(set (match_operand:SF 0 "gpr_operand" "=r")
823 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
824 (match_operand:SF 2 "gpr_operand" "r"))
825 (match_operand:SF 3 "gpr_operand" "0")))
826 (clobber (reg:CC_FP CCFP_REGNUM))])]
829 (define_insn "*maddsf_combine"
830 [(match_parallel 4 "float_operation"
831 [(set (match_operand:SF 0 "gpr_operand" "=r")
832 (plus:SF (mult:SF (match_operand:SF 1 "gpr_operand" "r")
833 (match_operand:SF 2 "gpr_operand" "r"))
834 (match_operand:SF 3 "gpr_operand" "0")))
835 (clobber (reg:CC_FP CCFP_REGNUM))])]
838 [(set_attr "type" "fp")])
840 ;; Fused multiply-sub
841 (define_expand "fnmasf4"
843 [(set (match_operand:SF 0 "gpr_operand" "")
844 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" ""))
845 (match_operand:SF 2 "gpr_operand" "")
846 (match_operand:SF 3 "gpr_operand" "")))
847 (clobber (reg:CC_FP CCFP_REGNUM))])]
850 (define_insn "*fmsub"
851 [(match_parallel 4 "float_operation"
852 [(set (match_operand:SF 0 "gpr_operand" "=r")
853 (fma:SF (neg:SF (match_operand:SF 1 "gpr_operand" "r"))
854 (match_operand:SF 2 "gpr_operand" "r")
855 (match_operand:SF 3 "gpr_operand" "0")))
856 (clobber (reg:CC_FP CCFP_REGNUM))])]
859 [(set_attr "type" "fp")])
861 (define_insn "*fmsub_combine"
862 [(match_parallel 4 "float_operation"
863 [(set (match_operand:SF 0 "gpr_operand" "=r")
864 (minus:SF (match_operand:SF 3 "gpr_operand" "0")
865 (mult:SF (match_operand:SF 1 "gpr_operand" "r")
866 (match_operand:SF 2 "gpr_operand" "r"))))
867 (clobber (reg:CC_FP CCFP_REGNUM))])]
870 [(set_attr "type" "fp")])
872 ;; float / integer conversions
874 (define_expand "floatsisf2"
876 [(set (match_operand:SF 0 "gpr_operand" "")
877 (float:SF (match_operand:SI 1 "gpr_operand" "")))
878 (clobber (reg:CC_FP CCFP_REGNUM))])])
880 (define_insn "*floatsisf2_i"
881 [(match_parallel 2 "float_operation"
882 [(set (match_operand:SF 0 "gpr_operand" "=r")
883 (float:SF (match_operand:SI 1 "gpr_operand" "r")))
884 (clobber (reg:CC_FP CCFP_REGNUM))])]
887 [(set_attr "type" "fp")])
889 (define_expand "floatsisf2_cmp"
891 [(set (reg:CC_FP CCFP_REGNUM)
892 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
894 (set (match_operand:SF 0 "gpr_operand" "=r")
895 (float:SF (match_dup 1)))])]
897 "operands[2] = CONST0_RTX (SFmode);")
899 (define_insn "*floatsisf2_cmp_i"
900 [(match_parallel 3 "float_operation"
901 [(set (reg:CC_FP CCFP_REGNUM)
902 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r"))
903 (match_operand:SF 2 "const0_operand" "")))
904 (set (match_operand:SF 0 "gpr_operand" "=r")
905 (float:SF (match_dup 1)))])]
908 [(set_attr "type" "fp")])
910 (define_expand "floatunssisf2"
911 [(set (match_operand:SF 0 "gpr_operand" "")
912 (float:SF (match_operand:SI 1 "gpr_operand" "")))]
913 "epiphany_normal_fp_rounding == /*FP_MODE_ROUND_TRUNC*/ 2"
915 rtx cst = force_reg (SImode, gen_int_mode (0xb0800000, SImode));
916 rtx tmp = gen_reg_rtx (SImode);
917 rtx cmp = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
919 if (reg_overlap_mentioned_p (operands[0], operands[1]))
920 operands[1] = copy_to_mode_reg (SImode, operands[1]);
921 emit_insn (gen_floatsisf2 (operands[0], operands[1]));
922 emit_insn (gen_ashrsi3 (tmp, operands[1], GEN_INT (8)));
923 emit_insn (gen_sub_f (tmp, tmp, cst));
924 emit_insn (gen_movsfcc (operands[0], cmp,
925 simplify_gen_subreg (SFmode, tmp, SImode, 0),
930 (define_expand "fix_truncsfsi2"
932 [(set (match_operand:SI 0 "gpr_operand" "")
933 (fix:SI (match_operand:SF 1 "gpr_operand" "")))
934 (clobber (reg:CC_FP CCFP_REGNUM))])])
936 (define_insn "*fix_truncsfsi2_i"
937 [(match_parallel 2 "float_operation"
938 [(set (match_operand:SI 0 "gpr_operand" "=r")
939 (fix:SI (match_operand:SF 1 "gpr_operand" "r")))
940 (clobber (reg:CC_FP CCFP_REGNUM))])]
943 [(set_attr "type" "fp")
944 (set (attr "fp_mode")
945 (cond [(match_test "TARGET_MAY_ROUND_FOR_TRUNC")
946 (const_string "round_unknown")]
947 (const_string "round_trunc")))])
949 (define_expand "fixuns_truncsfsi2"
950 [(set (match_operand:SI 0 "gpr_operand" "")
951 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))]
954 if (reg_overlap_mentioned_p (operands[0], operands[1]))
955 operands[1] = copy_to_mode_reg (SImode, operands[1]);
956 if (TARGET_SOFT_CMPSF || optimize_function_for_speed_p (cfun))
959 /* By toggling what it to be bit31 before the shift, we get a chance to
960 use a short movt insn. */
961 rtx bit31 = force_reg (SImode, GEN_INT (0x800000));
962 rtx tmp = gen_reg_rtx (SImode);
963 rtx limit = force_reg (SImode, gen_int_mode (0x4f000000, SImode));
965 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
967 op1si = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
968 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
969 emit_insn (gen_subsi3_i (tmp, op1si, bit31));
970 emit_insn (gen_ashlsi3 (tmp, tmp, GEN_INT (8)));
971 emit_insn (gen_cmpsi_cc_insn (op1si, limit));
972 emit_insn (gen_movsicc (operands[0], cmp, tmp, operands[0]));
976 REAL_VALUE_TYPE offset;
978 rtx tmp = gen_reg_rtx (SFmode);
979 rtx label = gen_label_rtx ();
981 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM);
982 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode));
984 real_2expN (&offset, 31, SFmode);
985 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode);
986 limit = force_reg (SFmode, limit);
987 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
988 emit_insn (gen_subsf3_f (tmp, operands[1], limit));
989 emit_jump_insn (gen_branch_insn (label, cmp, cc1));
990 bit31 = force_reg (SImode, gen_int_mode (0x80000000, SImode));
991 emit_insn (gen_fix_truncsfsi2 (operands[0], tmp));
992 emit_insn (gen_xorsi3 (operands[0], operands[0], bit31));
998 (define_expand "iadd"
1000 [(set (match_operand:SF 0 "gpr_operand" "")
1001 (plus:SI (match_operand:SF 1 "gpr_operand" "")
1002 (match_operand:SF 2 "gpr_operand" "")))
1003 (clobber (reg:CC_FP CCFP_REGNUM))])])
1005 (define_insn "*iadd_i"
1006 [(match_parallel 3 "float_operation"
1007 [(set (match_operand:SI 0 "gpr_operand" "=r")
1008 (plus:SI (match_operand:SI 1 "gpr_operand" "%r")
1009 (match_operand:SI 2 "gpr_operand" "r")))
1010 (clobber (reg:CC_FP CCFP_REGNUM))])]
1013 [(set_attr "type" "fp_int")])
1015 (define_expand "isub"
1017 [(set (match_operand:SF 0 "gpr_operand" "")
1018 (minus:SI (match_operand:SF 1 "gpr_operand" "")
1019 (match_operand:SF 2 "gpr_operand" "")))
1020 (clobber (reg:CC_FP CCFP_REGNUM))])])
1022 (define_insn "*isub_i"
1023 [(match_parallel 3 "float_operation"
1024 [(set (match_operand:SI 0 "gpr_operand" "=r")
1025 (minus:SI (match_operand:SI 1 "gpr_operand" "r")
1026 (match_operand:SI 2 "gpr_operand" "r")))
1027 (clobber (reg:CC_FP CCFP_REGNUM))])]
1030 [(set_attr "type" "fp_int")])
1032 ; Try to figure out if we over-committed the FPU, and if so, move
1033 ; some insns back over to the integer pipe.
1035 ; The peephole optimizer 'consumes' the insns that are explicitly
1036 ; mentioned. We do not want the preceding insn reconsidered, but
1037 ; we do want that for the following one, so that if we have a run
1038 ; of five fpu users, two of them get changed. Therefore, we
1039 ; use next_active_insn to look at the 'following' insn. That should
1040 ; exist, because peephole2 runs after reload, and there has to be
1041 ; a return after an fp_int insn.
1042 ; ??? However, we can not even ordinarily match the preceding insn;
1043 ; there is some bug in the generators such that then it leaves out
1044 ; the check for PARALLEL before the length check for the then-second
1045 ; main insn. Observed when compiling compatibility-atomic-c++0x.cc
1046 ; from libstdc++-v3.
1048 [(match_parallel 3 "float_operation"
1049 [(set (match_operand:SI 0 "gpr_operand" "")
1050 (match_operator:SI 4 "addsub_operator"
1051 [(match_operand:SI 1 "gpr_operand" "")
1052 (match_operand:SI 2 "gpr_operand" "")]))
1053 (clobber (reg:CC_FP CCFP_REGNUM))])]
1054 "get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1055 && peep2_regno_dead_p (1, CC_REGNUM)
1056 && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))"
1057 [(parallel [(set (match_dup 0) (match_dup 4))
1058 (clobber (reg:CC CC_REGNUM))])]
1062 [(match_parallel 3 "float_operation"
1063 [(set (match_operand:SI 0 "gpr_operand" "")
1065 (match_operand:SI 1 "gpr_operand" "")
1066 (match_operand:SI 2 "gpr_operand" "")))
1067 (clobber (reg:CC_FP CCFP_REGNUM))])]
1068 "prev_active_insn (peep2_next_insn (0))
1069 && get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
1070 && peep2_regno_dead_p (1, CC_REGNUM)
1071 && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))
1072 && find_reg_note (insn, REG_EQUAL, NULL_RTX) != NULL_RTX
1073 && GET_CODE (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0)) == MULT
1074 && CONST_INT_P (XEXP (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0),
1076 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 4)))
1077 (clobber (reg:CC CC_REGNUM))])]
1080 = XEXP (XEXP (find_reg_note (curr_insn, REG_EQUAL, NULL_RTX), 0), 1);
1083 (define_expand "mulsi3"
1085 [(set (match_operand:SI 0 "gpr_operand" "")
1086 (mult:SI (match_operand:SI 1 "gpr_operand" "")
1087 (match_operand:SI 2 "gpr_operand" "")))
1088 (clobber (reg:CC_FP CCFP_REGNUM))])])
1090 (define_insn "*imul"
1091 [(match_parallel 3 "float_operation"
1092 [(set (match_operand:SI 0 "gpr_operand" "=r")
1093 (mult:SI (match_operand:SI 1 "gpr_operand" "%r")
1094 (match_operand:SI 2 "gpr_operand" "r")))
1095 (clobber (reg:CC_FP CCFP_REGNUM))])]
1098 [(set_attr "type" "fp_int")])
1100 ; combiner pattern, also used by vector combiner pattern
1101 (define_expand "maddsi"
1103 [(set (match_operand:SI 0 "gpr_operand" "=r")
1104 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1105 (match_operand:SI 2 "gpr_operand" "r"))
1106 (match_operand:SI 3 "gpr_operand" "0")))
1107 (clobber (reg:CC_FP CCFP_REGNUM))])]
1110 (define_insn "*maddsi_combine"
1111 [(match_parallel 4 "float_operation"
1112 [(set (match_operand:SI 0 "gpr_operand" "=r")
1113 (plus:SI (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1114 (match_operand:SI 2 "gpr_operand" "r"))
1115 (match_operand:SI 3 "gpr_operand" "0")))
1116 (clobber (reg:CC_FP CCFP_REGNUM))])]
1119 [(set_attr "type" "fp_int")])
1121 (define_insn "*imsub"
1122 [(match_parallel 4 "float_operation"
1123 [(set (match_operand:SI 0 "gpr_operand" "=r")
1124 (minus:SI (match_operand:SI 3 "gpr_operand" "0")
1125 (mult:SI (match_operand:SI 1 "gpr_operand" "r")
1126 (match_operand:SI 2 "gpr_operand" "r"))))
1127 (clobber (reg:CC_FP CCFP_REGNUM))])]
1130 [(set_attr "type" "fp_int")])
1132 (define_expand "divsi3"
1134 [(set (match_operand:SI 0 "move_dest_operand" "")
1135 (div:SI (match_operand:SI 1 "move_src_operand" "")
1136 (match_operand:SI 2 "move_src_operand" "")))
1138 (clobber (reg:SI 0))
1139 (clobber (reg:SI 1))
1140 (clobber (reg:SI GPR_IP))
1141 (clobber (reg:DI GPR_16))
1142 (clobber (reg:DI GPR_18))
1143 (clobber (reg:SI GPR_20))
1144 (clobber (reg:SI GPR_LR))
1145 (clobber (reg:CC CC_REGNUM))
1146 (clobber (reg:CC_FP CCFP_REGNUM))])]
1148 "operands[3] = sfunc_symbol (\"__divsi3\");")
1150 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1151 ;; optimizers can more easily move this insn.
1152 (define_insn_and_split "*divsi3_1"
1153 [(match_parallel 4 "float_operation"
1154 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1155 (div:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1156 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1157 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1158 (clobber (reg:SI 0))
1159 (clobber (reg:SI 1))
1160 (clobber (reg:SI GPR_IP))
1161 (clobber (reg:DI GPR_16))
1162 (clobber (reg:DI GPR_18))
1163 (clobber (reg:SI GPR_20))
1164 (clobber (reg:SI GPR_LR))
1165 (clobber (reg:CC CC_REGNUM))
1166 (clobber (reg:CC_FP CCFP_REGNUM))])]
1169 "&& reload_completed"
1170 [(set (reg:SI 0) (match_dup 1))
1171 (set (reg:SI 1) (match_dup 2))
1173 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1175 (clobber (reg:SI 1))
1176 (clobber (reg:SI GPR_IP))
1177 (clobber (reg:DI GPR_16))
1178 (clobber (reg:DI GPR_18))
1179 (clobber (reg:SI GPR_20))
1180 (clobber (reg:SI GPR_LR))
1181 (clobber (reg:CC CC_REGNUM))
1182 (clobber (reg:CC_FP CCFP_REGNUM))
1185 (set (match_dup 0) (reg:SI 0))]
1186 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1187 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1188 [(set_attr "type" "fp_sfunc")
1189 (set_attr "length" "16,24")])
1191 (define_insn "*divsi3_2"
1192 [(match_parallel 1 "float_operation"
1193 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1)))
1194 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1195 (clobber (reg:SI 1))
1196 (clobber (reg:SI GPR_IP))
1197 (clobber (reg:DI GPR_16))
1198 (clobber (reg:DI GPR_18))
1199 (clobber (reg:SI GPR_20))
1200 (clobber (reg:SI GPR_LR))
1201 (clobber (reg:CC CC_REGNUM))
1202 (clobber (reg:CC_FP CCFP_REGNUM))])]
1205 [(set_attr "type" "fp_sfunc")])
1207 (define_expand "udivsi3"
1209 [(set (match_operand:SI 0 "move_dest_operand" "")
1210 (udiv:SI (match_operand:SI 1 "move_src_operand" "")
1211 (match_operand:SI 2 "move_src_operand" "")))
1213 (clobber (reg:SI 0))
1214 (clobber (reg:SI 1))
1215 (clobber (reg:SI GPR_IP))
1216 (clobber (reg:DI GPR_16))
1217 (clobber (reg:SI GPR_18))
1218 (clobber (reg:SI GPR_LR))
1219 (clobber (reg:CC CC_REGNUM))
1220 (clobber (reg:CC_FP CCFP_REGNUM))])]
1222 "operands[3] = sfunc_symbol (\"__udivsi3\");")
1224 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1225 ;; optimizers can more easily move this insn.
1226 (define_insn_and_split "*udivsi3_1"
1227 [(match_parallel 4 "float_operation"
1228 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1229 (udiv:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1230 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1231 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1232 (clobber (reg:SI 0))
1233 (clobber (reg:SI 1))
1234 (clobber (reg:SI GPR_IP))
1235 (clobber (reg:DI GPR_16))
1236 (clobber (reg:SI GPR_18))
1237 (clobber (reg:SI GPR_LR))
1238 (clobber (reg:CC CC_REGNUM))
1239 (clobber (reg:CC_FP CCFP_REGNUM))])]
1242 "&& reload_completed"
1243 [(set (reg:SI 0) (match_dup 1))
1244 (set (reg:SI 1) (match_dup 2))
1246 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1248 (clobber (reg:SI 1))
1249 (clobber (reg:SI GPR_IP))
1250 (clobber (reg:DI GPR_16))
1251 (clobber (reg:SI GPR_18))
1252 (clobber (reg:SI GPR_LR))
1253 (clobber (reg:CC CC_REGNUM))
1254 (clobber (reg:CC_FP CCFP_REGNUM))
1257 (set (match_dup 0) (reg:SI 0))]
1258 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1259 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1260 [(set_attr "type" "fp_sfunc")
1261 (set_attr "length" "16,24")])
1263 (define_insn "*udivsi3_2"
1264 [(match_parallel 1 "float_operation"
1265 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1)))
1266 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1267 (clobber (reg:SI 1))
1268 (clobber (reg:SI GPR_IP))
1269 (clobber (reg:DI GPR_16))
1270 (clobber (reg:SI GPR_18))
1271 (clobber (reg:SI GPR_LR))
1272 (clobber (reg:CC CC_REGNUM))
1273 (clobber (reg:CC_FP CCFP_REGNUM))])]
1276 [(set_attr "type" "fp_sfunc")])
1278 (define_expand "modsi3"
1280 [(set (match_operand:SI 0 "move_dest_operand" "")
1281 (mod:SI (match_operand:SI 1 "move_src_operand" "")
1282 (match_operand:SI 2 "move_src_operand" "")))
1284 (clobber (reg:SI 0))
1285 (clobber (reg:SI 1))
1286 (clobber (reg:SI 2))
1287 (clobber (reg:SI GPR_IP))
1288 (clobber (reg:DI GPR_16))
1289 (clobber (reg:DI GPR_18))
1290 (clobber (reg:SI GPR_LR))
1291 (clobber (reg:CC CC_REGNUM))
1292 (clobber (reg:CC_FP CCFP_REGNUM))])]
1294 "operands[3] = sfunc_symbol (\"__modsi3\");")
1296 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1297 ;; optimizers can more easily move this insn.
1298 (define_insn_and_split "*modsi3_1"
1299 [(match_parallel 4 "float_operation"
1300 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1301 (mod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1302 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1303 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1304 (clobber (reg:SI 0))
1305 (clobber (reg:SI 1))
1306 (clobber (reg:SI 2))
1307 (clobber (reg:SI GPR_IP))
1308 (clobber (reg:DI GPR_16))
1309 (clobber (reg:DI GPR_18))
1310 (clobber (reg:SI GPR_LR))
1311 (clobber (reg:CC CC_REGNUM))
1312 (clobber (reg:CC_FP CCFP_REGNUM))])]
1315 "&& reload_completed"
1316 [(set (reg:SI 0) (match_dup 1))
1317 (set (reg:SI 1) (match_dup 2))
1319 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1321 (clobber (reg:SI 2))
1322 (clobber (reg:SI GPR_IP))
1323 (clobber (reg:DI GPR_16))
1324 (clobber (reg:DI GPR_18))
1325 (clobber (reg:SI GPR_LR))
1326 (clobber (reg:CC CC_REGNUM))
1327 (clobber (reg:CC_FP CCFP_REGNUM))
1330 (set (match_dup 0) (reg:SI 0))]
1331 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1332 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1333 [(set_attr "type" "fp_sfunc")
1334 (set_attr "length" "16,24")])
1336 (define_insn "*modsi3_2"
1337 [(match_parallel 1 "float_operation"
1338 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1)))
1339 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1340 (clobber (reg:SI 2))
1341 (clobber (reg:SI GPR_IP))
1342 (clobber (reg:DI GPR_16))
1343 (clobber (reg:DI GPR_18))
1344 (clobber (reg:SI GPR_LR))
1345 (clobber (reg:CC CC_REGNUM))
1346 (clobber (reg:CC_FP CCFP_REGNUM))])]
1349 [(set_attr "type" "fp_sfunc")])
1351 (define_expand "umodsi3"
1353 [(set (match_operand:SI 0 "move_dest_operand" "")
1354 (umod:SI (match_operand:SI 1 "move_src_operand" "")
1355 (match_operand:SI 2 "move_src_operand" "")))
1357 (clobber (reg:SI 0))
1358 (clobber (reg:SI 1))
1359 (clobber (reg:SI 2))
1360 (clobber (reg:SI GPR_IP))
1361 (clobber (reg:DI GPR_16))
1362 (clobber (reg:SI GPR_LR))
1363 (clobber (reg:CC CC_REGNUM))
1364 (clobber (reg:CC_FP CCFP_REGNUM))])]
1366 "operands[3] = sfunc_symbol (\"__umodsi3\");")
1368 ;; Before reload, keep the hard reg usage to clobbers so that the loop
1369 ;; optimizers can more easily move this insn.
1370 (define_insn_and_split "*umodsi3_1"
1371 [(match_parallel 4 "float_operation"
1372 [(set (match_operand:SI 0 "move_dest_operand" "=r,r")
1373 (umod:SI (match_operand:SI 1 "move_src_operand" "rU16m,rU16mCal")
1374 (match_operand:SI 2 "move_src_operand" "rU16m,rU16mCal")))
1375 (use (match_operand:SI 3 "call_address_operand" "Csy,r"))
1376 (clobber (reg:SI 0))
1377 (clobber (reg:SI 1))
1378 (clobber (reg:SI 2))
1379 (clobber (reg:SI GPR_IP))
1380 (clobber (reg:DI GPR_16))
1381 (clobber (reg:SI GPR_LR))
1382 (clobber (reg:CC CC_REGNUM))
1383 (clobber (reg:CC_FP CCFP_REGNUM))])]
1386 "&& reload_completed"
1387 [(set (reg:SI 0) (match_dup 1))
1388 (set (reg:SI 1) (match_dup 2))
1390 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1392 (clobber (reg:SI 2))
1393 (clobber (reg:SI GPR_IP))
1394 (clobber (reg:DI GPR_16))
1395 (clobber (reg:SI GPR_LR))
1396 (clobber (reg:CC CC_REGNUM))
1397 (clobber (reg:CC_FP CCFP_REGNUM))
1400 (set (match_dup 0) (reg:SI 0))]
1401 "operands[5] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
1402 operands[6] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);"
1403 [(set_attr "type" "fp_sfunc")
1404 (set_attr "length" "16,24")])
1406 (define_insn "*umodsi3_2"
1407 [(match_parallel 1 "float_operation"
1408 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1)))
1409 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1410 (clobber (reg:SI 2))
1411 (clobber (reg:SI GPR_IP))
1412 (clobber (reg:DI GPR_16))
1413 (clobber (reg:SI GPR_LR))
1414 (clobber (reg:CC CC_REGNUM))
1415 (clobber (reg:CC_FP CCFP_REGNUM))])]
1418 [(set_attr "type" "fp_sfunc")])
1420 ; Disable interrupts.
1421 ; Any earlier values read from CONFIG_REGNUM are out of date, since interrupts
1422 ; might have changed settings that we do not want to mess with.
1424 [(set (reg:SI CONFIG_REGNUM)
1425 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))]
1428 [(set_attr "type" "flow")])
1430 ; Enable interrupts.
1431 ; Present CONTROL_REGNUM here to make sure it is live before the
1432 ; actual uses in floating point insns / calls are inserted.
1433 ; FWIW, interrupts also do mind what is in the control register.
1435 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)]
1438 [(set_attr "type" "flow")])
1440 ; Floating point instructions require manipulating the control register.
1441 ; Manipulating the control register needs aritmetic.
1442 ; Arithmetic clobbers flags.
1443 ; The flags are in the status register, which also contains the alternate
1444 ; flag and the interrupt enable/disable bits.
1445 ; saving/restoring status and mixing up the order with gid/gie could
1447 ; Usually, saving/restoring the status is unnecessary, and will be optimized
1448 ; away. But when we really need it, we must make sure that we don't change
1449 ; anything but the flags.
1450 ; N.B.: We could make the constant easier to load by inverting it, but
1451 ; then we'd need to clobber the saved value - and that would make optimizing
1452 ; away unneeded saves/restores harder / less likely.
1453 (define_expand "movcc"
1454 [(parallel [(set (match_operand:CC 0 "cc_move_operand" "")
1455 (match_operand:CC 1 "cc_move_operand" ""))
1457 (clobber (match_scratch:SI 3 "=X, &r"))])]
1459 "operands[2] = gen_int_mode (~0x10f0, SImode);")
1461 (define_insn "*movcc_i"
1462 [(set (match_operand:CC 0 "cc_move_operand" "=r,Rcc")
1463 (match_operand:CC 1 "cc_move_operand" "Rcc, r"))
1464 (use (match_operand:SI 2 "nonmemory_operand" "X, r"))
1465 (clobber (match_scratch:SI 3 "=X, &r"))]
1469 movfs %3,status\;eor %3,%3,%1\;and %3,%3,%2\;eor %3,%3,%1\;movts status,%3"
1470 [(set_attr "type" "flow")
1471 (set_attr "length" "20,4")])
1473 (define_insn_and_split "save_config"
1474 [(set (match_operand:SI 0 "gpr_operand" "=r") (reg:SI CONFIG_REGNUM))
1475 (use (reg:SI FP_NEAREST_REGNUM))
1476 (use (reg:SI FP_TRUNCATE_REGNUM))
1477 (use (reg:SI FP_ANYFP_REGNUM))]
1481 [(set (match_dup 0) (reg:SI CONFIG_REGNUM))])
1483 (define_insn_and_split "set_fp_mode"
1484 [(set (reg:SI FP_NEAREST_REGNUM)
1485 (match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
1486 (set (reg:SI FP_TRUNCATE_REGNUM) (match_dup 0))
1487 (set (reg:SI FP_ANYFP_REGNUM)
1488 (match_operand:SI 1 "set_fp_mode_operand" "rCfm"))
1489 (use (match_operand:SI 2 "gpr_operand" "r"))
1490 (clobber (reg:CC CC_REGNUM))
1491 (clobber (match_scratch:SI 3 "=&r"))]
1494 "reload_completed || !rtx_equal_p (operands[0], operands[1])"
1497 if (!reload_completed)
1498 emit_note (NOTE_INSN_DELETED);
1500 epiphany_expand_set_fp_mode (operands);
1505 ;; Boolean instructions.
1507 ;; We don't define the DImode versions as expand_binop does a good enough job.
1509 (define_insn "andsi3"
1510 [(set (match_operand:SI 0 "gpr_operand" "=r")
1511 (and:SI (match_operand:SI 1 "gpr_operand" "r")
1512 (match_operand:SI 2 "gpr_operand" "r")))
1513 (clobber (reg:CC CC_REGNUM))]
1517 (define_insn "iorsi3"
1518 [(set (match_operand:SI 0 "gpr_operand" "=r")
1519 (ior:SI (match_operand:SI 1 "gpr_operand" "r")
1520 (match_operand:SI 2 "gpr_operand" "r")))
1521 (clobber (reg:CC CC_REGNUM))]
1525 (define_insn "xorsi3"
1526 [(set (match_operand:SI 0 "gpr_operand" "=r")
1527 (xor:SI (match_operand:SI 1 "gpr_operand" "r")
1528 (match_operand:SI 2 "gpr_operand" "r")))
1529 (clobber (reg:CC CC_REGNUM))]
1533 (define_expand "one_cmplsi2"
1534 [(set (match_operand:SI 0 "gpr_operand" "")
1535 (xor:SI (match_operand:SI 1 "gpr_operand" "")
1539 if (epiphany_m1reg >= 0)
1540 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1]));
1542 emit_insn (gen_xorsi3 (operands[0], operands[1],
1543 force_reg (SImode, GEN_INT (-1))));
1547 ; Note that folding this pattern into the xorsi3 pattern would make combine
1549 (define_insn "one_cmplsi2_i"
1550 [(set (match_operand:SI 0 "gpr_operand" "=r")
1551 (not:SI (match_operand:SI 1 "gpr_operand" "r")))
1552 (clobber (reg:CC CC_REGNUM))]
1553 "epiphany_m1reg >= 0"
1556 ;; Shift instructions.
1557 ;; In principle we could support arbitrary symbolic values as shift constant
1558 ;; (truncating the value appropriately), but that would require a suitable
1559 ;; relocation and assembler & linker support.
1560 (define_insn "ashrsi3"
1561 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1562 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1563 (match_operand:SI 2 "arith_operand" "r,K")))
1564 (clobber (reg:CC CC_REGNUM))]
1567 [(set_attr "length" "4")
1568 (set_attr "type" "shift")])
1570 (define_insn "ashrsi3_tst"
1571 [(set (reg:CC CC_REGNUM)
1573 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1574 (match_operand:SI 2 "arith_operand" "r,K"))
1576 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1577 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
1580 [(set_attr "length" "4")
1581 (set_attr "type" "shift")])
1583 ;; Logical Shift Right
1584 (define_insn "lshrsi3"
1585 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1586 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1587 (match_operand:SI 2 "arith_operand" "r,K")))
1588 (clobber (reg:CC CC_REGNUM))]
1591 [(set_attr "length" "4")
1592 (set_attr "type" "shift")])
1594 (define_insn "lshrsi3_tst"
1595 [(set (reg:CC CC_REGNUM)
1597 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r")
1598 (match_operand:SI 2 "arith_operand" "r,K"))
1600 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1601 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
1604 [(set_attr "length" "4")
1605 (set_attr "type" "shift")])
1607 ;; Logical/Arithmetic Shift Left
1608 (define_insn "ashlsi3"
1609 [(set (match_operand:SI 0 "gpr_operand" "=r,r")
1610 (ashift:SI (match_operand:SI 1 "gpr_operand" "r,r")
1611 (match_operand:SI 2 "arith_operand" "r,K")))
1612 (clobber (reg:CC CC_REGNUM))]
1615 [(set_attr "length" "4")
1616 (set_attr "type" "shift")])
1618 (define_insn "*ashlsi_btst"
1619 [(set (reg:CC_N_NE CC_REGNUM)
1621 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r")
1623 (match_operand 2 "const_int_operand" "K"))
1625 (clobber (match_scratch:SI 0 "=r"))]
1630 xop[0] = operands[0];
1631 xop[1] = operands[1];
1632 xop[2] = GEN_INT (31-INTVAL (operands[2]));
1633 output_asm_insn ("lsl %0,%1,%2", xop);
1638 (define_insn_and_split "zero_extendqisi2"
1639 [(set (match_operand:SI 0 "register_operand" "=r,r")
1640 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))
1641 (clobber (reg:CC CC_REGNUM))]
1647 ? true_regnum (operands[1]) >= 0
1648 : REG_P (operands[1]) && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER"
1649 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
1650 (clobber (reg:CC CC_REGNUM))])
1651 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))
1652 (clobber (reg:CC CC_REGNUM))])]
1653 "operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);")
1655 (define_insn "zero_extendhisi2"
1656 [(set (match_operand:SI 0 "register_operand" "=r,r")
1657 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
1664 ;; Compare instructions.
1666 (define_insn "cmpsi_cc_insn"
1667 [(set (reg:CC CC_REGNUM)
1668 (compare:CC (match_operand:SI 0 "add_reg_operand" "r,r")
1669 (match_operand:SI 1 "arith_operand" "r,L")))
1670 (clobber (match_scratch:SI 2 "=r,r"))]
1673 [(set_attr "type" "compare")])
1675 (define_insn "sub_f"
1676 [(set (reg:CC CC_REGNUM)
1677 (compare:CC (match_operand:SI 1 "gpr_operand" "r,r")
1678 (match_operand:SI 2 "arith_operand" "r,L")))
1679 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1680 (minus:SI (match_dup 1) (match_dup 2)))]
1683 [(set_attr "type" "compare")])
1685 (define_insn "*sub_f_add_imm"
1686 [(set (reg:CC CC_REGNUM)
1687 (compare:CC (match_operand:SI 1 "gpr_operand" "r")
1688 (match_operand:SI 2 "arith_int_operand" "L")))
1689 (set (match_operand:SI 0 "gpr_operand" "=r")
1690 (plus:SI (match_dup 1) (match_operand:SI 3 "const_int_operand" "L")))]
1691 "INTVAL (operands[2]) == -INTVAL (operands[3])"
1693 [(set_attr "type" "compare")])
1695 (define_expand "abssi2"
1696 [(set (match_dup 2) (const_int 0))
1697 (parallel [(set (reg:CC CC_REGNUM)
1698 (compare:CC (match_dup 2)
1699 (match_operand:SI 1 "nonmemory_operand" "")))
1701 (minus:SI (match_dup 2) (match_dup 1)))])
1702 (set (match_operand:SI 0 "gpr_operand" "=r")
1703 (if_then_else:SI (gt:SI (reg:CC CC_REGNUM) (const_int 0))
1707 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
1709 (define_insn "*add_c"
1710 [(set (reg:CC_C_LTU CC_REGNUM)
1712 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1713 (match_operand:SI 2 "arith_operand" "r,L"))
1715 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1716 (plus:SI (match_dup 1) (match_dup 2)))]
1719 [(set_attr "type" "compare")])
1721 (define_insn "*add_c_rev"
1722 [(set (reg:CC_C_LTU CC_REGNUM)
1724 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r")
1725 (match_operand:SI 2 "arith_operand" "r,L"))
1727 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1728 (plus:SI (match_dup 2) (match_dup 1)))]
1731 [(set_attr "type" "compare")])
1733 (define_insn "*sub_c"
1734 [(set (reg:CC_C_GTU CC_REGNUM)
1736 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1737 (match_operand:SI 2 "arith_operand" "r,L"))
1739 (set (match_operand:SI 0 "gpr_operand" "=r,r")
1740 (minus:SI (match_dup 1) (match_dup 2)))]
1743 [(set_attr "type" "compare")])
1745 (define_insn "*sub_c_void"
1746 [(set (reg:CC_C_GTU CC_REGNUM)
1748 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r")
1749 (match_operand:SI 2 "arith_operand" "r,L"))
1751 (clobber (match_scratch:SI 0 "=r,r"))]
1754 [(set_attr "type" "compare")])
1756 (define_code_iterator logical_op
1759 (define_code_attr op_mnc
1760 [(plus "add") (minus "sub") (and "and") (ior "orr") (xor "eor")])
1762 (define_insn "*<op_mnc>_f"
1763 [(set (reg:CC CC_REGNUM)
1764 (compare:CC (logical_op:SI (match_operand:SI 1 "gpr_operand" "%r")
1765 (match_operand:SI 2 "gpr_operand" "r"))
1767 (set (match_operand:SI 0 "gpr_operand" "=r")
1768 (logical_op:SI (match_dup 1) (match_dup 2)))]
1771 [(set_attr "type" "compare")])
1773 (define_insn_and_split "*mov_f"
1774 [(set (reg:CC CC_REGNUM)
1775 (compare:CC (match_operand:SI 1 "gpr_operand" "r") (const_int 0)))
1776 (set (match_operand:SI 0 "gpr_operand" "=r") (match_dup 1))]
1781 [(set (reg:CC CC_REGNUM)
1782 (compare:CC (and:SI (match_dup 1) (match_dup 1)) (const_int 0)))
1783 (set (match_operand:SI 0 "gpr_operand" "=r")
1784 (and:SI (match_dup 1) (match_dup 1)))])]
1786 [(set_attr "type" "compare")])
1790 [(set (match_operand:SI 0 "gpr_operand")
1791 (logical_op:SI (match_operand:SI 1 "gpr_operand")
1792 (match_operand:SI 2 "gpr_operand")))
1793 (clobber (reg:CC CC_REGNUM))])
1795 [(set (reg:CC CC_REGNUM)
1796 (compare:CC (and:SI (match_dup 0) (match_dup 0)) (const_int 0)))
1797 (set (match_operand:SI 3 "gpr_operand")
1798 (and:SI (match_dup 0) (match_dup 0)))])]
1799 "peep2_reg_dead_p (2, operands[0])"
1801 [(set (reg:CC CC_REGNUM)
1802 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1804 (set (match_dup 3) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1808 [(set (match_operand:SI 0 "gpr_operand")
1809 (logical_op:SI (match_operand:SI 1 "gpr_operand")
1810 (match_operand:SI 2 "gpr_operand")))
1811 (clobber (reg:CC CC_REGNUM))])
1813 [(set (reg:CC CC_REGNUM)
1814 (compare:CC (and:SI (match_dup 0) (match_dup 0)) (const_int 0)))
1815 (set (match_operand:SI 3 "gpr_operand")
1816 (and:SI (match_dup 0) (match_dup 0)))])]
1817 "peep2_reg_dead_p (2, operands[3])"
1819 [(set (reg:CC CC_REGNUM)
1820 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1822 (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1826 [(set (match_operand:SI 0 "gpr_operand")
1827 (logical_op:SI (match_operand:SI 1 "gpr_operand")
1828 (match_operand:SI 2 "gpr_operand")))
1829 (clobber (reg:CC CC_REGNUM))])
1831 [(set (reg:CC CC_REGNUM)
1832 (compare:CC (match_dup 0) (const_int 0)))
1833 (clobber (match_operand:SI 3 "gpr_operand"))])]
1836 [(set (reg:CC CC_REGNUM)
1837 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2))
1839 (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])])
1841 (define_expand "cstoresi4"
1843 [(set (reg:CC CC_REGNUM)
1844 (match_operand:SI 1 "comparison_operator"))
1845 (match_operand:SI 2 "" "")])
1846 (set (match_dup 0) (match_operand:SI 3 "arith_operand" ""))
1847 (set (match_operand:SI 0 "gpr_operand" "=r")
1848 (if_then_else:SI (match_dup 4) (match_dup 5) (match_dup 0)))]
1851 enum rtx_code o2_code = GET_CODE (operands[2]);
1852 enum rtx_code cmp_code = GET_CODE (operands[1]);
1854 if ((o2_code == AND || o2_code == IOR || o2_code == XOR)
1855 && operands[3] == const0_rtx)
1857 operands[2] = copy_rtx(operands[2]);
1858 XEXP (operands[2], 0) = force_reg (SImode, XEXP (operands[2], 0));
1859 XEXP (operands[2], 1) = force_reg (SImode, XEXP (operands[2], 1));
1862 operands[2] = force_reg (SImode, operands[2]);
1863 operands[1] = gen_rtx_COMPARE (CCmode, operands[2], operands[3]);
1866 operands[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode));
1867 operands[3] = const0_rtx;
1871 if (operands[3] != const0_rtx)
1872 operands[2] = gen_rtx_MINUS (SImode, operands[2], operands[3]);
1873 operands[2] = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
1874 operands[3] = operands[0];
1876 operands[4] = gen_rtx_fmt_ee (cmp_code, SImode,
1877 gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx);
1878 operands[5] = force_reg (SImode, GEN_INT (STORE_FLAG_VALUE));
1882 ; floating point comparisons
1884 (define_insn "*cmpsf_cc_insn"
1885 [(match_parallel 3 "float_operation"
1886 [(set (reg:CC_FP CCFP_REGNUM)
1887 (compare:CC_FP (match_operand:SF 0 "gpr_operand" "r")
1888 (match_operand:SF 1 "gpr_operand" "r")))
1889 (clobber (match_scratch:SF 2 "=r"))])]
1890 "!TARGET_SOFT_CMPSF"
1892 [(set_attr "type" "fp")
1893 (set_attr "fp_mode" "round_unknown")])
1895 ;; ??? do we have to relax the operand0 predicate to immediate_operand
1896 ;; to allow the rtl loop optimizer to generate comparisons? OTOH
1897 ;; we want call_address_operand to enforce valid operands so that
1898 ;; combine won't do silly things, allowing instruction scheduling to do
1900 (define_insn "*cmpsf_eq"
1901 [(set (reg:CC_FP_EQ CC_REGNUM) (compare:CC_FP_EQ (reg:SF 0) (reg:SF 1)))
1902 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1903 (clobber (reg:SI GPR_IP))
1904 (clobber (reg:SI GPR_LR))]
1907 [(set_attr "type" "sfunc")])
1909 (define_insn "*cmpsf_gte"
1910 [(set (reg:CC_FP_GTE CC_REGNUM) (compare:CC_FP_GTE (reg:SF 0) (reg:SF 1)))
1911 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1912 (clobber (reg:SI GPR_IP))
1913 (clobber (reg:SI GPR_LR))]
1916 [(set_attr "type" "sfunc")])
1918 (define_insn "*cmpsf_ord"
1919 [(set (reg:CC_FP_ORD CC_REGNUM) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
1920 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1921 (clobber (reg:SI GPR_IP))
1922 (clobber (reg:SI GPR_16))
1923 (clobber (reg:SI GPR_LR))]
1926 [(set_attr "type" "sfunc")])
1928 (define_insn "*cmpsf_uneq"
1929 [(set (reg:CC_FP_UNEQ CC_REGNUM) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
1930 (use (match_operand:SI 0 "call_address_operand" "Csy,r"))
1931 (clobber (reg:SI GPR_IP))
1932 (clobber (reg:SI GPR_16))
1933 (clobber (reg:SI GPR_LR))]
1936 [(set_attr "type" "sfunc")])
1938 ;; conditional moves
1940 (define_expand "mov<mode>cc"
1941 [(set (match_operand:WMODE 0 "gpr_operand" "")
1942 (if_then_else:WMODE (match_operand 1 "comparison_operator" "")
1943 (match_operand:WMODE 2 "gpr_operand" "")
1944 (match_operand:WMODE 3 "gpr_operand" "")))]
1947 rtx cmp_op0 = XEXP (operands[1], 0);
1948 rtx cmp_op1 = XEXP (operands[1], 1);
1949 enum machine_mode cmp_in_mode;
1950 enum rtx_code code = GET_CODE (operands[1]);
1952 cmp_in_mode = GET_MODE (cmp_op0);
1953 if (cmp_in_mode == VOIDmode)
1954 cmp_in_mode = GET_MODE (cmp_op1);
1955 if (cmp_in_mode == VOIDmode)
1956 cmp_in_mode = SImode;
1957 /* If the operands are a better match when reversed, swap them now.
1958 This allows combine to see the proper comparison codes. */
1959 if (rtx_equal_p (operands[0], operands[2])
1960 && !rtx_equal_p (operands[0], operands[3]))
1962 rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp;
1963 code = (FLOAT_MODE_P (GET_MODE (cmp_op0))
1964 ? reverse_condition_maybe_unordered (code)
1965 : reverse_condition (code));
1968 if (proper_comparison_operator (operands[1], VOIDmode))
1969 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1);
1972 if (!currently_expanding_to_rtl)
1974 /* ??? It would seem safest to FAIL here, but that would defeat
1975 the purpose of having an if-conversion pass; its logic currently
1976 assumes that the backend should be safe to insert condition code
1977 setting instructions, as the same condition codes were presumably
1978 set by the if-conversion input code. */
1980 /* What mode to give as first operand to gen_compare_reg here is
1981 debatable. VOIDmode would be minimalist; telling gen_compare_reg
1982 to use the mode of CC_REGNUM (or putting it on the comparison
1983 operator afterwards) is also a logical choice. OTOH, by using
1984 <MODE>mode, we have mode combine opportunities with flag setting
1985 operations - if we get some. */
1987 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1);
1993 (define_insn "*mov<mode>cc_insn"
1994 [(set (match_operand:WMODE 0 "gpr_operand" "=r")
1995 (if_then_else:WMODE (match_operator 3 "proper_comparison_operator"
1996 [(match_operand 4 "cc_operand") (const_int 0)])
1997 (match_operand:WMODE 1 "gpr_operand" "r")
1998 (match_operand:WMODE 2 "gpr_operand" "0")))]
2001 [(set_attr "type" "cmove")])
2004 [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
2005 (match_operand:WMODE 1 "" ""))
2006 (clobber (match_operand 8 "cc_operand"))])
2007 (match_operand 2 "" "")
2008 (set (match_operand:WMODE2 3 "gpr_operand" "")
2009 (match_operand:WMODE2 9 "gpr_operand" ""))
2011 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
2012 [(match_operand 6 "cc_operand")
2013 (match_operand 7 "const0_operand")])
2014 (match_operand:WMODE2 4 "nonmemory_operand" "")
2016 "REGNO (operands[0]) == REGNO (operands[9])
2017 && peep2_reg_dead_p (3, operands[0])
2018 && !reg_set_p (operands[0], operands[2])
2019 && !reg_set_p (operands[3], operands[2])
2020 && !reg_overlap_mentioned_p (operands[3], operands[2])"
2021 [(parallel [(set (match_dup 10) (match_dup 1))
2022 (clobber (match_dup 8))])
2025 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
2027 operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
2028 <WMODE2:MODE>mode, 0);
2029 replace_rtx (operands[2], operands[9], operands[3]);
2030 replace_rtx (operands[2], operands[0], operands[10]);
2031 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
2035 [(parallel [(set (match_operand 6 "cc_operand") (match_operand 2 "" ""))
2036 (set (match_operand:WMODE 0 "gpr_operand" "")
2037 (match_operand:WMODE 1 "" ""))])
2038 (set (match_operand:WMODE2 3 "gpr_operand" "")
2039 (match_operand:WMODE2 4 "gpr_operand"))
2041 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
2043 (match_operand:WMODE 7 "const0_operand")])
2044 (match_operand:WMODE2 8 "gpr_operand")
2046 "REGNO (operands[0]) == REGNO (operands[8])
2047 && REVERSIBLE_CC_MODE (GET_MODE (operands[6]))
2048 && peep2_reg_dead_p (3, operands[6])
2049 && peep2_reg_dead_p (3, operands[0])
2050 && !reg_overlap_mentioned_p (operands[4], operands[3])"
2051 [(parallel [(set (match_dup 6) (match_dup 2))
2052 (set (match_dup 9) (match_dup 1))])
2054 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
2058 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[5]),
2059 GET_MODE (operands[6])),
2060 GET_MODE (operands[5]), operands[6], operands[7]);
2061 operands[9] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
2062 <WMODE2:MODE>mode, 0);
2065 ;; These control RTL generation for conditional jump insns
2067 ;; To signal to can_compare_p that the cbranchs?4 patterns work,
2068 ;; they must allow const0_rtx for both comparison operands
2069 (define_expand "cbranchsi4"
2070 [(set (reg CC_REGNUM)
2071 (compare (match_operand:SI 1 "add_operand" "")
2072 (match_operand:SI 2 "arith_operand" "")))
2075 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM)
2077 (label_ref (match_operand 3 "" ""))
2081 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SImode,
2082 operands[1], operands[2]);
2083 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
2087 (define_expand "cbranchsf4"
2088 [(set (reg CC_REGNUM)
2089 (compare (match_operand:SF 1 "arith_operand" "")
2090 (match_operand:SF 2 "arith_operand" "")))
2093 (match_operator 0 "comparison_operator" [(reg CC_REGNUM)
2095 (label_ref (match_operand 3 "" ""))
2099 rtx cmp = gen_compare_reg (VOIDmode, GET_CODE (operands[0]), SFmode,
2100 operands[1], operands[2]);
2101 emit_jump_insn (gen_branch_insn (operands[3], cmp, XEXP (cmp, 0)));
2105 ;; Now match both normal and inverted jump.
2107 (define_insn "branch_insn"
2109 (if_then_else (match_operator 1 "proper_comparison_operator"
2110 [(match_operand 2 "cc_operand")
2112 (label_ref (match_operand 0 "" ""))
2116 [(set_attr "type" "branch")])
2118 (define_insn "*rev_branch_insn"
2120 (if_then_else (match_operator 1 "proper_comparison_operator"
2121 [(reg CC_REGNUM) (const_int 0)])
2123 (label_ref (match_operand 0 "" ""))))]
2126 [(set_attr "type" "branch")])
2128 ;; Unconditional and other jump instructions.
2131 [(set (pc) (label_ref (match_operand 0 "" "")))]
2134 [(set_attr "type" "uncond_branch")])
2136 (define_insn "indirect_jump"
2137 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))]
2140 [(set_attr "type" "uncond_branch")])
2142 (define_expand "tablejump"
2143 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" ""))
2144 (use (label_ref (match_operand 1 "" "")))])]
2147 /* In PIC mode, the table entries are stored PC relative.
2148 Convert the relative address to an absolute address. */
2151 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
2153 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2154 op1, NULL_RTX, 0, OPTAB_DIRECT);
2158 (define_insn "*tablejump_internal"
2159 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))
2160 (use (label_ref (match_operand 1 "" "")))]
2163 [(set_attr "type" "uncond_branch")])
2165 (define_insn "*tablejump_hi_internal"
2166 [(set (pc) (match_operand:HI 0 "gpr_operand" "r"))
2167 (use (label_ref (match_operand 1 "" "")))]
2168 "optimize_size && TARGET_SMALL16"
2170 [(set_attr "type" "uncond_branch")])
2173 (define_expand "call"
2174 ;; operands[1] is stack_size_rtx
2175 ;; operands[2] is next_arg_register
2176 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2177 (match_operand 1 "" ""))
2178 (clobber (reg:SI GPR_LR))])]
2181 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2183 if (!call_operand (operands[1], VOIDmode))
2185 = change_address (operands[0], VOIDmode,
2186 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2187 if (epiphany_uninterruptible_p (current_function_decl)
2188 != target_uninterruptible)
2190 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2194 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2195 gen_rtx_CLOBBER (VOIDmode,
2196 gen_rtx_REG (SImode, GPR_LR)))));
2197 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2202 (define_insn "*call_i"
2203 [(match_parallel 2 "float_operation"
2204 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,r"))
2205 (match_operand 1 "" ""))
2206 (clobber (reg:SI GPR_LR))])]
2209 [(set_attr "type" "call")])
2211 (define_expand "sibcall"
2212 ;; operands[1] is stack_size_rtx
2213 ;; operands[2] is next_arg_register
2214 [(parallel [(call (match_operand:SI 0 "call_operand" "")
2215 (match_operand 1 "" ""))
2219 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]);
2221 if (!call_operand (operands[1], VOIDmode))
2223 = change_address (operands[0], VOIDmode,
2224 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2225 if (epiphany_uninterruptible_p (current_function_decl)
2226 != target_uninterruptible)
2228 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2232 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]),
2234 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2239 (define_insn "*sibcall_i"
2240 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc"))
2241 (match_operand 1 "" ""))
2247 [(set_attr "type" "call")])
2249 (define_expand "call_value"
2250 ;; operand 2 is stack_size_rtx
2251 ;; operand 3 is next_arg_register
2252 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2253 (call (match_operand:SI 1 "call_operand" "")
2254 (match_operand 2 "" "")))
2255 (clobber (reg:SI GPR_LR))])]
2258 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2260 if (!call_operand (operands[1], VOIDmode))
2262 = change_address (operands[1], VOIDmode,
2263 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2264 if (epiphany_uninterruptible_p (current_function_decl)
2265 != target_uninterruptible)
2267 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2271 gen_rtvec (2, gen_rtx_SET
2272 (VOIDmode, operands[0],
2273 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2274 gen_rtx_CLOBBER (VOIDmode,
2275 gen_rtx_REG (SImode, GPR_LR)))));
2276 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2281 (define_insn "*call_value_i"
2282 [(match_parallel 3 "float_operation"
2283 [(set (match_operand 0 "gpr_operand" "=r,r")
2284 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,r"))
2285 (match_operand 2 "" "")))
2286 (clobber (reg:SI GPR_LR))])]
2289 [(set_attr "type" "call")
2290 (set_attr "length" "4")])
2292 (define_expand "sibcall_value"
2293 ;; operand 2 is stack_size_rtx
2294 ;; operand 3 is next_arg_register
2295 [(parallel [(set (match_operand 0 "gpr_operand" "=r")
2296 (call (match_operand:SI 1 "call_operand" "")
2297 (match_operand 2 "" "")))
2301 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]);
2303 if (!call_operand (operands[1], VOIDmode))
2305 = change_address (operands[1], VOIDmode,
2306 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2307 if (epiphany_uninterruptible_p (current_function_decl)
2308 != target_uninterruptible)
2310 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ());
2314 gen_rtvec (2, gen_rtx_SET
2315 (VOIDmode, operands[0],
2316 gen_rtx_CALL (VOIDmode, operands[1], operands[2])),
2318 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ());
2323 (define_insn "*sibcall_value_i"
2324 [(set (match_operand 0 "gpr_operand" "=r,r")
2325 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Csy,Rsc"))
2326 (match_operand 2 "" "")))
2332 [(set_attr "type" "call")
2333 (set_attr "length" "4")])
2335 (define_expand "prologue"
2339 epiphany_expand_prologue ();
2343 (define_expand "epilogue"
2347 epiphany_expand_epilogue (0);
2351 (define_expand "sibcall_epilogue"
2355 epiphany_expand_epilogue (1);
2359 ; Since the demise of REG_N_SETS, it is no longer possible to find out
2360 ; in the prologue / epilogue expanders how many times lr is set.
2361 ; Using df_regs_ever_live_p to decide if lr needs saving means that
2362 ; any explicit use of lr will cause it to be saved; hence we cannot
2363 ; represent the blink use in return / sibcall instructions themselves, and
2364 ; instead have to show it in EPILOGUE_USES.
2365 (define_insn "return_i"
2369 [(set_attr "type" "uncond_branch")])
2371 (define_insn "return_internal_interrupt"
2373 (unspec_volatile [(const_int 0)] 1)]
2376 [(set_attr "type" "uncond_branch")])
2378 (define_insn "stack_adjust_add"
2379 [(set (reg:SI GPR_SP)
2380 (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL")))
2381 (clobber (reg:CC CC_REGNUM))
2382 (clobber (reg:SI STATUS_REGNUM))
2383 (clobber (match_operand:BLK 1 "memory_operand" "=m"))]
2387 (define_insn "stack_adjust_mov"
2388 [(set (reg:SI GPR_SP) (reg:SI GPR_FP))
2389 (clobber (match_operand:BLK 0 "memory_operand" "=m"))]
2392 [(set_attr "type" "move")])
2394 (define_insn "stack_adjust_str"
2395 [(set (match_operand 0 "stacktop_operand" "=m")
2396 (match_operand 1 "any_gpr_operand" "r"))
2397 (set (reg:SI GPR_SP)
2398 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2399 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2402 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4
2403 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\");
2405 [(set_attr "type" "store")])
2407 (define_insn "stack_adjust_ldr"
2408 [(set (match_operand:SI 0 "gpr_operand" "=r")
2409 (match_operand:SI 1 "stacktop_operand" "m"))
2410 (set (reg:SI GPR_SP)
2411 (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn")))
2412 (clobber (match_operand:BLK 3 "memory_operand" "=m"))]
2415 [(set_attr "type" "load")])
2417 ;; Define some fake vector operations so that the vectorizer is happy to use
2418 ;; 64 bit loads/stores.
2419 (define_expand "vec_unpacks_lo_v4hi"
2420 [(match_operand:V2SI 0 "gpr_operand")
2421 (match_operand:V4HI 1 "gpr_operand")]
2424 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0);
2425 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2427 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2429 if (reg_overlap_mentioned_p (outl, in))
2430 in = copy_to_mode_reg (SImode, in);
2431 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2432 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2433 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2437 (define_expand "vec_unpacks_hi_v4hi"
2438 [(match_operand:V2SI 0 "gpr_operand")
2439 (match_operand:V4HI 1 "gpr_operand")]
2442 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD);
2443 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2445 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2447 if (reg_overlap_mentioned_p (outl, in))
2448 in = copy_to_mode_reg (SImode, in);
2449 emit_insn (gen_ashlsi3 (outl, in, GEN_INT (16)));
2450 emit_insn (gen_ashrsi3 (outl, outl, GEN_INT (16)));
2451 emit_insn (gen_ashrsi3 (outh, in, GEN_INT (16)));
2455 (define_code_iterator addsub [plus minus])
2457 (define_code_iterator alu_binop
2458 [plus minus and ior xor])
2460 (define_code_attr insn_opname
2461 [(plus "add") (minus "sub") (mult "mul") (div "div")
2462 (and "and") (ior "ior") (xor "xor")])
2464 ; The addsi3 / subsi3 do checks that we don't want when splitting V2SImode
2465 ; operations into two SImode operations.
2466 (define_code_attr si_pattern_suffix
2467 [(plus "_i") (minus "_i") (and "") (ior "") (xor "")])
2469 ; You might think that this would work better as a define_expand, but
2470 ; again lower_subreg pessimizes the code if it sees indiviudual operations.
2471 ; We need to keep inputs and outputs as register pairs if we want to
2472 ; get sensible register allocation for double-word load and store operations.
2473 (define_insn_and_split "<insn_opname>v2si3"
2474 [(set (match_operand:V2SI 0 "gpr_operand" "=r")
2475 (alu_binop:V2SI (match_operand:V2SI 1 "gpr_operand" "r")
2476 (match_operand:V2SI 2 "gpr_operand" "r")))
2477 (clobber (reg:CC CC_REGNUM))]
2480 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2483 rtx o0l, o0h, o1l, o1h, o2l, o2h;
2485 o0l = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2486 o0h = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD);
2487 o1l = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2488 o1h = simplify_gen_subreg (SImode, operands[1], V2SImode, UNITS_PER_WORD);
2489 o2l = simplify_gen_subreg (SImode, operands[2], V2SImode, 0);
2490 o2h = simplify_gen_subreg (SImode, operands[2], V2SImode, UNITS_PER_WORD);
2491 if (reg_overlap_mentioned_p (o0l, o1h))
2492 o1h = copy_to_mode_reg (SImode, o1h);
2493 if (reg_overlap_mentioned_p (o0l, o2h))
2494 o2h = copy_to_mode_reg (SImode, o2h);
2495 emit_insn (gen_<insn_opname>si3<si_pattern_suffix> (o0l, o1l, o2l));
2496 emit_insn (gen_<insn_opname>si3<si_pattern_suffix> (o0h, o1h, o2h));
2499 [(set_attr "length" "8")])
2501 (define_expand "<insn_opname>v2sf3"
2503 [(set (match_operand:V2SF 0 "gpr_operand" "")
2504 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "")
2505 (match_operand:V2SF 2 "gpr_operand" "")))
2506 (clobber (reg:CC_FP CCFP_REGNUM))])])
2508 (define_insn_and_split "<insn_opname>v2sf3_i"
2509 [(match_parallel 3 "float_operation"
2510 [(set (match_operand:V2SF 0 "gpr_operand" "=r")
2511 (addsub:V2SF (match_operand:V2SF 1 "gpr_operand" "r")
2512 (match_operand:V2SF 2 "gpr_operand" "r")))
2513 (clobber (reg:CC_FP CCFP_REGNUM))])]
2516 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2518 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6)))
2519 (clobber (reg:CC_FP CCFP_REGNUM))
2523 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9)))
2524 (clobber (reg:CC_FP CCFP_REGNUM))
2528 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
2529 operands[5] = simplify_gen_subreg (SFmode, operands[1], V2SFmode, 0);
2530 operands[6] = simplify_gen_subreg (SFmode, operands[2], V2SFmode, 0);
2532 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD);
2534 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD);
2536 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD);
2537 if (!reload_completed)
2539 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2540 operands[8] = copy_to_mode_reg (SFmode, operands[8]);
2541 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2542 operands[9] = copy_to_mode_reg (SFmode, operands[9]);
2543 emit_insn (gen_<insn_opname>sf3 (operands[4], operands[5], operands[6]));
2544 emit_insn (gen_<insn_opname>sf3 (operands[7], operands[8], operands[9]));
2547 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2548 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2549 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2550 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2552 [(set_attr "length" "8")
2553 (set_attr "type" "v2fp")])
2555 (define_expand "ashlv2si3"
2557 [(set (match_operand:V2SI 0 "gpr_operand" "")
2558 (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "")
2559 (match_operand:SI 2 "general_operand")))
2561 (clobber (reg:CC_FP CCFP_REGNUM))])]
2564 if (const_int_operand (operands[2], VOIDmode))
2566 = copy_to_mode_reg (SImode, GEN_INT (1 << INTVAL (operands[2])));
2570 rtx xop[2], last_out = pc_rtx;
2572 for (o = 0; o <= UNITS_PER_WORD; o += UNITS_PER_WORD)
2574 for (i = 0; i < 2; i++)
2577 = (i == 2 ? operands[2]
2578 : simplify_gen_subreg (SImode, operands[i], V2SImode, o));
2579 gcc_assert (!reg_overlap_mentioned_p (last_out, xop[i])
2580 /* ??? reg_overlap_mentioned_p doesn't understand
2581 about multi-word SUBREGs. */
2582 || (GET_CODE (last_out) == SUBREG
2583 && GET_CODE (xop[i]) == SUBREG
2584 && SUBREG_REG (last_out) == SUBREG_REG (xop[i])
2585 && ((SUBREG_BYTE (last_out) & -UNITS_PER_WORD)
2586 != (SUBREG_BYTE (xop[i]) & -UNITS_PER_WORD))));
2588 emit_insn (gen_ashlsi3 (xop[0], xop[1], operands[2]));
2595 (define_insn_and_split "*ashlv2si3_i"
2596 [(match_parallel 3 "float_operation"
2597 [(set (match_operand:V2SI 0 "gpr_operand" "=&r,*1*2")
2598 (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "r,r")
2599 (match_operand 2 "const_int_operand" "n,n")))
2600 (use (match_operand:SI 4 "gpr_operand" "r,r"))
2601 (clobber (reg:CC_FP CCFP_REGNUM))])]
2606 [(set (match_dup 5) (mult:SI (match_dup 6) (match_dup 4)))
2607 (clobber (reg:CC_FP CCFP_REGNUM))
2611 [(set (match_dup 7) (mult:SI (match_dup 8) (match_dup 4)))
2612 (clobber (reg:CC_FP CCFP_REGNUM))
2616 operands[5] = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
2617 operands[6] = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
2618 operands[7] = simplify_gen_subreg (SImode, operands[0],
2619 V2SImode, UNITS_PER_WORD);
2620 operands[8] = simplify_gen_subreg (SImode, operands[1],
2621 V2SImode, UNITS_PER_WORD);
2622 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[8]));
2623 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[4]));
2624 operands[9] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2625 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2631 gen_rtx_SET (VOIDmode, operands[5],
2632 gen_rtx_MULT (SImode, operands[6], operands[4])),
2633 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
2634 operands[9], operands[10])));
2635 insn = emit_insn (insn);
2636 add_reg_note (insn, REG_EQUAL,
2637 gen_rtx_ASHIFT (SImode, operands[6], operands[2]));
2643 gen_rtx_SET (VOIDmode, operands[7],
2644 gen_rtx_MULT (SImode, operands[8], operands[4])),
2645 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
2646 operands[9], operands[10])));
2647 insn = emit_insn (insn);
2648 add_reg_note (insn, REG_EQUAL,
2649 gen_rtx_ASHIFT (SImode, operands[7], operands[2]));
2652 [(set_attr "length" "8")
2653 (set_attr "type" "fp_int")])
2655 (define_expand "mul<mode>3"
2657 [(set (match_operand:DWV2MODE 0 "gpr_operand" "")
2658 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "")
2659 (match_operand:DWV2MODE 2 "gpr_operand" "")))
2660 (clobber (reg:CC_FP CCFP_REGNUM))])])
2662 (define_insn_and_split "mul<mode>3_i"
2663 [(match_parallel 3 "float_operation"
2664 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2665 (mult:DWV2MODE (match_operand:DWV2MODE 1 "gpr_operand" "r")
2666 (match_operand:DWV2MODE 2 "gpr_operand" "r")))
2667 (clobber (reg:CC_FP CCFP_REGNUM))])]
2670 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2672 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6)))
2673 (clobber (reg:CC_FP CCFP_REGNUM))
2677 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9)))
2678 (clobber (reg:CC_FP CCFP_REGNUM))
2683 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2685 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2687 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2688 operands[7] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2689 <MODE>mode, UNITS_PER_WORD);
2690 operands[8] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2691 <MODE>mode, UNITS_PER_WORD);
2692 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2693 <MODE>mode, UNITS_PER_WORD);
2694 if (!reload_completed)
2696 if (reg_overlap_mentioned_p (operands[4], operands[8]))
2697 operands[8] = copy_to_mode_reg (<vmode_PART>mode, operands[8]);
2698 if (reg_overlap_mentioned_p (operands[4], operands[9]))
2699 operands[9] = copy_to_mode_reg (<vmode_PART>mode, operands[9]);
2700 emit_insn (gen_mul<vmode_part>3 (operands[4], operands[5], operands[6]));
2701 emit_insn (gen_mul<vmode_part>3 (operands[7], operands[8], operands[9]));
2704 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[8]));
2705 gcc_assert (!reg_overlap_mentioned_p (operands[4], operands[9]));
2706 operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
2707 operands[11] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
2709 [(set_attr "length" "8")
2710 (set_attr "type" "<vmode_fp_type>")])
2712 (define_insn_and_split "*fmadd<mode>_combine"
2713 [(match_parallel 4 "float_operation"
2714 [(set (match_operand:DWV2MODE 0 "gpr_operand" "=r")
2715 (plus:DWV2MODE (mult:<MODE>
2716 (match_operand:<MODE> 1 "gpr_operand" "r")
2717 (match_operand:<MODE> 2 "gpr_operand" "r"))
2718 (match_operand:<MODE> 3 "gpr_operand" "0")))
2719 (clobber (reg:CC_FP CCFP_REGNUM))])]
2720 "TARGET_FUSED_MADD || <MODE>mode == V2SImode"
2722 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)"
2725 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7))
2727 (clobber (reg:CC_FP CCFP_REGNUM))
2732 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11))
2734 (clobber (reg:CC_FP CCFP_REGNUM))
2739 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2741 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2743 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0);
2745 = simplify_gen_subreg (<vmode_PART>mode, operands[3], <MODE>mode, 0);
2746 operands[9] = simplify_gen_subreg (<vmode_PART>mode, operands[0],
2747 <MODE>mode, UNITS_PER_WORD);
2748 operands[10] = simplify_gen_subreg (<vmode_PART>mode, operands[1],
2749 <MODE>mode, UNITS_PER_WORD);
2750 operands[11] = simplify_gen_subreg (<vmode_PART>mode, operands[2],
2751 <MODE>mode, UNITS_PER_WORD);
2752 operands[12] = simplify_gen_subreg (<vmode_PART>mode, operands[3],
2753 <MODE>mode, UNITS_PER_WORD);
2754 if (!reload_completed)
2756 if (reg_overlap_mentioned_p (operands[5], operands[10]))
2757 operands[10] = copy_to_mode_reg (<vmode_PART>mode, operands[10]);
2758 if (reg_overlap_mentioned_p (operands[5], operands[11]))
2759 operands[11] = copy_to_mode_reg (<vmode_PART>mode, operands[11]);
2760 if (reg_overlap_mentioned_p (operands[5], operands[12]))
2761 operands[12] = copy_to_mode_reg (<vmode_PART>mode, operands[12]);
2762 emit_insn (gen_madd<vmode_part> (operands[5], operands[6], operands[7],
2764 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11],
2768 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[10]));
2769 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[11]));
2770 gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[12]));
2771 operands[13] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 2);
2772 operands[14] = XVECEXP (operands[4], 0, XVECLEN (operands[4], 0) - 1);
2774 [(set_attr "length" "8")
2775 (set_attr "type" "<vmode_fp_type>")])
2777 (define_expand "vec_set<mode>"
2778 [(match_operand:DWV2MODE 0 "register_operand")
2779 (match_operand:<vmode_PART> 1 "register_operand")
2780 (match_operand 2 "const_int_operand" "")]
2784 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2785 UNITS_PER_WORD * INTVAL (operands[2]));
2786 emit_move_insn (operands[0], operands[1]);
2790 (define_expand "movmisalign<mode>"
2791 [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "")
2792 (match_operand:DWV2MODE 1 "general_operand" ""))]
2795 rtx op00, op01, op10, op11;
2797 op00 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0);
2798 op01 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode,
2800 op10 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0);
2801 op11 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode,
2803 emit_move_insn (op00, op10);
2804 emit_move_insn (op01, op11);
2812 [(set_attr "type" "flow")])