1;; Machine description of the Adaptiva epiphany cpu for GNU C compiler 2;; Copyright (C) 1994-2018 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_1 1) 26 (GPR_FP 11) 27 (GPR_IP 12) 28 (GPR_SP 13) 29 (GPR_LR 14) 30 (GPR_16 16) 31 (GPR_18 18) 32 (GPR_20 20) 33 (ARG_POINTER_REGNUM 64) 34 (FRAME_POINTER_REGNUM 65) 35 (CC_REGNUM 66) ;; 66 or 17 36 (CCFP_REGNUM 67) ;; 67 or 18 37 (CONFIG_REGNUM 68) 38 (STATUS_REGNUM 69) 39 (LC_REGNUM 70) 40 (LS_REGNUM 71) 41 (LE_REGNUM 72) 42 (IRET_REGNUM 73) 43 (FP_NEAREST_REGNUM 74) 44 (FP_TRUNCATE_REGNUM 75) 45 (FP_ANYFP_REGNUM 76) 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) 52 (UNSPEC_FP_MODE 1) 53 54 (UNSPECV_GID 0) 55 (UNSPECV_GIE 1)]) 56 57;; Insn type. Used to default other attribute values. 58 59(define_attr "type" 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")) 62 63;; Length (in # bytes) 64 65(define_attr "length" "" (const_int 4)) 66 67;; The length here is the length of a single asm. 68 69(define_asm_attributes 70 [(set_attr "length" "4") 71 (set_attr "type" "misc")]) 72 73;; pipeline model; so far we have only one. 74(define_attr "pipe_model" "epiphany" (const_string "epiphany")) 75 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"))) 80 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") 87 (const_string "int")] 88 (const_string "none"))) 89 90(include "epiphany-sched.md") 91 92(include "predicates.md") 93(include "constraints.md") 94 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]) 98 99;; modes that are held in a two single registers 100(define_mode_iterator DWMODE [DI DF V2SI V2SF V4HI V8QI]) 101 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")]) 109 110;; Move instructions. 111 112(define_expand "mov<mode>" 113 [(set (match_operand:WMODE 0 "general_operand" "") 114 (match_operand:WMODE 1 "general_operand" ""))] 115 "" 116{ 117 if (<MODE>mode == V4QImode || <MODE>mode == V2HImode) 118 { 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])); 122 DONE; 123 } 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)) 128 { 129 rtx reg = operands[0]; 130 131 if (!REG_P (reg)) 132 reg = gen_reg_rtx (SImode); 133 emit_insn (gen_move_frame (reg, operands[1])); 134 operands[1] = reg; 135 if (operands[0] == reg) 136 DONE; 137 } 138}) 139 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"))] 143;; ??? Needed? 144 "gpr_operand (operands[0], QImode) 145 || gpr_operand (operands[1], QImode)" 146 "@ 147 mov %0,%1 148 mov %0,%1 149 mov %0,%1 150 ldrb %0,%1 151 strb %1,%0" 152 [(set_attr "type" "move,move,move,load,store")]) 153 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)" 159 "@ 160 mov %0,%1 161 mov %0,%%low(%1); %1 162 ldrh %0,%c1 163 strh %1,%c0" 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")]) 170 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 178;; register. 179;; 180;; N.B. operand 1 is an operand so that reload will perform elimination. 181;; 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" 188 "#") 189 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"))))] 194 "" 195 "movt %0, %%high(%1)" 196 [(set_attr "type" "move") 197 (set_attr "length" "4")]) 198 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")))] 203 "" 204 "mov %0, %%low(%1)" 205 [(set_attr "type" "move") 206 (set_attr "length" "4")]) 207 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])" 216{ 217 switch (which_alternative) 218 { 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 (); 231 } 232} 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")]) 244 245(define_split 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))]) 250 251(define_split 252 [(set (match_operand:SI 0 "gpr_operand") 253 (unspec:SI [(const_int 0)] UNSPEC_RETURN_ADDR))] 254 "reload_completed" 255 [(set (match_dup 0) (match_dup 1))] 256{ 257 emit_insn (gen_reload_insi_ra (operands[0], operands[1])); 258 DONE; 259}) 260 261(define_expand "reload_insi_ra" 262 [(set (match_operand:SI 0 "gpr_operand" "r") (match_operand:SI 1 "" "Sra"))] 263 "" 264{ 265 rtx addr 266 = (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx); 267 268 if (!MACHINE_FUNCTION (cfun)->lr_slot_known) 269 { 270 start_sequence (); 271 epiphany_expand_prologue (); 272 if (!MACHINE_FUNCTION (cfun)->lr_slot_known) 273 epiphany_expand_epilogue (0); 274 end_sequence (); 275 gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_known); 276 } 277 addr = plus_constant (Pmode, addr, MACHINE_FUNCTION (cfun)->lr_slot_offset); 278 operands[1] = gen_frame_mem (SImode, addr); 279}) 280 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)" 296 "#" 297 "reload_in_progress || reload_completed" 298 [(set (match_dup 0) (match_dup 1))]) 299 300(define_expand "mov<mode>" 301 [(set (match_operand:DWMODE 0 "general_operand" "") 302 (match_operand:DWMODE 1 "general_operand" ""))] 303 "" 304 " 305{ 306 if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_INT 307 || GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT) 308 { 309 if (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY) 310 { 311 rtx o0l, o0h, o1l, o1h; 312 313 o0l = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 0); 314 o0h = simplify_gen_subreg (SImode, operands[0], <MODE>mode, 315 UNITS_PER_WORD); 316 o1l = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0); 317 o1h = simplify_gen_subreg (SImode, operands[1], <MODE>mode, 318 UNITS_PER_WORD); 319 if (reg_overlap_mentioned_p (o0l, o1h)) 320 { 321 emit_move_insn (o0h, o1h); 322 emit_move_insn (o0l, o1l); 323 } 324 else 325 { 326 emit_move_insn (o0l, o1l); 327 emit_move_insn (o0h, o1h); 328 } 329 DONE; 330 } 331 /* lower_subreg has a tendency to muck up vectorized code. 332 To protect the wide memory accesses, we must use same-size 333 subregs. */ 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))) 342 { 343 operands[0] 344 = simplify_gen_subreg (DImode, operands[0], <MODE>mode, 0); 345 operands[1] 346 = simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0); 347 emit_insn (gen_movdi (operands[0], operands[1])); 348 DONE; 349 } 350 } 351 /* Everything except mem = const or mem = mem can be done easily. */ 352 353 if (GET_CODE (operands[0]) == MEM) 354 operands[1] = force_reg (<MODE>mode, operands[1]); 355}") 356 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))" 362 "@ 363 # 364 # 365 ldrd %0,%X1 366 strd %1,%X0" 367 "reload_completed 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))] 374{ 375 int word0 = 0, word1 = UNITS_PER_WORD; 376 377 if (post_modify_operand (operands[0], <MODE>mode) 378 || post_modify_operand (operands[1], <MODE>mode)) 379 word0 = UNITS_PER_WORD, word1 = 0; 380 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)) 386 operands[2] 387 = change_address (operands[2], VOIDmode, 388 plus_constant (Pmode, XEXP (XEXP (operands[0], 0), 0), 389 UNITS_PER_WORD)); 390 if (post_modify_operand (operands[1], <MODE>mode)) 391 operands[3] 392 = change_address (operands[3], VOIDmode, 393 plus_constant (Pmode, XEXP (XEXP (operands[1], 0), 0), 394 UNITS_PER_WORD)); 395} 396 [(set_attr "type" "move,move,load,store") 397 (set_attr "length" "8,16,4,4")]) 398 399 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)" 405 "@ 406 mov %0,%1 407 mov %0,%%low(%1)\;movt %0,%%high(%1) ; %1 408 ldr %0,%C1 409 str %1,%C0" 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")]) 416 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" "")))] 421 "" 422 " 423{ 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])); 428 else 429 emit_insn (gen_addsi3_i (operands[0], operands[1], operands[2])); 430 DONE; 431}") 432 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))] 442 "" 443 "@ 444 add %0,%1,%2 445 sub %0,%1,#%n2" 446[(set_attr "type" "misc")]) 447 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. 451; 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" 460{ 461 int scratch = (0x17 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); 470 return ""; 471} 472 [(set_attr "length" "20") 473 (set_attr "type" "misc")]) 474 475;; reload uses gen_addsi2 because it doesn't understand the need for 476;; the clobber. 477(define_peephole2 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))])] 492 ;; FIXME: 493 ;; need this patch: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html 494 ;; "peep2_rescan = true;" 495) 496 497(define_peephole2 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))]) 514 (match_dup 5)] 515 "") 516 517(define_peephole2 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))])] 529 "") 530 531(define_peephole2 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)))) 541 (reg:WMODE GPR_SP))] 542 "") 543 544 545 546(define_peephole2 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)) 557 (set (match_dup 2) 558 (mem:WMODE (post_modify (match_dup 0) 559 (plus:SI (match_dup 0) (match_dup 1)))))] 560 "") 561 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" "")))] 566 "" 567 " 568{ 569 gcc_assert (!reload_in_progress && !reload_completed); 570 571 if (TARGET_FP_IARITH) 572 emit_insn (gen_isub (operands[0], operands[1], operands[2])); 573 else 574 emit_insn (gen_subsi3_i (operands[0], operands[1], operands[2])); 575 DONE; 576}") 577 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))] 583 "" 584 "sub %0,%1,%2" 585 [(set_attr "type" "misc")]) 586 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 594; USE. 595 596;; Addition 597(define_expand "addsf3" 598 [(parallel 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))])]) 603 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))])] 610 "" 611 "fadd %0,%1,%2" 612 [(set_attr "type" "fp")]) 613 614;; Subtraction 615(define_expand "subsf3" 616 [(parallel 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))])]) 621 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))])] 628 "" 629 "fsub %0,%1,%2" 630 [(set_attr "type" "fp")]) 631 632(define_expand "subsf3_f" 633 [(parallel 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") 640 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)))])] 648 "!TARGET_SOFT_CMPSF" 649 "fsub %0,%1,%2" 650 [(set_attr "type" "fp")]) 651 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" "")))] 656 "" 657 " 658{ 659 rtx op1 = copy_to_mode_reg (SImode, simplify_gen_subreg (SImode, operands[1], 660 SFmode, 0)); 661 rtx op0 = simplify_gen_subreg (SImode, operands[0], SFmode, 0); 662 663 emit_insn (gen_ashlsi3 (op1, op1, const1_rtx)); 664 emit_insn (gen_lshrsi3 (op0, op1, const1_rtx)); 665 DONE; 666}") 667 668;; Multiplication 669(define_expand "mulsf3" 670 [(parallel 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))])]) 675 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))])] 682 "" 683 "fmul %0,%1,%2" 684 [(set_attr "type" "fp")]) 685 686;; Division 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" 692{ 693 rtx one = CONST1_RTX (SFmode); 694 rtx dst = operands[0]; 695 696 if (rtx_equal_p (dst, operands[1])) 697 { 698 emit_move_insn (dst, one); 699 DONE; 700 } 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)); 706 DONE; 707}) 708 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" 717 [(parallel 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" "")) 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 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")) 738 (clobber (reg:SF 0)) 739 (clobber (reg:SI 1)) 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" 748 "#" 749 "&& reload_completed" 750 [(set (reg:SI 1) (match_dup 3)) 751 (set (reg:SF 0) (match_dup 2)) 752 (parallel 753 [(set (reg:SF 0) 754 (div:SF (match_dup 1) 755 (reg:SF 0))) 756 (use (reg:SI 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)) 764 (match_dup 5) 765 (match_dup 6)]) 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")]) 771 772(define_insn "*recipsf2_2" 773 [(match_parallel 1 "float_operation" 774 [(set (reg:SF 0) 775 (div:SF (match_operand:SF 0 "const_float_1_operand" "") 776 (reg:SF 0))) 777 (use (reg:SI 1)) 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" 786 "jalr r1" 787 [(set_attr "type" "fp_sfunc")]) 788 789 790;; Fused multiply-add 791(define_expand "fmasf4" 792 [(parallel 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))])] 798 "") 799 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))])] 809 "" 810 "fmadd %0,%1,%2" 811 [(set_attr "type" "fp")]) 812 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. 818; 819; combiner pattern, also used by vector combiner pattern 820(define_expand "maddsf" 821 [(parallel 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))])] 827 "TARGET_FUSED_MADD") 828 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))])] 836 "TARGET_FUSED_MADD" 837 "fmadd %0,%1,%2" 838 [(set_attr "type" "fp")]) 839 840;; Fused multiply-sub 841(define_expand "fnmasf4" 842 [(parallel 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))])] 848 "") 849 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))])] 857 "" 858 "fmsub %0,%1,%2" 859 [(set_attr "type" "fp")]) 860 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))])] 868 "TARGET_FUSED_MADD" 869 "fmsub %0,%1,%2" 870 [(set_attr "type" "fp")]) 871 872;; float / integer conversions 873 874(define_expand "floatsisf2" 875 [(parallel 876 [(set (match_operand:SF 0 "gpr_operand" "") 877 (float:SF (match_operand:SI 1 "gpr_operand" ""))) 878 (clobber (reg:CC_FP CCFP_REGNUM))])]) 879 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))])] 885 "" 886 "float %0, %1" 887 [(set_attr "type" "fp")]) 888 889(define_expand "floatsisf2_cmp" 890 [(parallel 891 [(set (reg:CC_FP CCFP_REGNUM) 892 (compare:CC_FP (float:SF (match_operand:SF 1 "gpr_operand" "r")) 893 (match_dup 2))) 894 (set (match_operand:SF 0 "gpr_operand" "=r") 895 (float:SF (match_dup 1)))])] 896 "" 897 "operands[2] = CONST0_RTX (SFmode);") 898 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)))])] 906 "" 907 "float %0, %1" 908 [(set_attr "type" "fp")]) 909 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" 914{ 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); 918 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), 926 operands[0])); 927 DONE; 928}) 929 930(define_expand "fix_truncsfsi2" 931 [(parallel 932 [(set (match_operand:SI 0 "gpr_operand" "") 933 (fix:SI (match_operand:SF 1 "gpr_operand" ""))) 934 (clobber (reg:CC_FP CCFP_REGNUM))])]) 935 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))])] 941 "" 942 "fix %0, %1" 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")))]) 948 949(define_expand "fixuns_truncsfsi2" 950 [(set (match_operand:SI 0 "gpr_operand" "") 951 (unsigned_fix:SI (match_operand:SF 1 "gpr_operand" "")))] 952 "" 953{ 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)) 957 { 958 rtx op1si; 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)); 964 rtx cmp 965 = gen_rtx_GE (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx); 966 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])); 973 } 974 else 975 { 976 REAL_VALUE_TYPE offset; 977 rtx limit; 978 rtx tmp = gen_reg_rtx (SFmode); 979 rtx_code_label *label = gen_label_rtx (); 980 rtx bit31; 981 rtx cc1 = gen_rtx_REG (CC_FPmode, CCFP_REGNUM); 982 rtx cmp = gen_rtx_LT (VOIDmode, cc1, CONST0_RTX (SFmode)); 983 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)); 993 emit_label (label); 994 } 995 DONE; 996}) 997 998(define_expand "iadd" 999 [(parallel 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))])]) 1004 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))])] 1011 "" 1012 "iadd %0, %1, %2" 1013 [(set_attr "type" "fp_int")]) 1014 1015(define_expand "isub" 1016 [(parallel 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))])]) 1021 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))])] 1028 "" 1029 "isub %0, %1, %2" 1030 [(set_attr "type" "fp_int")]) 1031 1032; Try to figure out if we over-committed the FPU, and if so, move 1033; some insns back over to the integer pipe. 1034 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. 1047(define_peephole2 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))])] 1059) 1060 1061(define_peephole2 1062 [(match_parallel 3 "float_operation" 1063 [(set (match_operand:SI 0 "gpr_operand" "") 1064 (mult:SI 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), 1075 1))" 1076 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 4))) 1077 (clobber (reg:CC CC_REGNUM))])] 1078{ 1079 operands[4] 1080 = XEXP (XEXP (find_reg_note (curr_insn, REG_EQUAL, NULL_RTX), 0), 1); 1081}) 1082 1083(define_expand "mulsi3" 1084 [(parallel 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))])]) 1089 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))])] 1096 "" 1097 "imul %0, %1, %2" 1098 [(set_attr "type" "fp_int")]) 1099 1100; combiner pattern, also used by vector combiner pattern 1101(define_expand "maddsi" 1102 [(parallel 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))])] 1108 "") 1109 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))])] 1117 "" 1118 "imadd %0, %1, %2" 1119 [(set_attr "type" "fp_int")]) 1120 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))])] 1128 "" 1129 "imsub %0, %1, %2" 1130 [(set_attr "type" "fp_int")]) 1131 1132(define_expand "divsi3" 1133 [(parallel 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" ""))) 1137 (use (match_dup 3)) 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))])] 1147 "" 1148 "operands[3] = sfunc_symbol (\"__divsi3\");") 1149 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))])] 1167 "" 1168 "#" 1169 "&& reload_completed" 1170 [(set (reg:SI 0) (match_dup 1)) 1171 (set (reg:SI 1) (match_dup 2)) 1172 (parallel 1173 [(set (reg:SI 0) (div:SI (reg:SI 0) (reg:SI 1))) 1174 (use (match_dup 3)) 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)) 1183 (match_dup 5) 1184 (match_dup 6)]) 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")]) 1190 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))])] 1203 "" 1204 "%f0" 1205 [(set_attr "type" "fp_sfunc")]) 1206 1207(define_expand "udivsi3" 1208 [(parallel 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" ""))) 1212 (use (match_dup 3)) 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))])] 1221 "" 1222 "operands[3] = sfunc_symbol (\"__udivsi3\");") 1223 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))])] 1240 "" 1241 "#" 1242 "&& reload_completed" 1243 [(set (reg:SI 0) (match_dup 1)) 1244 (set (reg:SI 1) (match_dup 2)) 1245 (parallel 1246 [(set (reg:SI 0) (udiv:SI (reg:SI 0) (reg:SI 1))) 1247 (use (match_dup 3)) 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)) 1255 (match_dup 5) 1256 (match_dup 6)]) 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")]) 1262 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))])] 1274 "" 1275 "%f0" 1276 [(set_attr "type" "fp_sfunc")]) 1277 1278(define_expand "modsi3" 1279 [(parallel 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" ""))) 1283 (use (match_dup 3)) 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))])] 1293 "" 1294 "operands[3] = sfunc_symbol (\"__modsi3\");") 1295 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))])] 1313 "" 1314 "#" 1315 "&& reload_completed" 1316 [(set (reg:SI 0) (match_dup 1)) 1317 (set (reg:SI 1) (match_dup 2)) 1318 (parallel 1319 [(set (reg:SI 0) (mod:SI (reg:SI 0) (reg:SI 1))) 1320 (use (match_dup 3)) 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)) 1328 (match_dup 5) 1329 (match_dup 6)]) 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")]) 1335 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))])] 1347 "" 1348 "%f0" 1349 [(set_attr "type" "fp_sfunc")]) 1350 1351(define_expand "umodsi3" 1352 [(parallel 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" ""))) 1356 (use (match_dup 3)) 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))])] 1365 "" 1366 "operands[3] = sfunc_symbol (\"__umodsi3\");") 1367 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))])] 1384 "" 1385 "#" 1386 "&& reload_completed" 1387 [(set (reg:SI 0) (match_dup 1)) 1388 (set (reg:SI 1) (match_dup 2)) 1389 (parallel 1390 [(set (reg:SI 0) (umod:SI (reg:SI 0) (reg:SI 1))) 1391 (use (match_dup 3)) 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)) 1398 (match_dup 5) 1399 (match_dup 6)]) 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")]) 1405 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))])] 1416 "" 1417 "%f0" 1418 [(set_attr "type" "fp_sfunc")]) 1419 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. 1423(define_insn "gid" 1424 [(set (reg:SI CONFIG_REGNUM) 1425 (unspec_volatile:SI [(const_int 0)] UNSPECV_GID))] 1426 "" 1427 "gid" 1428 [(set_attr "type" "flow")]) 1429 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. 1434(define_insn "gie" 1435 [(unspec_volatile [(reg:SI CONFIG_REGNUM)] UNSPECV_GIE)] 1436 "" 1437 "gie" 1438 [(set_attr "type" "flow")]) 1439 1440; Floating point instructions require manipulating the control register. 1441; Manipulating the control register needs arithmetic. 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 1446; lead to disaster. 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" "")) 1456 (use (match_dup 2)) 1457 (clobber (match_scratch:SI 3 "=X, &r"))])] 1458 "" 1459 "operands[2] = gen_int_mode (~0x10f0, SImode);") 1460 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"))] 1466 "" 1467 "@ 1468 movfs %0,status 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")]) 1472 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))] 1478 "" 1479 "#" 1480 "reload_completed" 1481 [(set (match_dup 0) (reg:SI CONFIG_REGNUM))]) 1482 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"))] 1492 "" 1493 "#" 1494 "reload_completed || !rtx_equal_p (operands[0], operands[1])" 1495 [(const_int 0)] 1496{ 1497 if (!reload_completed) 1498 emit_note (NOTE_INSN_DELETED); 1499 else 1500 epiphany_expand_set_fp_mode (operands); 1501 DONE; 1502}) 1503 1504 1505;; Boolean instructions. 1506;; 1507;; We don't define the DImode versions as expand_binop does a good enough job. 1508 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))] 1514 "" 1515 "and %0,%1,%2") 1516 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))] 1522 "" 1523 "orr %0,%1,%2") 1524 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))] 1530 "" 1531 "eor %0,%1,%2") 1532 1533(define_expand "one_cmplsi2" 1534 [(set (match_operand:SI 0 "gpr_operand" "") 1535 (xor:SI (match_operand:SI 1 "gpr_operand" "") 1536 (match_dup 2)))] 1537 "" 1538{ 1539 if (epiphany_m1reg >= 0) 1540 emit_insn (gen_one_cmplsi2_i (operands[0], operands[1])); 1541 else 1542 emit_insn (gen_xorsi3 (operands[0], operands[1], 1543 force_reg (SImode, GEN_INT (-1)))); 1544 DONE; 1545}) 1546 1547; Note that folding this pattern into the xorsi3 pattern would make combine 1548; less effective. 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" 1554 "eor %0,%1,%-") 1555 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))] 1565 "" 1566 "asr %0,%1,%2" 1567 [(set_attr "length" "4") 1568 (set_attr "type" "shift")]) 1569 1570(define_insn "ashrsi3_tst" 1571 [(set (reg:CC CC_REGNUM) 1572 (compare:CC 1573 (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r") 1574 (match_operand:SI 2 "arith_operand" "r,K")) 1575 (const_int 0))) 1576 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1577 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 1578 "" 1579 "asr %0,%1,%2" 1580 [(set_attr "length" "4") 1581 (set_attr "type" "shift")]) 1582 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))] 1589 "" 1590 "lsr %0,%1,%2" 1591 [(set_attr "length" "4") 1592 (set_attr "type" "shift")]) 1593 1594(define_insn "lshrsi3_tst" 1595 [(set (reg:CC CC_REGNUM) 1596 (compare:CC 1597 (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "r,r") 1598 (match_operand:SI 2 "arith_operand" "r,K")) 1599 (const_int 0))) 1600 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1601 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 1602 "" 1603 "lsr %0,%1,%2" 1604 [(set_attr "length" "4") 1605 (set_attr "type" "shift")]) 1606 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))] 1613 "" 1614 "lsl %0,%1,%2" 1615 [(set_attr "length" "4") 1616 (set_attr "type" "shift")]) 1617 1618(define_insn "*ashlsi_btst" 1619 [(set (reg:CC_N_NE CC_REGNUM) 1620 (compare:CC_N_NE 1621 (zero_extract:SI (match_operand:SI 1 "gpr_operand" "r") 1622 (const_int 1) 1623 (match_operand 2 "const_int_operand" "K")) 1624 (const_int 0))) 1625 (clobber (match_scratch:SI 0 "=r"))] 1626 "" 1627{ 1628 rtx xop[3]; 1629 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); 1634 return ""; 1635}) 1636 1637;; zero extensions 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))] 1642 "" 1643 "@ 1644 # 1645 ldrb %0,%1" 1646 "reload_completed 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);") 1654 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")))] 1658 "" 1659 "@ 1660 movt %0, 0 1661 ldrh %0,%c1") 1662 1663 1664;; Compare instructions. 1665 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"))] 1671 "" 1672 "sub %2,%0,%1" 1673 [(set_attr "type" "compare")]) 1674 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)))] 1681 "" 1682 "sub %0,%1,%2" 1683 [(set_attr "type" "compare")]) 1684 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" "CnL")))] 1691 "INTVAL (operands[2]) == -INTVAL (operands[3])" 1692 "sub %0,%1,%2" 1693 [(set_attr "type" "compare")]) 1694 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" ""))) 1700 (set (match_dup 3) 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)) 1704 (match_dup 3) 1705 (match_dup 1)))] 1706 "TARGET_CMOVE" 1707 "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);") 1708 1709(define_insn "*add_c" 1710 [(set (reg:CC_C_LTU CC_REGNUM) 1711 (compare:CC_C_LTU 1712 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r") 1713 (match_operand:SI 2 "arith_operand" "r,L")) 1714 (match_dup 1))) 1715 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1716 (plus:SI (match_dup 1) (match_dup 2)))] 1717 "" 1718 "add %0,%1,%2" 1719 [(set_attr "type" "compare")]) 1720 1721(define_insn "*add_c_rev" 1722 [(set (reg:CC_C_LTU CC_REGNUM) 1723 (compare:CC_C_LTU 1724 (plus:SI (match_operand:SI 1 "gpr_operand" "%r,r") 1725 (match_operand:SI 2 "arith_operand" "r,L")) 1726 (match_dup 1))) 1727 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1728 (plus:SI (match_dup 2) (match_dup 1)))] 1729 "" 1730 "add %0,%1,%2" 1731 [(set_attr "type" "compare")]) 1732 1733(define_insn "*sub_c" 1734 [(set (reg:CC_C_GTU CC_REGNUM) 1735 (compare:CC_C_GTU 1736 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r") 1737 (match_operand:SI 2 "arith_operand" "r,L")) 1738 (match_dup 1))) 1739 (set (match_operand:SI 0 "gpr_operand" "=r,r") 1740 (minus:SI (match_dup 1) (match_dup 2)))] 1741 "" 1742 "sub %0,%1,%2" 1743 [(set_attr "type" "compare")]) 1744 1745(define_insn "*sub_c_void" 1746 [(set (reg:CC_C_GTU CC_REGNUM) 1747 (compare:CC_C_GTU 1748 (minus:SI (match_operand:SI 1 "gpr_operand" "r,r") 1749 (match_operand:SI 2 "arith_operand" "r,L")) 1750 (match_dup 1))) 1751 (clobber (match_scratch:SI 0 "=r,r"))] 1752 "" 1753 "sub %0,%1,%2" 1754 [(set_attr "type" "compare")]) 1755 1756(define_code_iterator logical_op 1757 [and ior xor]) 1758 1759(define_code_attr op_mnc 1760 [(plus "add") (minus "sub") (and "and") (ior "orr") (xor "eor")]) 1761 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")) 1766 (const_int 0))) 1767 (set (match_operand:SI 0 "gpr_operand" "=r") 1768 (logical_op:SI (match_dup 1) (match_dup 2)))] 1769 "" 1770 "<op_mnc> %0,%1,%2" 1771 [(set_attr "type" "compare")]) 1772 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))] 1777 "" 1778 "#" 1779 "reload_completed" 1780 [(parallel 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)))])] 1785 "" 1786 [(set_attr "type" "compare")]) 1787 1788(define_peephole2 1789 [(parallel 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))]) 1794 (parallel 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])" 1800 [(parallel 1801 [(set (reg:CC CC_REGNUM) 1802 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2)) 1803 (const_int 0))) 1804 (set (match_dup 3) (logical_op:SI (match_dup 1) (match_dup 2)))])]) 1805 1806(define_peephole2 1807 [(parallel 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))]) 1812 (parallel 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])" 1818 [(parallel 1819 [(set (reg:CC CC_REGNUM) 1820 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2)) 1821 (const_int 0))) 1822 (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])]) 1823 1824(define_peephole2 1825 [(parallel 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))]) 1830 (parallel 1831 [(set (reg:CC CC_REGNUM) 1832 (compare:CC (match_dup 0) (const_int 0))) 1833 (clobber (match_operand:SI 3 "gpr_operand"))])] 1834 "" 1835 [(parallel 1836 [(set (reg:CC CC_REGNUM) 1837 (compare:CC (logical_op:SI (match_dup 1) (match_dup 2)) 1838 (const_int 0))) 1839 (set (match_dup 0) (logical_op:SI (match_dup 1) (match_dup 2)))])]) 1840 1841(define_expand "cstoresi4" 1842 [(parallel 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)))] 1849 "" 1850{ 1851 enum rtx_code o2_code = GET_CODE (operands[2]); 1852 enum rtx_code cmp_code = GET_CODE (operands[1]); 1853 1854 if ((o2_code == AND || o2_code == IOR || o2_code == XOR) 1855 && operands[3] == const0_rtx) 1856 { 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)); 1860 } 1861 else 1862 operands[2] = force_reg (SImode, operands[2]); 1863 operands[1] = gen_rtx_COMPARE (CCmode, operands[2], operands[3]); 1864 if (cmp_code != NE) 1865 { 1866 operands[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)); 1867 operands[3] = const0_rtx; 1868 } 1869 else 1870 { 1871 if (operands[3] != const0_rtx) 1872 operands[2] = gen_rtx_MINUS (SImode, operands[2], operands[3]); 1873 operands[2] = gen_rtx_SET (operands[0], operands[2]); 1874 operands[3] = operands[0]; 1875 } 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)); 1879}) 1880 1881 1882; floating point comparisons 1883 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" 1891 "fsub %2,%0,%1" 1892 [(set_attr "type" "fp") 1893 (set_attr "fp_mode" "round_unknown")]) 1894 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 1899;; a proper job. 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))] 1905 "TARGET_SOFT_CMPSF" 1906 "%f0" 1907 [(set_attr "type" "sfunc")]) 1908 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))] 1914 "TARGET_SOFT_CMPSF" 1915 "%f0" 1916 [(set_attr "type" "sfunc")]) 1917 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))] 1924 "" 1925 "%f0" 1926 [(set_attr "type" "sfunc")]) 1927 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))] 1934 "TARGET_SOFT_CMPSF" 1935 "%f0" 1936 [(set_attr "type" "sfunc")]) 1937 1938;; conditional moves 1939 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" "")))] 1945 "TARGET_CMOVE" 1946{ 1947 rtx cmp_op0 = XEXP (operands[1], 0); 1948 rtx cmp_op1 = XEXP (operands[1], 1); 1949 machine_mode cmp_in_mode; 1950 enum rtx_code code = GET_CODE (operands[1]); 1951 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])) 1961 { 1962 rtx tmp = operands[2]; operands[2] = operands[3]; operands[3] = tmp; 1963 code = (FLOAT_MODE_P (GET_MODE (cmp_op0)) && !flag_finite_math_only 1964 ? reverse_condition_maybe_unordered (code) 1965 : reverse_condition (code)); 1966 } 1967 1968 if (proper_comparison_operator (operands[1], VOIDmode)) 1969 operands[1] = gen_rtx_fmt_ee (code, cmp_in_mode, cmp_op0, cmp_op1); 1970 else 1971 { 1972 if (!currently_expanding_to_rtl) 1973 { 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. */ 1979 } 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. */ 1986 operands[1] 1987 = gen_compare_reg (<MODE>mode, code, cmp_in_mode, cmp_op0, cmp_op1); 1988 if (!operands[1]) 1989 FAIL; 1990 } 1991}) 1992 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")))] 1999 "TARGET_CMOVE" 2000 "mov%d3 %0,%1" 2001 [(set_attr "type" "cmove")]) 2002 2003(define_peephole2 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" "")) 2010 (set (match_dup 3) 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" "") 2015 (match_dup 3)))] 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))]) 2023 (match_dup 2) 2024 (set (match_dup 3) 2025 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))] 2026{ 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], true); 2030 replace_rtx (operands[2], operands[0], operands[10], true); 2031 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2])); 2032}) 2033 2034(define_peephole2 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")) 2040 (set (match_dup 3) 2041 (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator" 2042 [(match_dup 6) 2043 (match_operand:WMODE 7 "const0_operand")]) 2044 (match_operand:WMODE2 8 "gpr_operand") 2045 (match_dup 3)))] 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))]) 2053 (set (match_dup 3) 2054 (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))] 2055 " 2056{ 2057 operands[5] 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); 2063}") 2064 2065;; These control RTL generation for conditional jump insns 2066 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" ""))) 2073 (set (pc) 2074 (if_then_else 2075 (match_operator 0 "ordered_comparison_operator" [(reg CC_REGNUM) 2076 (const_int 0)]) 2077 (label_ref (match_operand 3 "" "")) 2078 (pc)))] 2079 "" 2080{ 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))); 2084 DONE; 2085}) 2086 2087(define_expand "cbranchsf4" 2088 [(set (reg CC_REGNUM) 2089 (compare (match_operand:SF 1 "arith_operand" "") 2090 (match_operand:SF 2 "arith_operand" ""))) 2091 (set (pc) 2092 (if_then_else 2093 (match_operator 0 "comparison_operator" [(reg CC_REGNUM) 2094 (const_int 0)]) 2095 (label_ref (match_operand 3 "" "")) 2096 (pc)))] 2097 "" 2098{ 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))); 2102 DONE; 2103}) 2104 2105;; Now match both normal and inverted jump. 2106 2107(define_insn "branch_insn" 2108 [(set (pc) 2109 (if_then_else (match_operator 1 "proper_comparison_operator" 2110 [(match_operand 2 "cc_operand") 2111 (const_int 0)]) 2112 (label_ref (match_operand 0 "" "")) 2113 (pc)))] 2114 "" 2115 "b%d1 %l0" 2116 [(set_attr "type" "branch")]) 2117 2118(define_insn "*rev_branch_insn" 2119 [(set (pc) 2120 (if_then_else (match_operator 1 "proper_comparison_operator" 2121 [(reg CC_REGNUM) (const_int 0)]) 2122 (pc) 2123 (label_ref (match_operand 0 "" ""))))] 2124 "" 2125 "b%D1 %l0" 2126 [(set_attr "type" "branch")]) 2127 2128;; Unconditional and other jump instructions. 2129 2130(define_insn "jump" 2131 [(set (pc) (label_ref (match_operand 0 "" "")))] 2132 "" 2133 "b %l0" 2134 [(set_attr "type" "uncond_branch")]) 2135 2136(define_insn "indirect_jump" 2137 [(set (pc) (match_operand:SI 0 "gpr_operand" "r"))] 2138 "" 2139 "jr %0" 2140 [(set_attr "type" "uncond_branch")]) 2141 2142(define_expand "tablejump" 2143 [(parallel [(set (pc) (match_operand:SI 0 "gpr_operand" "")) 2144 (use (label_ref (match_operand 1 "" "")))])] 2145 "" 2146{ 2147 /* In PIC mode, the table entries are stored PC relative. 2148 Convert the relative address to an absolute address. */ 2149 if (flag_pic) 2150 { 2151 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 2152 2153 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], 2154 op1, NULL_RTX, 0, OPTAB_DIRECT); 2155 } 2156}) 2157 2158(define_insn "*tablejump_internal" 2159 [(set (pc) (match_operand:SI 0 "gpr_operand" "r")) 2160 (use (label_ref (match_operand 1 "" "")))] 2161 "" 2162 "jr %0;" 2163 [(set_attr "type" "uncond_branch")]) 2164 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" 2169 "jr %0;" 2170 [(set_attr "type" "uncond_branch")]) 2171 2172 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))])] 2179 "" 2180{ 2181 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]); 2182 2183 if (!call_operand (operands[1], VOIDmode)) 2184 operands[0] 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) 2189 { 2190 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2191 emit_call_insn 2192 (gen_rtx_PARALLEL 2193 (VOIDmode, 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 ()); 2198 DONE; 2199 } 2200}) 2201 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))])] 2207 "" 2208 "%f0" 2209 [(set_attr "type" "call")]) 2210 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 "" "")) 2216 (return)])] 2217 "" 2218{ 2219 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[0]); 2220 2221 if (!call_operand (operands[1], VOIDmode)) 2222 operands[0] 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) 2227 { 2228 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2229 emit_call_insn 2230 (gen_rtx_PARALLEL 2231 (VOIDmode, 2232 gen_rtvec (2, gen_rtx_CALL (VOIDmode, operands[0], operands[1]), 2233 ret_rtx))); 2234 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ()); 2235 DONE; 2236 } 2237}) 2238 2239(define_insn "*sibcall_i" 2240 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Csy,Rsc")) 2241 (match_operand 1 "" "")) 2242 (return)] 2243 "" 2244 "@ 2245 b %0 2246 jr %0" 2247 [(set_attr "type" "call")]) 2248 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))])] 2256 "" 2257{ 2258 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]); 2259 2260 if (!call_operand (operands[1], VOIDmode)) 2261 operands[1] 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) 2266 { 2267 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2268 emit_call_insn 2269 (gen_rtx_PARALLEL 2270 (VOIDmode, 2271 gen_rtvec (2, gen_rtx_SET 2272 (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 ()); 2277 DONE; 2278 } 2279}) 2280 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))])] 2287 "" 2288 "%f1" 2289 [(set_attr "type" "call") 2290 (set_attr "length" "4")]) 2291 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 "" ""))) 2298 (return)])] 2299 "" 2300{ 2301 bool target_uninterruptible = epiphany_call_uninterruptible_p (operands[1]); 2302 2303 if (!call_operand (operands[1], VOIDmode)) 2304 operands[1] 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) 2309 { 2310 emit_insn (target_uninterruptible ? gen_gid (): gen_gie ()); 2311 emit_call_insn 2312 (gen_rtx_PARALLEL 2313 (VOIDmode, 2314 gen_rtvec (2, gen_rtx_SET 2315 (operands[0], 2316 gen_rtx_CALL (VOIDmode, operands[1], operands[2])), 2317 ret_rtx))); 2318 emit_insn (target_uninterruptible ? gen_gie (): gen_gid ()); 2319 DONE; 2320 } 2321}) 2322 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 "" ""))) 2327 (return)] 2328 "" 2329 "@ 2330 b %1 2331 jr %1" 2332 [(set_attr "type" "call") 2333 (set_attr "length" "4")]) 2334 2335(define_expand "prologue" 2336 [(pc)] 2337 "" 2338{ 2339 epiphany_expand_prologue (); 2340 DONE; 2341}) 2342 2343(define_expand "epilogue" 2344 [(pc)] 2345 "" 2346{ 2347 epiphany_expand_epilogue (0); 2348 DONE; 2349}) 2350 2351(define_expand "sibcall_epilogue" 2352 [(pc)] 2353 "" 2354{ 2355 epiphany_expand_epilogue (1); 2356 DONE; 2357}) 2358 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" 2366 [(return)] 2367 "reload_completed" 2368 "rts" 2369 [(set_attr "type" "uncond_branch")]) 2370 2371(define_insn "return_internal_interrupt" 2372 [(return) 2373 (unspec_volatile [(const_int 0)] 1)] 2374 "" 2375 "rti" 2376 [(set_attr "type" "uncond_branch")]) 2377 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 "memclob_operand" "=X"))] 2384 "reload_completed" 2385 "add sp,sp,%0") 2386 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"))] 2390 "reload_completed" 2391 "mov sp,fp" 2392 [(set_attr "type" "move")]) 2393 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 "memclob_operand" "=X"))] 2400 "reload_completed" 2401{ 2402 return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 2403 ? \"str %1,%0,%C2\" : \"strd %1,%0,%X2\"); 2404} 2405 [(set_attr "type" "store")]) 2406 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"))] 2413 "reload_completed" 2414 "ldr %0,%1,%C2" 2415 [(set_attr "type" "load")]) 2416 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")] 2422 "" 2423{ 2424 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, 0); 2425 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0); 2426 rtx outh 2427 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD); 2428 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))); 2434 DONE; 2435}) 2436 2437(define_expand "vec_unpacks_hi_v4hi" 2438 [(match_operand:V2SI 0 "gpr_operand") 2439 (match_operand:V4HI 1 "gpr_operand")] 2440 "" 2441{ 2442 rtx in = simplify_gen_subreg (SImode, operands[1], V4HImode, UNITS_PER_WORD); 2443 rtx outl = simplify_gen_subreg (SImode, operands[0], V2SImode, 0); 2444 rtx outh 2445 = simplify_gen_subreg (SImode, operands[0], V2SImode, UNITS_PER_WORD); 2446 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))); 2452 DONE; 2453}) 2454 2455(define_code_iterator addsub [plus minus]) 2456 2457(define_code_iterator alu_binop 2458 [plus minus and ior xor]) 2459 2460(define_code_attr insn_opname 2461 [(plus "add") (minus "sub") (mult "mul") (div "div") 2462 (and "and") (ior "ior") (xor "xor")]) 2463 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 "")]) 2468 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))] 2478 "" 2479 "#" 2480 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2481 [(const_int 0)] 2482{ 2483 rtx o0l, o0h, o1l, o1h, o2l, o2h; 2484 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)); 2497 DONE; 2498} 2499 [(set_attr "length" "8")]) 2500 2501(define_expand "<insn_opname>v2sf3" 2502 [(parallel 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))])]) 2507 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))])] 2514 "" 2515 "#" 2516 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2517 [(parallel 2518 [(set (match_dup 4) (addsub:SF (match_dup 5) (match_dup 6))) 2519 (clobber (reg:CC_FP CCFP_REGNUM)) 2520 (match_dup 10) 2521 (match_dup 11)]) 2522 (parallel 2523 [(set (match_dup 7) (addsub:SF (match_dup 8) (match_dup 9))) 2524 (clobber (reg:CC_FP CCFP_REGNUM)) 2525 (match_dup 10) 2526 (match_dup 11)])] 2527{ 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); 2531 operands[7] 2532 = simplify_gen_subreg (SFmode, operands[0], V2SFmode, UNITS_PER_WORD); 2533 operands[8] 2534 = simplify_gen_subreg (SFmode, operands[1], V2SFmode, UNITS_PER_WORD); 2535 operands[9] 2536 = simplify_gen_subreg (SFmode, operands[2], V2SFmode, UNITS_PER_WORD); 2537 if (!reload_completed) 2538 { 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])); 2545 DONE; 2546 } 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); 2551} 2552 [(set_attr "length" "8") 2553 (set_attr "type" "v2fp")]) 2554 2555(define_expand "ashlv2si3" 2556 [(parallel 2557 [(set (match_operand:V2SI 0 "gpr_operand" "") 2558 (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "") 2559 (match_operand:SI 2 "general_operand"))) 2560 (use (match_dup 3)) 2561 (clobber (reg:CC_FP CCFP_REGNUM))])] 2562 "" 2563{ 2564 if (const_int_operand (operands[2], VOIDmode)) 2565 operands[3] 2566 = copy_to_mode_reg (SImode, GEN_INT (1 << INTVAL (operands[2]))); 2567 else 2568 { 2569 int o, i; 2570 rtx xop[2], last_out = pc_rtx; 2571 2572 for (o = 0; o <= UNITS_PER_WORD; o += UNITS_PER_WORD) 2573 { 2574 for (i = 0; i < 2; i++) 2575 { 2576 xop[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)))); 2587 } 2588 emit_insn (gen_ashlsi3 (xop[0], xop[1], operands[2])); 2589 last_out = xop[0]; 2590 } 2591 DONE; 2592 } 2593}) 2594 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))])] 2602 "" 2603 "#" 2604 "reload_completed" 2605 [(parallel 2606 [(set (match_dup 5) (mult:SI (match_dup 6) (match_dup 4))) 2607 (clobber (reg:CC_FP CCFP_REGNUM)) 2608 (match_dup 9) 2609 (match_dup 10)]) 2610 (parallel 2611 [(set (match_dup 7) (mult:SI (match_dup 8) (match_dup 4))) 2612 (clobber (reg:CC_FP CCFP_REGNUM)) 2613 (match_dup 9) 2614 (match_dup 10)])] 2615{ 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); 2626 rtx insn 2627 = (gen_rtx_PARALLEL 2628 (VOIDmode, 2629 gen_rtvec 2630 (4, 2631 gen_rtx_SET (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])); 2638 insn 2639 = (gen_rtx_PARALLEL 2640 (VOIDmode, 2641 gen_rtvec 2642 (4, 2643 gen_rtx_SET (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])); 2650 DONE; 2651} 2652 [(set_attr "length" "8") 2653 (set_attr "type" "fp_int")]) 2654 2655(define_expand "mul<mode>3" 2656 [(parallel 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))])]) 2661 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))])] 2668 "" 2669 "#" 2670 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2671 [(parallel 2672 [(set (match_dup 4) (mult:<vmode_PART> (match_dup 5) (match_dup 6))) 2673 (clobber (reg:CC_FP CCFP_REGNUM)) 2674 (match_dup 10) 2675 (match_dup 11)]) 2676 (parallel 2677 [(set (match_dup 7) (mult:<vmode_PART> (match_dup 8) (match_dup 9))) 2678 (clobber (reg:CC_FP CCFP_REGNUM)) 2679 (match_dup 10) 2680 (match_dup 11)])] 2681{ 2682 operands[4] 2683 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0); 2684 operands[5] 2685 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0); 2686 operands[6] 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) 2695 { 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])); 2702 DONE; 2703 } 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); 2708} 2709 [(set_attr "length" "8") 2710 (set_attr "type" "<vmode_fp_type>")]) 2711 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" 2721 "#" 2722 "reload_completed || (epiphany_vect_align == 4 && TARGET_SPLIT_VECMOVE_EARLY)" 2723 [(parallel 2724 [(set (match_dup 5) 2725 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 6) (match_dup 7)) 2726 (match_dup 8))) 2727 (clobber (reg:CC_FP CCFP_REGNUM)) 2728 (match_dup 13) 2729 (match_dup 14)]) 2730 (parallel 2731 [(set (match_dup 9) 2732 (plus:<vmode_PART> (mult:<vmode_PART> (match_dup 10) (match_dup 11)) 2733 (match_dup 12))) 2734 (clobber (reg:CC_FP CCFP_REGNUM)) 2735 (match_dup 13) 2736 (match_dup 14)])] 2737{ 2738 operands[5] 2739 = simplify_gen_subreg (<vmode_PART>mode, operands[0], <MODE>mode, 0); 2740 operands[6] 2741 = simplify_gen_subreg (<vmode_PART>mode, operands[1], <MODE>mode, 0); 2742 operands[7] 2743 = simplify_gen_subreg (<vmode_PART>mode, operands[2], <MODE>mode, 0); 2744 operands[8] 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) 2755 { 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], 2763 operands[8])); 2764 emit_insn (gen_madd<vmode_part> (operands[9], operands[10], operands[11], 2765 operands[12])); 2766 DONE; 2767 } 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); 2773} 2774 [(set_attr "length" "8") 2775 (set_attr "type" "<vmode_fp_type>")]) 2776 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" "")] 2781 "" 2782{ 2783 operands[0] 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]); 2787 DONE; 2788}) 2789 2790(define_expand "movmisalign<mode>" 2791 [(set (match_operand:DWV2MODE 0 "nonimmediate_operand" "") 2792 (match_operand:DWV2MODE 1 "general_operand" ""))] 2793 "" 2794{ 2795 rtx op00, op01, op10, op11; 2796 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, 2799 UNITS_PER_WORD); 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, 2802 UNITS_PER_WORD); 2803 emit_move_insn (op00, op10); 2804 emit_move_insn (op01, op11); 2805 DONE; 2806}) 2807 2808(define_insn "nop" 2809 [(const_int 0)] 2810 "" 2811 "nop" 2812 [(set_attr "type" "flow")]) 2813