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. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11 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. 16 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/>. 20 21;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23(define_constants 24 [(GPR_0 0) 25 (GPR_FP 11) 26 (GPR_IP 12) 27 (GPR_SP 13) 28 (GPR_LR 14) 29 (GPR_16 16) 30 (GPR_18 18) 31 (GPR_20 20) 32 (ARG_POINTER_REGNUM 64) 33 (FRAME_POINTER_REGNUM 65) 34 (CC_REGNUM 66) ;; 66 or 17 35 (CCFP_REGNUM 67) ;; 67 or 18 36 (CONFIG_REGNUM 68) 37 (STATUS_REGNUM 69) 38 (LC_REGNUM 70) 39 (LS_REGNUM 71) 40 (LE_REGNUM 72) 41 (IRET_REGNUM 73) 42 (FP_NEAREST_REGNUM 74) 43 (FP_TRUNCATE_REGNUM 75) 44 (FP_ANYFP_REGNUM 76) 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) 51 (UNSPEC_FP_MODE 1) 52 53 (UNSPECV_GID 0) 54 (UNSPECV_GIE 1)]) 55 56;; Insn type. Used to default other attribute values. 57 58(define_attr "type" 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")) 61 62;; Length (in # bytes) 63 64(define_attr "length" "" (const_int 4)) 65 66;; The length here is the length of a single asm. 67 68(define_asm_attributes 69 [(set_attr "length" "4") 70 (set_attr "type" "misc")]) 71 72;; pipeline model; so far we have only one. 73(define_attr "pipe_model" "epiphany" (const_string "epiphany")) 74 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"))) 79 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") 86 (const_string "int")] 87 (const_string "none"))) 88 89(include "epiphany-sched.md") 90 91(include "predicates.md") 92(include "constraints.md") 93 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]) 97 98;; modes that are held in a two single registers 99(define_mode_iterator DWMODE [DI DF V2SI V2SF V4HI V8QI]) 100 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")]) 108 109;; Move instructions. 110 111(define_expand "mov<mode>" 112 [(set (match_operand:WMODE 0 "general_operand" "") 113 (match_operand:WMODE 1 "general_operand" ""))] 114 "" 115{ 116 if (<MODE>mode == V4QImode || <MODE>mode == V2HImode) 117 { 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])); 121 DONE; 122 } 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)) 127 { 128 rtx reg = operands[0]; 129 130 if (!REG_P (reg)) 131 reg = gen_reg_rtx (SImode); 132 emit_insn (gen_move_frame (reg, operands[1])); 133 operands[1] = reg; 134 if (operands[0] == reg) 135 DONE; 136 } 137}) 138 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"))] 142;; ??? Needed? 143 "gpr_operand (operands[0], QImode) 144 || gpr_operand (operands[1], QImode)" 145 "@ 146 mov %0,%1 147 mov %0,%1 148 mov %0,%1 149 ldrb %0,%1 150 strb %1,%0" 151 [(set_attr "type" "move,move,move,load,store")]) 152 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)" 158 "@ 159 mov %0,%1 160 mov %0,%%low(%1); %1 161 ldrh %0,%c1 162 strh %1,%c0" 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")]) 169 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 177;; register. 178;; 179;; N.B. operand 1 is an operand so that reload will perform elimination. 180;; 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" 187 "#") 188 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"))))] 193 "" 194 "movt %0, %%high(%1)" 195 [(set_attr "type" "move") 196 (set_attr "length" "4")]) 197 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")))] 202 "" 203 "mov %0, %%low(%1)" 204 [(set_attr "type" "move") 205 (set_attr "length" "4")]) 206 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])" 215{ 216 switch (which_alternative) 217 { 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 (); 230 } 231} 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")]) 243 244(define_split 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))]) 249 250(define_split 251 [(set (match_operand:SI 0 "gpr_operand") 252 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))] 253 "reload_completed" 254 [(set (match_dup 0) (match_dup 1))] 255{ 256 emit_insn (gen_reload_insi_ra (operands[0], operands[1])); 257 DONE; 258}) 259 260(define_expand "reload_insi_ra" 261 [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))] 262 "" 263{ 264 rtx addr 265 = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx); 266 267 addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset); 268 operands[1] = gen_frame_mem (SImode, addr); 269}) 270 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)" 286 "#" 287 "reload_in_progress || reload_completed" 288 [(set (match_dup 0) (match_dup 1))]) 289 290(define_expand "mov<mode>" 291 [(set (match_operand:DWMODE 0 "general_operand" "") 292 (match_operand:DWMODE 1 "general_operand" ""))] 293 "" 294 " 295{ 296 if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT 297 || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT) 298 { 299 if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY) 300 { 301 rtx o0l, o0h, o1l, o1h; 302 303 o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0); 304 o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 305 UNITS_PER_WORD); 306 o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0); 307 o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 308 UNITS_PER_WORD); 309 if (reg_overlap_mentioned_p (o0l, o1h)) 310 { 311 emit_move_insn (o0h, o1h); 312 emit_move_insn (o0l, o1l); 313 } 314 else 315 { 316 emit_move_insn (o0l, o1l); 317 emit_move_insn (o0h, o1h); 318 } 319 DONE; 320 } 321 /* lower_subreg has a tendency to muck up vectorized code. 322 To protect the wide memory accesses, we must use same-size 323 subregs. */ 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))) 332 { 333 operands[0] 334 = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0); 335 operands[1] 336 = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0); 337 emit_insn (gen_movdi (operands[0], operands[1])); 338 DONE; 339 } 340 } 341 /* Everything except mem = const or mem = mem can be done easily. */ 342 343 if (GET_CODE (operands[0]) == MEM) 344 operands[1] = force_reg (<MODE>mode, operands[1]); 345}") 346 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))" 352 "@ 353 # 354 # 355 ldrd %0,%X1 356 strd %1,%X0" 357 "reload_completed 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))] 364{ 365 int word0 = 0, word1 = UNITS_PER_WORD; 366 367 if (post_modify_operand (operands[0], <MODE>mode) 368 || post_modify_operand (operands[1], <MODE>mode)) 369 word0 = UNITS_PER_WORD, word1 = 0; 370 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)) 376 operands[2] 377 = change_address (operands[2], VOIDmode, 378 plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0), 379 UNITS_PER_WORD)); 380 if (post_modify_operand (operands[1], <MODE>mode)) 381 operands[3] 382 = change_address (operands[3], VOIDmode, 383 plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0), 384 UNITS_PER_WORD)); 385} 386 [(set_attr "type" "move,move,load,store") 387 (set_attr "length" "8,16,4,4")]) 388 389 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)" 395 "@ 396 mov %0,%1 397 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1 398 ldr %0,%C1 399 str %1,%C0" 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")]) 406 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" "")))] 411 "" 412 " 413{ 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])); 418 else 419 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2])); 420 DONE; 421}") 422 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))] 428 "" 429 "add %0,%1,%2" 430[(set_attr "type" "misc")]) 431 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. 435; 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" 444{ 445 int scratch = (0x17 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); 454 return ""; 455} 456 [(set_attr "length" "20") 457 (set_attr "type" "misc")]) 458 459;; reload uses gen_addsi2 because it doesn't understand the need for 460;; the clobber. 461(define_peephole2 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))])] 476 ;; FIXME: 477 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html 478 ;; "peep2_rescan = true;" 479) 480 481(define_peephole2 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))]) 498 (match_dup 5)] 499 "") 500 501(define_peephole2 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))])] 513 "") 514 515(define_peephole2 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)))) 525 (reg:WMODE GPR_SP))] 526 "") 527 528 529 530(define_peephole2 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)) 541 (set (match_dup 2) 542 (mem:WMODE (post_modify (match_dup 0) 543 (plus:SI (match_dup 0) (match_dup 1)))))] 544 "") 545 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" "")))] 550 "" 551 " 552{ 553 gcc_assert (!reload_in_progress && !reload_completed); 554 555 if (TARGET_FP_IARITH) 556 emit_insn (gen_isub (operands[0], operands[1], operands[2])); 557 else 558 emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2])); 559 DONE; 560}") 561 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))] 567 "" 568 "sub %0,%1,%2" 569 [(set_attr "type" "misc")]) 570 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 578; USE. 579 580;; Addition 581(define_expand "addsf3" 582 [(parallel 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))])]) 587 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))])] 594 "" 595 "fadd %0,%1,%2" 596 [(set_attr "type" "fp")]) 597 598;; Subtraction 599(define_expand "subsf3" 600 [(parallel 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))])]) 605 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))])] 612 "" 613 "fsub %0,%1,%2" 614 [(set_attr "type" "fp")]) 615 616(define_expand "subsf3_f" 617 [(parallel 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") 624 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)))])] 632 "!TARGET_SOFT_CMPSF" 633 "fsub %0,%1,%2" 634 [(set_attr "type" "fp")]) 635 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" "")))] 640 "" 641 " 642{ 643 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1], 644 SFmode, 0)); 645 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0); 646 647 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx)); 648 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx)); 649 DONE; 650}") 651 652;; Multiplication 653(define_expand "mulsf3" 654 [(parallel 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))])]) 659 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))])] 666 "" 667 "fmul %0,%1,%2" 668 [(set_attr "type" "fp")]) 669 670;; Division 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" 676{ 677 rtx one = CONST1_RTX (SFmode); 678 rtx dst = operands[0]; 679 680 if (rtx_equal_p (dst, operands[1])) 681 { 682 emit_move_insn (dst, one); 683 DONE; 684 } 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)); 690 DONE; 691}) 692 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" 701 [(parallel 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" "")) 706 (clobber (reg:SF 0)) 707 (clobber (reg:SI 1)) 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))])]) 715 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")) 722 (clobber (reg:SF 0)) 723 (clobber (reg:SI 1)) 724 (clobber (reg:SF GPR_IP)) 725 (clobber (reg:DI GPR_16)) 726 (clobber (reg:DI GPR_18)) 727 (clobber (reg:SI GPR_20)) 728 (clobber (reg:SI GPR_LR)) 729 (clobber (reg:CC CC_REGNUM)) 730 (clobber (reg:CC_FP CCFP_REGNUM))])] 731 "flag_reciprocal_math" 732 "#" 733 "&& reload_completed" 734 [(set (reg:SI 1) (match_dup 3)) 735 (set (reg:SF 0) (match_dup 2)) 736 (parallel 737 [(set (reg:SF 0) 738 (div:SF (match_dup 1) 739 (reg:SF 0))) 740 (use (reg:SI 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)) 748 (match_dup 5) 749 (match_dup 6)]) 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")]) 755 756(define_insn "*recipsf2_2" 757 [(match_parallel 1 "float_operation" 758 [(set (reg:SF 0) 759 (div:SF (match_operand:SF 0 "const_float_1_operand" "") 760 (reg:SF 0))) 761 (use (reg:SI 1)) 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" 770 "jalr r1" 771 [(set_attr "type" "fp_sfunc")]) 772 773 774;; Fused multiply-add 775(define_expand "fmasf4" 776 [(parallel 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))])] 782 "") 783 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))])] 793 "" 794 "fmadd %0,%1,%2" 795 [(set_attr "type" "fp")]) 796 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. 802; 803; combiner pattern, also used by vector combiner pattern 804(define_expand "maddsf" 805 [(parallel 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))])] 811 "TARGET_FUSED_MADD") 812 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))])] 820 "TARGET_FUSED_MADD" 821 "fmadd %0,%1,%2" 822 [(set_attr "type" "fp")]) 823 824;; Fused multiply-sub 825(define_expand "fnmasf4" 826 [(parallel 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))])] 832 "") 833 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))])] 841 "" 842 "fmsub %0,%1,%2" 843 [(set_attr "type" "fp")]) 844 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))])] 852 "TARGET_FUSED_MADD" 853 "fmsub %0,%1,%2" 854 [(set_attr "type" "fp")]) 855 856;; float / integer conversions 857 858(define_expand "floatsisf2" 859 [(parallel 860 [(set (match_operand:SF 0 "gpr_operand" "") 861 (float:SF (match_operand:SI 1 "gpr_operand" ""))) 862 (clobber (reg:CC_FP CCFP_REGNUM))])]) 863 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))])] 869 "" 870 "float %0, %1" 871 [(set_attr "type" "fp")]) 872 873(define_expand "floatsisf2_cmp" 874 [(parallel 875 [(set (reg:CC_FP CCFP_REGNUM) 876 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r")) 877 (match_dup 2))) 878 (set (match_operand:SF 0 "gpr_operand" "=r") 879 (float:SF (match_dup 1)))])] 880 "" 881 "operands[2] = CONST0_RTX (SFmode);") 882 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)))])] 890 "" 891 "float %0, %1" 892 [(set_attr "type" "fp")]) 893 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" 898{ 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); 902 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), 910 operands[0])); 911 DONE; 912}) 913 914(define_expand "fix_truncsfsi2" 915 [(parallel 916 [(set (match_operand:SI 0 "gpr_operand" "") 917 (fix:SI (match_operand:SF 1 "gpr_operand" ""))) 918 (clobber (reg:CC_FP CCFP_REGNUM))])]) 919 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))])] 925 "" 926 "fix %0, %1" 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")))]) 932 933(define_expand "fixuns_truncsfsi2" 934 [(set (match_operand:SI 0 "gpr_operand" "") 935 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))] 936 "" 937{ 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)) 941 { 942 rtx op1si; 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)); 948 rtx cmp 949 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx); 950 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])); 957 } 958 else 959 { 960 REAL_VALUE_TYPE offset; 961 rtx limit; 962 rtx tmp = gen_reg_rtx (SFmode); 963 rtx label = gen_label_rtx (); 964 rtx bit31; 965 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM); 966 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode)); 967 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)); 977 emit_label (label); 978 } 979 DONE; 980}) 981 982(define_expand "iadd" 983 [(parallel 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))])]) 988 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))])] 995 "" 996 "iadd %0, %1, %2" 997 [(set_attr "type" "fp_int")]) 998 999(define_expand "isub" 1000 [(parallel 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))])]) 1005 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))])] 1012 "" 1013 "isub %0, %1, %2" 1014 [(set_attr "type" "fp_int")]) 1015 1016; Try to figure out if we over-committed the FPU, and if so, move 1017; some insns back over to the integer pipe. 1018 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. 1031(define_peephole2 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))])] 1043) 1044 1045(define_expand "mulsi3" 1046 [(parallel 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))])]) 1051 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))])] 1058 "" 1059 "imul %0, %1, %2" 1060 [(set_attr "type" "fp_int")]) 1061 1062; combiner pattern, also used by vector combiner pattern 1063(define_expand "maddsi" 1064 [(parallel 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))])] 1070 "") 1071 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))])] 1079 "" 1080 "imadd %0, %1, %2" 1081 [(set_attr "type" "fp_int")]) 1082 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))])] 1090 "" 1091 "imsub %0, %1, %2" 1092 [(set_attr "type" "fp_int")]) 1093 1094(define_expand "divsi3" 1095 [(parallel 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" ""))) 1099 (use (match_dup 3)) 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))])] 1109 "" 1110 "operands[3] = sfunc_symbol (\"__divsi3\");") 1111 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))])] 1129 "" 1130 "#" 1131 "&& reload_completed" 1132 [(set (reg:SI 0) (match_dup 1)) 1133 (set (reg:SI 1) (match_dup 2)) 1134 (parallel 1135 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1))) 1136 (use (match_dup 3)) 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)) 1145 (match_dup 5) 1146 (match_dup 6)]) 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")]) 1152 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))])] 1165 "" 1166 "%f0" 1167 [(set_attr "type" "fp_sfunc")]) 1168 1169(define_expand "udivsi3" 1170 [(parallel 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" ""))) 1174 (use (match_dup 3)) 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))])] 1183 "" 1184 "operands[3] = sfunc_symbol (\"__udivsi3\");") 1185 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))])] 1202 "" 1203 "#" 1204 "&& reload_completed" 1205 [(set (reg:SI 0) (match_dup 1)) 1206 (set (reg:SI 1) (match_dup 2)) 1207 (parallel 1208 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1))) 1209 (use (match_dup 3)) 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)) 1217 (match_dup 5) 1218 (match_dup 6)]) 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")]) 1224 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))])] 1236 "" 1237 "%f0" 1238 [(set_attr "type" "fp_sfunc")]) 1239 1240(define_expand "modsi3" 1241 [(parallel 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" ""))) 1245 (use (match_dup 3)) 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))])] 1255 "" 1256 "operands[3] = sfunc_symbol (\"__modsi3\");") 1257 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))])] 1275 "" 1276 "#" 1277 "&& reload_completed" 1278 [(set (reg:SI 0) (match_dup 1)) 1279 (set (reg:SI 1) (match_dup 2)) 1280 (parallel 1281 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1))) 1282 (use (match_dup 3)) 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)) 1290 (match_dup 5) 1291 (match_dup 6)]) 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")]) 1297 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))])] 1309 "" 1310 "%f0" 1311 [(set_attr "type" "fp_sfunc")]) 1312 1313(define_expand "umodsi3" 1314 [(parallel 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" ""))) 1318 (use (match_dup 3)) 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))])] 1327 "" 1328 "operands[3] = sfunc_symbol (\"__umodsi3\");") 1329 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))])] 1346 "" 1347 "#" 1348 "&& reload_completed" 1349 [(set (reg:SI 0) (match_dup 1)) 1350 (set (reg:SI 1) (match_dup 2)) 1351 (parallel 1352 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1))) 1353 (use (match_dup 3)) 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)) 1360 (match_dup 5) 1361 (match_dup 6)]) 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")]) 1367 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))])] 1378 "" 1379 "%f0" 1380 [(set_attr "type" "fp_sfunc")]) 1381 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. 1385(define_insn "gid" 1386 [(set (reg:SI CONFIG_REGNUM) 1387 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))] 1388 "" 1389 "gid" 1390 [(set_attr "type" "flow")]) 1391 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. 1396(define_insn "gie" 1397 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)] 1398 "" 1399 "gie" 1400 [(set_attr "type" "flow")]) 1401 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 1408; lead to disaster. 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" "")) 1418 (use (match_dup 2)) 1419 (clobber (match_scratch:SI 3 "=X, &r"))])] 1420 "" 1421 "operands[2] = gen_int_mode (~0x10f0, SImode);") 1422 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"))] 1428 "" 1429 "@ 1430 movfs %0,status 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")]) 1434 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))] 1440 "" 1441 "#" 1442 "reload_completed" 1443 [(set (match_dup 0) (reg:SI CONFIG_REGNUM))]) 1444 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"))] 1454 "" 1455 "#" 1456 "reload_completed || !rtx_equal_p (operands[0], operands[1])" 1457 [(const_int 0)] 1458{ 1459 if (!reload_completed) 1460 emit_note (NOTE_INSN_DELETED); 1461 else 1462 epiphany_expand_set_fp_mode (operands); 1463 DONE; 1464}) 1465 1466 1467;; Boolean instructions. 1468;; 1469;; We don't define the DImode versions as expand_binop does a good enough job. 1470 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))] 1476 "" 1477 "and %0,%1,%2") 1478 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))] 1484 "" 1485 "orr %0,%1,%2") 1486 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))] 1492 "" 1493 "eor %0,%1,%2") 1494 1495(define_expand "one_cmplsi2" 1496 [(set (match_operand:SI 0 "gpr_operand" "") 1497 (xor:SI (match_operand:SI 1 "gpr_operand" "") 1498 (match_dup 2)))] 1499 "" 1500{ 1501 if (epiphany_m1reg >= 0) 1502 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1])); 1503 else 1504 emit_insn (gen_xorsi3 (operands[0], operands[1], 1505 force_reg (SImode, GEN_INT (-1)))); 1506 DONE; 1507}) 1508 1509; Note that folding this pattern into the xorsi3 pattern would make combine 1510; less effective. 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" 1516 "eor %0,%1,%-") 1517 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))] 1527 "" 1528 "asr %0,%1,%2" 1529 [(set_attr "length" "4") 1530 (set_attr "type" "shift")]) 1531 1532(define_insn "ashrsi3_tst" 1533 [(set (reg:CC CC_REGNUM) 1534 (compare:CC 1535 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r") 1536 (match_operand:SI 2 "arith_operand" "r,K")) 1537 (const_int 0))) 1538 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1539 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 1540 "" 1541 "asr %0,%1,%2" 1542 [(set_attr "length" "4") 1543 (set_attr "type" "shift")]) 1544 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))] 1551 "" 1552 "lsr %0,%1,%2" 1553 [(set_attr "length" "4") 1554 (set_attr "type" "shift")]) 1555 1556(define_insn "lshrsi3_tst" 1557 [(set (reg:CC CC_REGNUM) 1558 (compare:CC 1559 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r") 1560 (match_operand:SI 2 "arith_operand" "r,K")) 1561 (const_int 0))) 1562 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1563 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 1564 "" 1565 "lsr %0,%1,%2" 1566 [(set_attr "length" "4") 1567 (set_attr "type" "shift")]) 1568 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))] 1575 "" 1576 "lsl %0,%1,%2" 1577 [(set_attr "length" "4") 1578 (set_attr "type" "shift")]) 1579 1580(define_insn "*ashlsi_btst" 1581 [(set (reg:CC_N_NE CC_REGNUM) 1582 (compare:CC_N_NE 1583 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r") 1584 (const_int 1) 1585 (match_operand 2 "const_int_operand" "K")) 1586 (const_int 0))) 1587 (clobber (match_scratch:SI 0 "=r"))] 1588 "" 1589{ 1590 rtx xop[3]; 1591 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); 1596 return ""; 1597}) 1598 1599;; zero extensions 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))] 1604 "" 1605 "@ 1606 # 1607 ldrb %0,%1" 1608 "reload_completed 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);") 1616 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")))] 1620 "" 1621 "@ 1622 movt %0, 0 1623 ldrh %0,%c1") 1624 1625 1626;; Compare instructions. 1627 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"))] 1633 "" 1634 "sub %2,%0,%1" 1635 [(set_attr "type" "compare")]) 1636 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)))] 1643 "" 1644 "sub %0,%1,%2" 1645 [(set_attr "type" "compare")]) 1646 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])" 1654 "sub %0,%1,%2" 1655 [(set_attr "type" "compare")]) 1656 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" ""))) 1662 (set (match_dup 3) 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)) 1666 (match_dup 3) 1667 (match_dup 1)))] 1668 "TARGET_CMOVE" 1669 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);") 1670 1671(define_insn "*add_c" 1672 [(set (reg:CC_C_LTU CC_REGNUM) 1673 (compare:CC_C_LTU 1674 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r") 1675 (match_operand:SI 2 "arith_operand" "r,L")) 1676 (match_dup 1))) 1677 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1678 (plus:SI (match_dup 1) (match_dup 2)))] 1679 "" 1680 "add %0,%1,%2" 1681 [(set_attr "type" "compare")]) 1682 1683(define_insn "*add_c_rev" 1684 [(set (reg:CC_C_LTU CC_REGNUM) 1685 (compare:CC_C_LTU 1686 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r") 1687 (match_operand:SI 2 "arith_operand" "r,L")) 1688 (match_dup 1))) 1689 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1690 (plus:SI (match_dup 2) (match_dup 1)))] 1691 "" 1692 "add %0,%1,%2" 1693 [(set_attr "type" "compare")]) 1694 1695(define_insn "*sub_c" 1696 [(set (reg:CC_C_GTU CC_REGNUM) 1697 (compare:CC_C_GTU 1698 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r") 1699 (match_operand:SI 2 "arith_operand" "r,L")) 1700 (match_dup 1))) 1701 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1702 (minus:SI (match_dup 1) (match_dup 2)))] 1703 "" 1704 "sub %0,%1,%2" 1705 [(set_attr "type" "compare")]) 1706 1707(define_insn "*sub_c_void" 1708 [(set (reg:CC_C_GTU CC_REGNUM) 1709 (compare:CC_C_GTU 1710 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r") 1711 (match_operand:SI 2 "arith_operand" "r,L")) 1712 (match_dup 1))) 1713 (clobber (match_scratch:SI 0 "=r,r"))] 1714 "" 1715 "sub %0,%1,%2" 1716 [(set_attr "type" "compare")]) 1717 1718; floating point comparisons 1719 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" 1727 "fsub %2,%0,%1" 1728 [(set_attr "type" "fp") 1729 (set_attr "fp_mode" "round_unknown")]) 1730 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 1735;; a proper job. 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))] 1741 "TARGET_SOFT_CMPSF" 1742 "%f0" 1743 [(set_attr "type" "sfunc")]) 1744 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))] 1750 "TARGET_SOFT_CMPSF" 1751 "%f0" 1752 [(set_attr "type" "sfunc")]) 1753 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))] 1760 "TARGET_SOFT_CMPSF" 1761 "%f0" 1762 [(set_attr "type" "sfunc")]) 1763 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))] 1770 "TARGET_SOFT_CMPSF" 1771 "%f0" 1772 [(set_attr "type" "sfunc")]) 1773 1774;; conditional moves 1775 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" "")))] 1781 "TARGET_CMOVE" 1782{ 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]); 1787 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])) 1797 { 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)); 1802 } 1803 1804 if (proper_comparison_operator (operands[1], VOIDmode)) 1805 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1); 1806 else 1807 { 1808 if (!currently_expanding_to_rtl) 1809 { 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. */ 1815 } 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. */ 1822 operands[1] 1823 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1); 1824 } 1825}) 1826 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")))] 1833 "TARGET_CMOVE" 1834 "mov%d3 %0,%1" 1835 [(set_attr "type" "cmove")]) 1836 1837(define_peephole2 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" "")) 1844 (set (match_dup 3) 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" "") 1849 (match_dup 3)))] 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))]) 1857 (match_dup 2) 1858 (set (match_dup 3) 1859 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))] 1860{ 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])); 1866}) 1867 1868(define_peephole2 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")) 1874 (set (match_dup 3) 1875 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator" 1876 [(match_dup 6) 1877 (match_operand:WMODE 7 "const0_operand")]) 1878 (match_operand:WMODE2 8 "gpr_operand") 1879 (match_dup 3)))] 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))]) 1887 (set (match_dup 3) 1888 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))] 1889 " 1890{ 1891 operands[5] 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); 1897}") 1898 1899;; These control RTL generation for conditional jump insns 1900 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" ""))) 1907 (set (pc) 1908 (if_then_else 1909 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM) 1910 (const_int 0)]) 1911 (label_ref (match_operand 3 "" "")) 1912 (pc)))] 1913 "" 1914{ 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))); 1918 DONE; 1919}) 1920 1921(define_expand "cbranchsf4" 1922 [(set (reg CC_REGNUM) 1923 (compare (match_operand:SF 1 "arith_operand" "") 1924 (match_operand:SF 2 "arith_operand" ""))) 1925 (set (pc) 1926 (if_then_else 1927 (match_operator 0 "comparison_operator" [(reg CC_REGNUM) 1928 (const_int 0)]) 1929 (label_ref (match_operand 3 "" "")) 1930 (pc)))] 1931 "" 1932{ 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))); 1936 DONE; 1937}) 1938 1939;; Now match both normal and inverted jump. 1940 1941(define_insn "branch_insn" 1942 [(set (pc) 1943 (if_then_else (match_operator 1 "proper_comparison_operator" 1944 [(match_operand 2 "cc_operand") 1945 (const_int 0)]) 1946 (label_ref (match_operand 0 "" "")) 1947 (pc)))] 1948 "" 1949 "b%d1 %l0" 1950 [(set_attr "type" "branch")]) 1951 1952(define_insn "*rev_branch_insn" 1953 [(set (pc) 1954 (if_then_else (match_operator 1 "proper_comparison_operator" 1955 [(reg CC_REGNUM) (const_int 0)]) 1956 (pc) 1957 (label_ref (match_operand 0 "" ""))))] 1958 "" 1959 "b%D1 %l0" 1960 [(set_attr "type" "branch")]) 1961 1962;; Unconditional and other jump instructions. 1963 1964(define_insn "jump" 1965 [(set (pc) (label_ref (match_operand 0 "" "")))] 1966 "" 1967 "b %l0" 1968 [(set_attr "type" "uncond_branch")]) 1969 1970(define_insn "indirect_jump" 1971 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))] 1972 "" 1973 "jr %0" 1974 [(set_attr "type" "uncond_branch")]) 1975 1976(define_expand "tablejump" 1977 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" "")) 1978 (use (label_ref (match_operand 1 "" "")))])] 1979 "" 1980{ 1981 /* In PIC mode, the table entries are stored PC relative. 1982 Convert the relative address to an absolute address. */ 1983 if (flag_pic) 1984 { 1985 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 1986 1987 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], 1988 op1, NULL_RTX, 0, OPTAB_DIRECT); 1989 } 1990}) 1991 1992(define_insn "*tablejump_internal" 1993 [(set (pc) (match_operand:SI 0 "gpr_operand" "r")) 1994 (use (label_ref (match_operand 1 "" "")))] 1995 "" 1996 "jr %0;" 1997 [(set_attr "type" "uncond_branch")]) 1998 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" 2003 "jr %0;" 2004 [(set_attr "type" "uncond_branch")]) 2005 2006 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))])] 2013 "" 2014{ 2015 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]); 2016 2017 if (!call_operand (operands[1], VOIDmode)) 2018 operands[0] 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) 2023 { 2024 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2025 emit_call_insn 2026 (gen_rtx_PARALLEL 2027 (VOIDmode, 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 ()); 2032 DONE; 2033 } 2034}) 2035 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))])] 2041 "" 2042 "%f0" 2043 [(set_attr "type" "call")]) 2044 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 "" "")) 2050 (return)])] 2051 "" 2052{ 2053 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]); 2054 2055 if (!call_operand (operands[1], VOIDmode)) 2056 operands[0] 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) 2061 { 2062 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2063 emit_call_insn 2064 (gen_rtx_PARALLEL 2065 (VOIDmode, 2066 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]), 2067 ret_rtx))); 2068 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ()); 2069 DONE; 2070 } 2071}) 2072 2073(define_insn "*sibcall_i" 2074 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc")) 2075 (match_operand 1 "" "")) 2076 (return)] 2077 "" 2078 "@ 2079 b %0 2080 jr %0" 2081 [(set_attr "type" "call")]) 2082 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))])] 2090 "" 2091{ 2092 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]); 2093 2094 if (!call_operand (operands[1], VOIDmode)) 2095 operands[1] 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) 2100 { 2101 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2102 emit_call_insn 2103 (gen_rtx_PARALLEL 2104 (VOIDmode, 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 ()); 2111 DONE; 2112 } 2113}) 2114 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))])] 2121 "" 2122 "%f1" 2123 [(set_attr "type" "call") 2124 (set_attr "length" "4")]) 2125 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 "" ""))) 2132 (return)])] 2133 "" 2134{ 2135 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]); 2136 2137 if (!call_operand (operands[1], VOIDmode)) 2138 operands[1] 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) 2143 { 2144 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2145 emit_call_insn 2146 (gen_rtx_PARALLEL 2147 (VOIDmode, 2148 gen_rtvec (2, gen_rtx_SET 2149 (VOIDmode, operands[0], 2150 gen_rtx_CALL (VOIDmode, operands[1], operands[2])), 2151 ret_rtx))); 2152 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ()); 2153 DONE; 2154 } 2155}) 2156 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 "" ""))) 2161 (return)] 2162 "" 2163 "@ 2164 b %1 2165 jr %1" 2166 [(set_attr "type" "call") 2167 (set_attr "length" "4")]) 2168 2169(define_expand "prologue" 2170 [(pc)] 2171 "" 2172{ 2173 epiphany_expand_prologue (); 2174 DONE; 2175}) 2176 2177(define_expand "epilogue" 2178 [(pc)] 2179 "" 2180{ 2181 epiphany_expand_epilogue (0); 2182 DONE; 2183}) 2184 2185(define_expand "sibcall_epilogue" 2186 [(pc)] 2187 "" 2188{ 2189 epiphany_expand_epilogue (1); 2190 DONE; 2191}) 2192 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" 2200 [(return)] 2201 "reload_completed" 2202 "rts" 2203 [(set_attr "type" "uncond_branch")]) 2204 2205(define_insn "return_internal_interrupt" 2206 [(return) 2207 (unspec_volatile [(const_int 0)] 1)] 2208 "" 2209 "rti" 2210 [(set_attr "type" "uncond_branch")]) 2211 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"))] 2218 "reload_completed" 2219 "add sp,sp,%0") 2220 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"))] 2224 "reload_completed" 2225 "mov sp,fp" 2226 [(set_attr "type" "move")]) 2227 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"))] 2234 "reload_completed" 2235{ 2236 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 2237 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\"); 2238} 2239 [(set_attr "type" "store")]) 2240 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"))] 2247 "reload_completed" 2248 "ldr %0,%1,%C2" 2249 [(set_attr "type" "load")]) 2250 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")] 2256 "" 2257{ 2258 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0); 2259 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0); 2260 rtx outh 2261 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD); 2262 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))); 2268 DONE; 2269}) 2270 2271(define_expand "vec_unpacks_hi_v4hi" 2272 [(match_operand:V2SI 0 "gpr_operand") 2273 (match_operand:V4HI 1 "gpr_operand")] 2274 "" 2275{ 2276 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD); 2277 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0); 2278 rtx outh 2279 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD); 2280 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))); 2286 DONE; 2287}) 2288 2289(define_code_iterator addsub [plus minus]) 2290 2291(define_code_iterator alu_binop 2292 [plus minus and ior xor]) 2293 2294(define_code_attr insn_opname 2295 [(plus "add") (minus "sub") (mult "mul") (div "div") 2296 (and "and") (ior "ior") (xor "xor")]) 2297 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))] 2307 "" 2308 "#" 2309 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2310 [(const_int 0)] 2311{ 2312 rtx o0l, o0h, o1l, o1h, o2l, o2h; 2313 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)); 2326 DONE; 2327} 2328 [(set_attr "length" "8")]) 2329 2330(define_expand "<insn_opname>v2sf3" 2331 [(parallel 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))])]) 2336 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))])] 2343 "" 2344 "#" 2345 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2346 [(parallel 2347 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6))) 2348 (clobber (reg:CC_FP CCFP_REGNUM)) 2349 (match_dup 10) 2350 (match_dup 11)]) 2351 (parallel 2352 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9))) 2353 (clobber (reg:CC_FP CCFP_REGNUM)) 2354 (match_dup 10) 2355 (match_dup 11)])] 2356{ 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); 2360 operands[7] 2361 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD); 2362 operands[8] 2363 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD); 2364 operands[9] 2365 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD); 2366 if (!reload_completed) 2367 { 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])); 2374 DONE; 2375 } 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); 2380} 2381 [(set_attr "length" "8") 2382 (set_attr "type" "v2fp")]) 2383 2384(define_expand "mul<mode>3" 2385 [(parallel 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))])]) 2390 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))])] 2397 "" 2398 "#" 2399 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2400 [(parallel 2401 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6))) 2402 (clobber (reg:CC_FP CCFP_REGNUM)) 2403 (match_dup 10) 2404 (match_dup 11)]) 2405 (parallel 2406 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9))) 2407 (clobber (reg:CC_FP CCFP_REGNUM)) 2408 (match_dup 10) 2409 (match_dup 11)])] 2410{ 2411 operands[4] 2412 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0); 2413 operands[5] 2414 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0); 2415 operands[6] 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) 2424 { 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])); 2431 DONE; 2432 } 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); 2437} 2438 [(set_attr "length" "8") 2439 (set_attr "type" "<vmode_fp_type>")]) 2440 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" 2450 "#" 2451 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2452 [(parallel 2453 [(set (match_dup 5) 2454 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7)) 2455 (match_dup 8))) 2456 (clobber (reg:CC_FP CCFP_REGNUM)) 2457 (match_dup 13) 2458 (match_dup 14)]) 2459 (parallel 2460 [(set (match_dup 9) 2461 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11)) 2462 (match_dup 12))) 2463 (clobber (reg:CC_FP CCFP_REGNUM)) 2464 (match_dup 13) 2465 (match_dup 14)])] 2466{ 2467 operands[5] 2468 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0); 2469 operands[6] 2470 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0); 2471 operands[7] 2472 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0); 2473 operands[8] 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) 2484 { 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], 2492 operands[8])); 2493 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11], 2494 operands[12])); 2495 DONE; 2496 } 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); 2502} 2503 [(set_attr "length" "8") 2504 (set_attr "type" "<vmode_fp_type>")]) 2505 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" "")] 2510 "" 2511{ 2512 operands[0] 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]); 2516 DONE; 2517}) 2518 2519(define_expand "movmisalign<mode>" 2520 [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "") 2521 (match_operand:DWV2MODE 1 "general_operand" ""))] 2522 "" 2523{ 2524 rtx op00, op01, op10, op11; 2525 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, 2528 UNITS_PER_WORD); 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, 2531 UNITS_PER_WORD); 2532 emit_move_insn (op00, op10); 2533 emit_move_insn (op01, op11); 2534 DONE; 2535}) 2536 2537(define_insn "nop" 2538 [(const_int 0)] 2539 "" 2540 "nop" 2541 [(set_attr "type" "flow")]) 2542