1;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler 2;; Copyright (C) 1994-2019 Free Software Foundation, Inc. 3 4;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on 5;; behalf of Synopsys Inc. 6 7;; Position Independent Code support added,Code cleaned up, 8;; Comments and Support For ARC700 instructions added by 9;; Saurabh Verma (saurabh.verma@codito.com) 10;; Ramana Radhakrishnan(ramana.radhakrishnan@codito.com) 11;; 12;; Performance improvements by 13;; Joern Rennecke (joern.rennecke@embecosm.com) 14;; 15 16;; This file is part of GCC. 17 18;; GCC is free software; you can redistribute it and/or modify 19;; it under the terms of the GNU General Public License as published by 20;; the Free Software Foundation; either version 3, or (at your option) 21;; any later version. 22 23;; GCC is distributed in the hope that it will be useful, 24;; but WITHOUT ANY WARRANTY; without even the implied warranty of 25;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26;; GNU General Public License for more details. 27 28;; You should have received a copy of the GNU General Public License 29;; along with GCC; see the file COPYING3. If not see 30;; <http://www.gnu.org/licenses/>. 31 32;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 33 34;; <op> dest, src Two operand instruction's syntax 35;; <op> dest, src1, src2 Three operand instruction's syntax 36 37;; ARC and ARCompact PREDICATES: 38;; 39;; comparison_operator LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE 40;; memory_operand memory [m] 41;; immediate_operand immediate constant [IKLMNOP] 42;; register_operand register [rq] 43;; general_operand register, memory, constant [rqmIKLMNOP] 44 45;; Note that the predicates are only used when selecting a pattern 46;; to determine if an operand is valid. 47 48;; The constraints then select which of the possible valid operands 49;; is present (and guide register selection). The actual assembly 50;; instruction is then selected on the basis of the constraints. 51 52;; ARC and ARCompact CONSTRAINTS: 53;; 54;; b stack pointer r28 55;; f frame pointer r27 56;; Rgp global pointer r26 57;; g general reg, memory, constant 58;; m memory 59;; p memory address 60;; q registers commonly used in 61;; 16-bit insns r0-r3, r12-r15 62;; c core registers r0-r60, ap, pcl 63;; r general registers r0-r28, blink, ap, pcl 64;; 65;; H fp 16-bit constant 66;; I signed 12-bit immediate (for ARCompact) 67;; K unsigned 3-bit immediate (for ARCompact) 68;; L unsigned 6-bit immediate (for ARCompact) 69;; M unsinged 5-bit immediate (for ARCompact) 70;; O unsinged 7-bit immediate (for ARCompact) 71;; P unsinged 8-bit immediate (for ARCompact) 72;; N constant '1' (for ARCompact) 73 74 75;; TODO: 76;; -> prefetch instruction 77 78;; ----------------------------------------------------------------------------- 79 80;; Include DFA scheduluers 81(include ("arc600.md")) 82(include ("arc700.md")) 83(include ("arcEM.md")) 84(include ("arcHS.md")) 85(include ("arcHS4x.md")) 86 87;; Predicates 88 89(include ("predicates.md")) 90(include ("constraints.md")) 91;; ----------------------------------------------------------------------------- 92 93;; UNSPEC Usage: 94;; ~~~~~~~~~~~~ 95;; ----------------------------------------------------------------------------- 96;; Symbolic name Value Desc. 97;; ----------------------------------------------------------------------------- 98;; UNSPEC_PLT 3 symbol to be referenced through the PLT 99;; UNSPEC_GOT 4 symbol to be rerenced through the GOT 100;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the 101;; GOTBASE.(Referenced as @GOTOFF) 102;; UNSPEC_GOTOFFPC 6 Local symbol. To be referenced pc-relative. 103;; ---------------------------------------------------------------------------- 104 105(define_c_enum "unspec" [ 106 DUMMY_0 107 DUMMY_1 108 DUMMY_2 109 ARC_UNSPEC_PLT 110 ARC_UNSPEC_GOT 111 ARC_UNSPEC_GOTOFF 112 ARC_UNSPEC_GOTOFFPC 113 UNSPEC_TLS_GD 114 UNSPEC_TLS_LD 115 UNSPEC_TLS_IE 116 UNSPEC_TLS_OFF 117 UNSPEC_ARC_NORM 118 UNSPEC_ARC_NORMW 119 UNSPEC_ARC_SWAP 120 UNSPEC_ARC_DIVAW 121 UNSPEC_ARC_DIRECT 122 UNSPEC_ARC_LP 123 UNSPEC_ARC_CASESI 124 UNSPEC_ARC_FFS 125 UNSPEC_ARC_FLS 126 UNSPEC_ARC_MEMBAR 127 UNSPEC_ARC_DMACH 128 UNSPEC_ARC_DMACHU 129 UNSPEC_ARC_DMACWH 130 UNSPEC_ARC_DMACWHU 131 UNSPEC_ARC_QMACH 132 UNSPEC_ARC_QMACHU 133 UNSPEC_ARC_QMPYH 134 UNSPEC_ARC_QMPYHU 135 UNSPEC_ARC_VMAC2H 136 UNSPEC_ARC_VMAC2HU 137 UNSPEC_ARC_VMPY2H 138 UNSPEC_ARC_VMPY2HU 139 140 VUNSPEC_ARC_RTIE 141 VUNSPEC_ARC_SYNC 142 VUNSPEC_ARC_BRK 143 VUNSPEC_ARC_FLAG 144 VUNSPEC_ARC_SLEEP 145 VUNSPEC_ARC_SWI 146 VUNSPEC_ARC_CORE_READ 147 VUNSPEC_ARC_CORE_WRITE 148 VUNSPEC_ARC_LR 149 VUNSPEC_ARC_SR 150 VUNSPEC_ARC_TRAP_S 151 VUNSPEC_ARC_UNIMP_S 152 VUNSPEC_ARC_KFLAG 153 VUNSPEC_ARC_CLRI 154 VUNSPEC_ARC_SETI 155 VUNSPEC_ARC_NOP 156 VUNSPEC_ARC_STACK_IRQ 157 VUNSPEC_ARC_DEXCL 158 VUNSPEC_ARC_DEXCL_NORES 159 VUNSPEC_ARC_LR_HIGH 160 VUNSPEC_ARC_EX 161 VUNSPEC_ARC_CAS 162 VUNSPEC_ARC_SC 163 VUNSPEC_ARC_LL 164 VUNSPEC_ARC_BLOCKAGE 165 VUNSPEC_ARC_EH_RETURN 166 ]) 167 168(define_constants 169 [(R0_REG 0) 170 (R1_REG 1) 171 (R2_REG 2) 172 (R3_REG 3) 173 (R4_REG 4) 174 175 (R9_REG 9) 176 (R10_REG 10) 177 178 (R12_REG 12) 179 180 (R15_REG 15) 181 (R16_REG 16) 182 183 (R25_REG 25) 184 (SP_REG 28) 185 (ILINK1_REG 29) 186 (ILINK2_REG 30) 187 (R30_REG 30) 188 (RETURN_ADDR_REGNUM 31) 189 (R32_REG 32) 190 (R40_REG 40) 191 (R41_REG 41) 192 (R42_REG 42) 193 (R43_REG 43) 194 (R44_REG 44) 195 (R57_REG 57) 196 (MUL64_OUT_REG 58) 197 (MUL32x16_REG 56) 198 (ARCV2_ACC 58) 199 (R59_REG 59) 200 201 (LP_COUNT 60) 202 (CC_REG 61) 203 (PCL_REG 63) 204 ] 205) 206 207(define_attr "is_sfunc" "no,yes" (const_string "no")) 208 209;; Insn type. Used to default other attribute values. 210; While the attribute is_sfunc is set for any call of a special function, 211; the instruction type sfunc is used only for the special call sequence 212; that loads the (pc-relative) function address into r12 and then calls 213; via r12. 214 215(define_attr "type" 216 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch, 217 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot, 218 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return, 219 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, 220 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero, 221 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle, 222 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc, 223 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc, 224 simd_valign, simd_valign_with_acc, simd_vcontrol, 225 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem, 226 fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block" 227 (cond [(eq_attr "is_sfunc" "yes") 228 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call") 229 (match_test "flag_pic") (const_string "sfunc")] 230 (const_string "call_no_delay_slot"))] 231 (const_string "binary"))) 232 233;; The following three attributes are mixed case so that they can be 234;; used conveniently with the CALL_ATTR macro. 235(define_attr "is_CALL" "no,yes" 236 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes") 237 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")] 238 (const_string "no"))) 239 240(define_attr "is_SIBCALL" "no,yes" (const_string "no")) 241 242(define_attr "is_NON_SIBCALL" "no,yes" 243 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no") 244 (eq_attr "is_CALL" "yes") (const_string "yes")] 245 (const_string "no"))) 246 247;; true for compact instructions (those with _s suffix) 248;; "maybe" means compact unless we conditionalize the insn. 249(define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false" 250 (cond [(eq_attr "type" "sfunc") 251 (const_string "maybe")] 252 (const_string "false"))) 253 254 255; Is there an instruction that we are actually putting into the delay slot? 256(define_attr "delay_slot_filled" "no,yes" 257 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn") 258 (const_string "no") 259 (match_test "!TARGET_AT_DBR_CONDEXEC 260 && JUMP_P (insn) 261 && INSN_ANNULLED_BRANCH_P (insn) 262 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))") 263 (const_string "no")] 264 (const_string "yes"))) 265 266; Is a delay slot present for purposes of shorten_branches? 267; We have to take the length of this insn into account for forward branches 268; even if we don't put the insn actually into a delay slot. 269(define_attr "delay_slot_present" "no,yes" 270 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn") 271 (const_string "no")] 272 (const_string "yes"))) 273 274; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the 275; length of a different insn with the same uid. 276(define_attr "delay_slot_length" "" 277 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn") 278 (const_int 0)] 279 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn))) 280 - get_attr_length (insn)"))) 281 282; for ARCv2 we need to disable/enable different instruction alternatives 283(define_attr "cpu_facility" "std,av1,av2,fpx,cd" 284 (const_string "std")) 285 286; We should consider all the instructions enabled until otherwise 287(define_attr "enabled" "no,yes" 288 (cond [(and (eq_attr "cpu_facility" "av1") 289 (match_test "TARGET_V2")) 290 (const_string "no") 291 292 (and (eq_attr "cpu_facility" "av2") 293 (not (match_test "TARGET_V2"))) 294 (const_string "no") 295 296 (and (eq_attr "cpu_facility" "fpx") 297 (match_test "TARGET_FP_DP_AX")) 298 (const_string "no") 299 300 (and (eq_attr "cpu_facility" "cd") 301 (not (and (match_test "TARGET_V2") 302 (match_test "TARGET_CODE_DENSITY")))) 303 (const_string "no") 304 ] 305 (const_string "yes"))) 306 307(define_attr "predicable" "no,yes" (const_string "no")) 308;; if 'predicable' were not so brain-dead, we would specify: 309;; (cond [(eq_attr "cond" "!canuse") (const_string "no") 310;; (eq_attr "iscompact" "maybe") (const_string "no")] 311;; (const_string "yes")) 312;; and then for everything but calls, we could just set the cond attribute. 313 314;; Condition codes: this one is used by final_prescan_insn to speed up 315;; conditionalizing instructions. It saves having to scan the rtl to see if 316;; it uses or alters the condition codes. 317 318;; USE: This insn uses the condition codes (eg: a conditional branch). 319;; CANUSE: This insn can use the condition codes (for conditional execution). 320;; SET: All condition codes are set by this insn. 321;; SET_ZN: the Z and N flags are set by this insn. 322;; SET_ZNC: the Z, N, and C flags are set by this insn. 323;; CLOB: The condition codes are set to unknown values by this insn. 324;; NOCOND: This insn can't use and doesn't affect the condition codes. 325 326(define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond" 327 (cond 328 [(and (eq_attr "predicable" "yes") 329 (eq_attr "is_sfunc" "no") 330 (eq_attr "delay_slot_filled" "no")) 331 (const_string "canuse") 332 333 (eq_attr "type" "call") 334 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond") 335 (match_test "!flag_pic") (const_string "canuse_limm")] 336 (const_string "nocond")) 337 338 (eq_attr "iscompact" "maybe,false") 339 (cond [ (and (eq_attr "type" "move") 340 (match_operand 1 "immediate_operand" "")) 341 (if_then_else 342 (ior (match_operand 1 "u6_immediate_operand" "") 343 (match_operand 1 "long_immediate_operand" "")) 344 (const_string "canuse") 345 (const_string "canuse_limm")) 346 347 (eq_attr "type" "binary") 348 (cond [(ne (symbol_ref "REGNO (operands[0])") 349 (symbol_ref "REGNO (operands[1])")) 350 (const_string "nocond") 351 (match_operand 2 "register_operand" "") 352 (const_string "canuse") 353 (match_operand 2 "u6_immediate_operand" "") 354 (const_string "canuse") 355 (match_operand 2 "long_immediate_operand" "") 356 (const_string "canuse") 357 (match_operand 2 "const_int_operand" "") 358 (const_string "canuse_limm")] 359 (const_string "nocond")) 360 361 (eq_attr "type" "compare") 362 (const_string "set") 363 364 (eq_attr "type" "cmove,branch") 365 (const_string "use") 366 367 (eq_attr "is_sfunc" "yes") 368 (cond [(match_test "(TARGET_MEDIUM_CALLS 369 && !TARGET_LONG_CALLS_SET 370 && flag_pic)") 371 (const_string "canuse_limm_add") 372 (match_test "(TARGET_MEDIUM_CALLS 373 && !TARGET_LONG_CALLS_SET)") 374 (const_string "canuse_limm")] 375 (const_string "canuse")) 376 377 ] 378 379 (const_string "nocond"))] 380 381 (cond [(eq_attr "type" "compare") 382 (const_string "set") 383 384 (eq_attr "type" "cmove,branch") 385 (const_string "use") 386 387 ] 388 389 (const_string "nocond")))) 390 391/* ??? Having all these patterns gives ifcvt more freedom to generate 392 inefficient code. It seem to operate on the premise that 393 register-register copies and registers are free. I see better code 394 with -fno-if-convert now than without. */ 395(define_cond_exec 396 [(match_operator 0 "proper_comparison_operator" 397 [(reg CC_REG) (const_int 0)])] 398 "true" 399 "") 400 401;; Length (in # of bytes, long immediate constants counted too). 402;; ??? There's a nasty interaction between the conditional execution fsm 403;; and insn lengths: insns with shimm values cannot be conditionally executed. 404(define_attr "length" "" 405 (cond 406 [(eq_attr "iscompact" "true") 407 (const_int 2) 408 409 (eq_attr "iscompact" "maybe") 410 (cond 411 [(eq_attr "type" "sfunc") 412 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") 413 (const_int 12)] 414 (const_int 10)) 415 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4) 416 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (1))") 417 (const_int 4)] 418 (const_int 2)) 419 420 (eq_attr "iscompact" "true_limm") 421 (const_int 6) 422 423 (eq_attr "iscompact" "maybe_limm") 424 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)] 425 (const_int 6)) 426 427 (eq_attr "type" "load") 428 (if_then_else 429 (match_operand 1 "long_immediate_loadstore_operand" "") 430 (const_int 8) (const_int 4)) 431 432 (eq_attr "type" "store") 433 (if_then_else 434 (ior (match_operand 0 "long_immediate_loadstore_operand" "") 435 (match_operand 1 "immediate_operand" "")) 436 (const_int 8) (const_int 4)) 437 438 (eq_attr "type" "move,unary") 439 (cond 440 [(match_operand 1 "u6_immediate_operand" "") (const_int 4) 441 (match_operand 1 "register_operand" "") (const_int 4) 442 (match_operand 1 "long_immediate_operand" "") (const_int 8) 443 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)] 444 (const_int 4)) 445 446 (and (eq_attr "type" "shift") 447 (match_operand 1 "immediate_operand")) 448 (const_int 8) 449 (eq_attr "type" "binary,shift") 450 (if_then_else 451 (ior (match_operand 2 "long_immediate_operand" "") 452 (and (ne (symbol_ref "REGNO (operands[0])") 453 (symbol_ref "REGNO (operands[1])")) 454 (eq (match_operand 2 "u6_immediate_operand" "") 455 (const_int 0)))) 456 457 (const_int 8) (const_int 4)) 458 459 (eq_attr "type" "cmove") 460 (if_then_else (match_operand 1 "register_operand" "") 461 (const_int 4) (const_int 8)) 462 463 (eq_attr "type" "call_no_delay_slot") (const_int 8) 464 ] 465 466 (const_int 4)) 467) 468 469;; The length here is the length of a single asm. Unfortunately it might be 470;; 4 or 8 so we must allow for 8. That's ok though. How often will users 471;; lament asm's not being put in delay slots? 472;; 473(define_asm_attributes 474 [(set_attr "length" "8") 475 (set_attr "type" "multi") 476 (set_attr "cond" "clob") ]) 477 478;; Delay slots. 479;; The first two cond clauses and the default are necessary for correctness; 480;; the remaining cond clause is mainly an optimization, as otherwise nops 481;; would be inserted; however, if we didn't do this optimization, we would 482;; have to be more conservative in our length calculations. 483 484(define_attr "in_delay_slot" "false,true" 485 (cond [(eq_attr "type" "uncond_branch,jump,branch, 486 call,sfunc,call_no_delay_slot, 487 brcc, brcc_no_delay_slot,loop_setup,loop_end") 488 (const_string "false") 489 (match_test "arc_write_ext_corereg (insn)") 490 (const_string "false") 491 (gt (symbol_ref "arc_hazard (prev_active_insn (insn), 492 next_active_insn (insn))") 493 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn) 494 + arc_hazard (insn, next_active_insn (insn)))")) 495 (const_string "false") 496 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))") 497 (const_string "false") 498 (eq_attr "iscompact" "maybe") (const_string "true") 499 ] 500 501 (if_then_else (eq_attr "length" "2,4") 502 (const_string "true") 503 (const_string "false")))) 504 505; must not put an insn inside that refers to blink. 506(define_attr "in_call_delay_slot" "false,true" 507 (cond [(eq_attr "in_delay_slot" "false") 508 (const_string "false") 509 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))") 510 (const_string "false")] 511 (const_string "true"))) 512 513(define_attr "in_sfunc_delay_slot" "false,true" 514 (cond [(eq_attr "in_call_delay_slot" "false") 515 (const_string "false") 516 (match_test "arc_regno_use_in (12, PATTERN (insn))") 517 (const_string "false")] 518 (const_string "true"))) 519 520;; Instructions that we can put into a delay slot and conditionalize. 521(define_attr "cond_delay_insn" "no,yes" 522 (cond [(eq_attr "cond" "!canuse") (const_string "no") 523 (eq_attr "type" "call,branch,uncond_branch,jump,brcc") 524 (const_string "no") 525 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))") 526 (const_string "no") 527 (eq_attr "length" "2,4") (const_string "yes")] 528 (const_string "no"))) 529 530(define_attr "in_ret_delay_slot" "no,yes" 531 (cond [(eq_attr "in_delay_slot" "false") 532 (const_string "no") 533 (match_test "regno_clobbered_p 534 (arc_return_address_register 535 (arc_compute_function_type (cfun)), 536 insn, SImode, 1)") 537 (const_string "no")] 538 (const_string "yes"))) 539 540(define_attr "cond_ret_delay_insn" "no,yes" 541 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no") 542 (eq_attr "cond_delay_insn" "no") (const_string "no")] 543 (const_string "yes"))) 544 545(define_attr "annul_ret_delay_insn" "no,yes" 546 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes") 547 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no") 548 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc") 549 (const_string "yes")] 550 (const_string "no"))) 551 552 553;; Delay slot definition for ARCompact ISA 554;; ??? FIXME: 555;; When outputting an annul-true insn elegible for cond-exec 556;; in a cbranch delay slot, unless optimizing for size, we use cond-exec 557;; for ARC600; we could also use this for ARC700 if the branch can't be 558;; unaligned and is at least somewhat likely (add parameter for this). 559 560(define_delay (eq_attr "type" "call") 561 [(eq_attr "in_call_delay_slot" "true") 562 (eq_attr "in_call_delay_slot" "true") 563 (nil)]) 564 565(define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC") 566 (eq_attr "type" "brcc")) 567 [(eq_attr "in_delay_slot" "true") 568 (eq_attr "in_delay_slot" "true") 569 (nil)]) 570 571(define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC") 572 (eq_attr "type" "brcc")) 573 [(eq_attr "in_delay_slot" "true") 574 (nil) 575 (nil)]) 576 577(define_delay 578 (eq_attr "type" "return") 579 [(eq_attr "in_ret_delay_slot" "yes") 580 (eq_attr "annul_ret_delay_insn" "yes") 581 (eq_attr "cond_ret_delay_insn" "yes")]) 582 583(define_delay (eq_attr "type" "loop_end") 584 [(eq_attr "in_delay_slot" "true") 585 (eq_attr "in_delay_slot" "true") 586 (nil)]) 587 588;; For ARC600, unexposing the delay sloy incurs a penalty also in the 589;; non-taken case, so the only meaningful way to have an annull-true 590;; filled delay slot is to conditionalize the delay slot insn. 591(define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC") 592 (eq_attr "type" "branch,uncond_branch,jump") 593 (match_test "!optimize_size")) 594 [(eq_attr "in_delay_slot" "true") 595 (eq_attr "cond_delay_insn" "yes") 596 (eq_attr "cond_delay_insn" "yes")]) 597 598;; For ARC700, anything goes for annulled-true insns, since there is no 599;; penalty for the unexposed delay slot when the branch is not taken, 600;; however, we must avoid things that have a delay slot themselvese to 601;; avoid confusing gcc. 602(define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC") 603 (eq_attr "type" "branch,uncond_branch,jump") 604 (match_test "!optimize_size")) 605 [(eq_attr "in_delay_slot" "true") 606 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc") 607 (eq_attr "cond_delay_insn" "yes")]) 608 609;; -mlongcall -fpic sfuncs use r12 to load the function address 610(define_delay (eq_attr "type" "sfunc") 611 [(eq_attr "in_sfunc_delay_slot" "true") 612 (eq_attr "in_sfunc_delay_slot" "true") 613 (nil)]) 614;; ??? need to use a working strategy for canuse_limm: 615;; - either canuse_limm is not eligible for delay slots, and has no 616;; delay slots, or arc_reorg has to treat them as nocond, or it has to 617;; somehow modify them to become inelegible for delay slots if a decision 618;; is made that makes conditional execution required. 619 620(define_attr "tune" "none,arc600,arc7xx,arc700_4_2_std,arc700_4_2_xmac, \ 621core_3, archs4x, archs4xd, archs4xd_slow" 622 (const 623 (cond [(symbol_ref "arc_tune == TUNE_ARC600") 624 (const_string "arc600") 625 (symbol_ref "arc_tune == ARC_TUNE_ARC7XX") 626 (const_string "arc7xx") 627 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD") 628 (const_string "arc700_4_2_std") 629 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC") 630 (const_string "arc700_4_2_xmac") 631 (symbol_ref "arc_tune == ARC_TUNE_CORE_3") 632 (const_string "core_3") 633 (symbol_ref "arc_tune == TUNE_ARCHS4X") 634 (const_string "archs4x") 635 (ior (symbol_ref "arc_tune == TUNE_ARCHS4XD") 636 (symbol_ref "arc_tune == TUNE_ARCHS4XD_SLOW")) 637 (const_string "archs4xd")] 638 (const_string "none")))) 639 640(define_attr "tune_arc700" "false,true" 641 (if_then_else (eq_attr "tune" "arc7xx, arc700_4_2_std, arc700_4_2_xmac") 642 (const_string "true") 643 (const_string "false"))) 644 645(define_attr "tune_dspmpy" "none, slow, fast" 646 (const 647 (cond [(ior (symbol_ref "arc_tune == TUNE_ARCHS4X") 648 (symbol_ref "arc_tune == TUNE_ARCHS4XD")) 649 (const_string "fast") 650 (symbol_ref "arc_tune == TUNE_ARCHS4XD_SLOW") 651 (const_string "slow")] 652 (const_string "none")))) 653 654;; Move instructions. 655(define_expand "movqi" 656 [(set (match_operand:QI 0 "move_dest_operand" "") 657 (match_operand:QI 1 "general_operand" ""))] 658 "" 659 "if (prepare_move_operands (operands, QImode)) DONE;") 660 661; In order to allow the ccfsm machinery to do its work, the leading compact 662; alternatives say 'canuse' - there is another alternative that will match 663; when the condition codes are used. 664; Rcq won't match if the condition is actually used; to avoid a spurious match 665; via q, q is inactivated as constraint there. 666; Likewise, the length of an alternative that might be shifted to conditional 667; execution must reflect this, lest out-of-range branches are created. 668; The iscompact attribute allows the epilogue expander to know for which 669; insns it should lengthen the return insn. 670(define_insn "*movqi_insn" 671 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc") 672 (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))] 673 "register_operand (operands[0], QImode) 674 || register_operand (operands[1], QImode) 675 || (satisfies_constraint_Cm3 (operands[1]) 676 && memory_operand (operands[0], QImode))" 677 "@ 678 mov%? %0,%1%& 679 mov%? %0,%1%& 680 mov%? %0,%1%& 681 mov%? %0,%1%& 682 mov%? %0,%1%& 683 mov%? %0,%1 684 mov%? %0,%1 685 mov%? %0,%1 686 mov%? %0,%1 687 mov%? %0,%1 688 ldb%? %0,%1%& 689 stb%? %1,%0%& 690 ldb%? %0,%1%& 691 xldb%U1 %0,%1 692 ldb%U1%V1 %0,%1 693 xstb%U0 %1,%0 694 stb%U0%V0 %1,%0 695 stb%U0%V0 %1,%0 696 stb%U0%V0 %1,%0 697 stb%U0%V0 %1,%0" 698 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store") 699 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false") 700 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no") 701 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) 702 703(define_expand "movhi" 704 [(set (match_operand:HI 0 "move_dest_operand" "") 705 (match_operand:HI 1 "general_operand" ""))] 706 "" 707 "if (prepare_move_operands (operands, HImode)) DONE;") 708 709(define_insn "*movhi_insn" 710 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,Rcq#q,h, w,Rcq, S, r,r, Ucm,m,???m, m,VUsc") 711 (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac, i,i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))] 712 "register_operand (operands[0], HImode) 713 || register_operand (operands[1], HImode) 714 || (CONSTANT_P (operands[1]) 715 /* Don't use a LIMM that we could load with a single insn - we loose 716 delay-slot filling opportunities. */ 717 && !satisfies_constraint_I (operands[1]) 718 && satisfies_constraint_Usc (operands[0])) 719 || (satisfies_constraint_Cm3 (operands[1]) 720 && memory_operand (operands[0], HImode))" 721 "@ 722 mov%? %0,%1%& 723 mov%? %0,%1%& 724 mov%? %0,%1%& 725 mov%? %0,%1%& 726 mov%? %0,%1%& 727 mov%? %0,%1 728 mov%? %0,%1 729 mov%? %0,%1 730 mov%? %0,%1%& 731 mov%? %0,%1 732 mov%? %0,%1 733 ld%_%? %0,%1%& 734 st%_%? %1,%0%& 735 xld%_%U1 %0,%1 736 ld%_%U1%V1 %0,%1 737 xst%_%U0 %1,%0 738 st%_%U0%V0 %1,%0 739 st%_%U0%V0 %1,%0 740 st%_%U0%V0 %1,%0 741 st%_%U0%V0 %1,%0" 742 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store") 743 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false") 744 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no") 745 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")]) 746 747(define_expand "movsi" 748 [(set (match_operand:SI 0 "move_dest_operand" "") 749 (match_operand:SI 1 "general_operand" ""))] 750 "" 751 "if (prepare_move_operands (operands, SImode)) DONE;") 752 753; In order to allow the ccfsm machinery to do its work, the leading compact 754; alternatives say 'canuse' - there is another alternative that will match 755; when the condition codes are used. 756; Rcq won't match if the condition is actually used; to avoid a spurious match 757; via q, q is inactivated as constraint there. 758; Likewise, the length of an alternative that might be shifted to conditional 759; execution must reflect this, lest out-of-range branches are created. 760; the iscompact attribute allows the epilogue expander to know for which 761; insns it should lengthen the return insn. 762; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . 763(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 764 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,wl, w, w, w, w, w,???w, ?w, w,Rcq#q, h, wl,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m, m,VUsc") 765 (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac,Cm3, C32"))] 766 "register_operand (operands[0], SImode) 767 || register_operand (operands[1], SImode) 768 || (CONSTANT_P (operands[1]) 769 /* Don't use a LIMM that we could load with a single insn - we loose 770 delay-slot filling opportunities. */ 771 && !satisfies_constraint_I (operands[1]) 772 && satisfies_constraint_Usc (operands[0])) 773 || (satisfies_constraint_Cm3 (operands[1]) 774 && memory_operand (operands[0], SImode))" 775 "@ 776 mov%? %0,%1%& ;0 777 mov%? %0,%1%& ;1 778 mov%? %0,%1%& ;2 779 mov%? %0,%1%& ;3 780 mov%? %0,%1%& ;4 781 mov%? %0,%1 ;5 782 mov%? %0,%1 ;6 783 ror %0,((%1*2+1) & 0x3f) ;7 784 movl.cl %0,%1 ;8 785 movh.cl %0,%L1>>16 ;9 786 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\"; 787 mov%? %0,%1 ;11 788 add %0,%1 ;12 789 add %0,pcl,%1@pcl ;13 790 mov%? %0,%j1 ;14 791 mov%? %0,%j1 ;15 792 mov%? %0,%j1 ;16 793 ld%? %0,%1 ;17 794 st%? %1,%0%& ;18 795 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); 796 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); 797 ld%? %0,%1%& ;21 798 xld%U1 %0,%1 ;22 799 ld%? %0,%1%& ;23 800 ld%? %0,%1%& ;24 801 ld%U1%V1 %0,%1 ;25 802 xst%U0 %1,%0 ;26 803 st%? %1,%0%& ;27 804 st%U0%V0 %1,%0 ;28 805 st%U0%V0 %1,%0 ;29 806 st%U0%V0 %1,%0 ;30 807 st%U0%V0 %1,%0 ;31" 808 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 809 [(set_attr "type" "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary, move, move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store") 810 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false, false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false,false") 811 ; Use default length for iscompact to allow for COND_EXEC. But set length 812 ; of Crr to 4. 813 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8") 814 (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") 815 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) 816 817;; Sometimes generated by the epilogue code. We don't want to 818;; recognize these addresses in general, because the limm is costly, 819;; and we can't use them for stores. */ 820(define_insn "*movsi_pre_mod" 821 [(set (match_operand:SI 0 "register_operand" "=w") 822 (mem:SI (pre_modify 823 (reg:SI SP_REG) 824 (plus:SI (reg:SI SP_REG) 825 (match_operand 1 "immediate_operand" "Cal")))))] 826 "reload_completed" 827 "ld.a %0,[sp,%1]" 828 [(set_attr "type" "load") 829 (set_attr "length" "8")]) 830 831;; Store a value to directly to memory. The location might also be cached. 832;; Since the cached copy can cause a write-back at unpredictable times, 833;; we first write cached, then we write uncached. 834(define_insn "store_direct" 835 [(set (match_operand:SI 0 "move_dest_operand" "=m") 836 (unspec:SI [(match_operand:SI 1 "register_operand" "c")] 837 UNSPEC_ARC_DIRECT))] 838 "" 839 "st%U0 %1,%0\;st%U0.di %1,%0" 840 [(set_attr "type" "store")]) 841 842;; Combiner patterns for compare with zero 843(define_mode_iterator SQH [QI HI]) 844(define_mode_attr SQH_postfix [(QI "b") (HI "%_")]) 845 846(define_code_iterator SEZ [sign_extend zero_extend]) 847(define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")]) 848 849(define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout" 850 [(set (match_operand 0 "cc_set_register" "") 851 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r")) 852 (const_int 0)))] 853 "" 854 "<SEZ_prefix><SQH_postfix>.f\\t0,%1" 855 [(set_attr "type" "compare") 856 (set_attr "cond" "set_zn")]) 857 858(define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0" 859 [(set (match_operand 0 "cc_set_register" "") 860 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r")) 861 (const_int 0))) 862 (set (match_operand:SI 2 "register_operand" "=r") 863 (SEZ:SI (match_dup 1)))] 864 "" 865 "<SEZ_prefix><SQH_postfix>.f\\t%2,%1" 866 [(set_attr "type" "compare") 867 (set_attr "cond" "set_zn")]) 868 869(define_insn "*xbfu_cmp0_noout" 870 [(set (match_operand 0 "cc_set_register" "") 871 (compare:CC_Z 872 (zero_extract:SI 873 (match_operand:SI 1 "register_operand" " r,r") 874 (match_operand:SI 2 "const_int_operand" "C3p,n") 875 (match_operand:SI 3 "const_int_operand" " n,n")) 876 (const_int 0)))] 877 "TARGET_HS && TARGET_BARREL_SHIFTER" 878 { 879 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f); 880 operands[2] = GEN_INT (assemble_op2); 881 return "xbfu%?.f\\t0,%1,%2"; 882 } 883 [(set_attr "type" "shift") 884 (set_attr "iscompact" "false") 885 (set_attr "length" "4,8") 886 (set_attr "predicable" "no") 887 (set_attr "cond" "set_zn")]) 888 889(define_insn "*xbfu_cmp0" 890 [(set (match_operand 4 "cc_set_register" "") 891 (compare:CC_Z 892 (zero_extract:SI 893 (match_operand:SI 1 "register_operand" "0 ,r,0") 894 (match_operand:SI 2 "const_int_operand" "C3p,n,n") 895 (match_operand:SI 3 "const_int_operand" "n ,n,n")) 896 (const_int 0))) 897 (set (match_operand:SI 0 "register_operand" "=r,r,r") 898 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 899 "TARGET_HS && TARGET_BARREL_SHIFTER" 900 { 901 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f); 902 operands[2] = GEN_INT (assemble_op2); 903 return "xbfu%?.f\\t%0,%1,%2"; 904 } 905 [(set_attr "type" "shift") 906 (set_attr "iscompact" "false") 907 (set_attr "length" "4,8,8") 908 (set_attr "predicable" "yes,no,yes") 909 (set_attr "cond" "set_zn")]) 910 911; splitting to 'tst' allows short insns and combination into brcc. 912(define_insn_and_split "*movsi_set_cc_insn" 913 [(set (match_operand 2 "cc_set_register" "") 914 (match_operator 3 "zn_compare_operator" 915 [(match_operand:SI 1 "nonmemory_operand" "rL,rI,Cal") 916 (const_int 0)])) 917 (set (match_operand:SI 0 "register_operand" "=r,r,r") 918 (match_dup 1))] 919 "" 920 "mov%?.f\\t%0,%1" 921 "reload_completed && operands_match_p (operands[0], operands[1])" 922 [(set (match_dup 2) (match_dup 3))] 923 "" 924 [(set_attr "type" "compare") 925 (set_attr "predicable" "yes,no,yes") 926 (set_attr "cond" "set_zn") 927 (set_attr "length" "4,4,8")]) 928 929(define_insn "unary_comparison" 930 [(set (match_operand:CC_ZN 0 "cc_set_register" "") 931 (match_operator:CC_ZN 3 "zn_compare_operator" 932 [(match_operator:SI 2 "unary_operator" 933 [(match_operand:SI 1 "register_operand" "c")]) 934 (const_int 0)]))] 935 "" 936 "%O2.f 0,%1" 937 [(set_attr "type" "compare") 938 (set_attr "cond" "set_zn")]) 939 940 941; this pattern is needed by combiner for cases like if (c=(~b)) { ... } 942(define_insn "*unary_comparison_result_used" 943 [(set (match_operand 2 "cc_register" "") 944 (match_operator 4 "zn_compare_operator" 945 [(match_operator:SI 3 "unary_operator" 946 [(match_operand:SI 1 "register_operand" "c")]) 947 (const_int 0)])) 948 (set (match_operand:SI 0 "register_operand" "=w") 949 (match_dup 3))] 950 "" 951 "%O3.f %0,%1" 952 [(set_attr "type" "compare") 953 (set_attr "cond" "set_zn") 954 (set_attr "length" "4")]) 955 956; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees 957; a c/???Cal/X alternative, so we say it's c/???Cal/c instead, 958; even if we don't need the clobber. 959(define_insn_and_split "*tst_movb" 960 [(set 961 (match_operand 0 "cc_register" "") 962 (match_operator 4 "zn_compare_operator" 963 [(and:SI 964 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq,Rrq, c") 965 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal")) 966 (const_int 0)])) 967 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))] 968 "TARGET_NPS_BITOPS" 969 "movb.f.cl %3,%1,%p2,%p2,%s2" 970 "TARGET_NPS_BITOPS && reload_completed 971 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)" 972 [(set (match_dup 0) (match_dup 4))]) 973 974(define_insn "*tst" 975 [(set 976 (match_operand 0 "cc_register" "") 977 (match_operator 3 "zn_compare_operator" 978 [(and:SI 979 (match_operand:SI 1 "register_operand" 980 "%Rcq,Rcq, c, c, c, c, c, c") 981 (match_operand:SI 2 "nonmemory_operand" 982 " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal")) 983 (const_int 0)]))] 984 "reload_completed 985 || !satisfies_constraint_Cbf (operands[2]) 986 || satisfies_constraint_C0p (operands[2]) 987 || satisfies_constraint_I (operands[2]) 988 || satisfies_constraint_C1p (operands[2]) 989 || satisfies_constraint_Chs (operands[2])" 990 "* 991 switch (which_alternative) 992 { 993 case 0: case 2: case 3: case 7: 994 return \"tst%? %1,%2\"; 995 case 1: 996 return \"btst%? %1,%z2\"; 997 case 4: 998 return \"bmsk%?.f 0,%1,%Z2%&\"; 999 case 5: 1000 return \"bclr%?.f 0,%1,%M2%&\"; 1001 case 6: 1002 return \"asr.f 0,%1,%p2\"; 1003 default: 1004 gcc_unreachable (); 1005 } 1006 " 1007 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false") 1008 (set_attr "type" "compare,compare,compare,compare,compare,compare,binary,compare") 1009 (set_attr "length" "*,*,4,4,4,4,4,8") 1010 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes") 1011 (set_attr "cond" "set_zn")]) 1012 1013; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract, 1014; combine will do that and not try the AND. 1015 1016; It would take 66 constraint combinations to describe the zero_extract 1017; constants that are covered by the 12-bit signed constant for tst 1018; (excluding the ones that are better done by mov or btst). 1019; so we rather use an extra pattern for tst; 1020; since this is about constants, reload shouldn't care. 1021(define_insn "*tst_bitfield_tst" 1022 [(set (match_operand:CC_ZN 0 "cc_set_register" "") 1023 (match_operator 4 "zn_compare_operator" 1024 [(zero_extract:SI 1025 (match_operand:SI 1 "register_operand" "c") 1026 (match_operand:SI 2 "const_int_operand" "n") 1027 (match_operand:SI 3 "const_int_operand" "n")) 1028 (const_int 0)]))] 1029 "INTVAL (operands[2]) > 1 1030 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11 1031 || (INTVAL (operands[3]) <= 11 1032 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))" 1033 "tst %1,((1<<%2)-1)<<%3" 1034 [(set_attr "type" "compare") 1035 (set_attr "cond" "set_zn") 1036 (set_attr "length" "4")]) 1037 1038; Likewise for asr.f. 1039(define_insn "*tst_bitfield_asr" 1040 [(set (match_operand:CC_ZN 0 "cc_set_register" "") 1041 (match_operator 4 "zn_compare_operator" 1042 [(zero_extract:SI 1043 (match_operand:SI 1 "register_operand" "c") 1044 (match_operand:SI 2 "const_int_operand" "n") 1045 (match_operand:SI 3 "const_int_operand" "n")) 1046 (const_int 0)]))] 1047 "INTVAL (operands[2]) > 1 1048 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32" 1049 "asr.f 0,%1,%3" 1050 [(set_attr "type" "shift") 1051 (set_attr "cond" "set_zn") 1052 (set_attr "length" "4")]) 1053 1054(define_insn "*tst_bitfield" 1055 [(set (match_operand:CC_ZN 0 "cc_set_register" "") 1056 (match_operator 5 "zn_compare_operator" 1057 [(zero_extract:SI 1058 (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c") 1059 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n") 1060 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n")) 1061 (const_int 0)])) 1062 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))] 1063 "" 1064 "@ 1065 btst%? %1,%3 1066 btst %1,%3 1067 bmsk.f 0,%1,%2-1 1068 movb.f.cl %4,%1,%3,%3,%2 1069 and.f 0,%1,((1<<%2)-1)<<%3" 1070 [(set_attr "iscompact" "maybe,false,false,false,false") 1071 (set_attr "type" "compare,compare,compare,shift,compare") 1072 (set_attr "cond" "set_zn") 1073 (set_attr "length" "*,4,4,4,8")]) 1074 1075;; The next two patterns are for plos, ior, xor, and, and mult. 1076(define_insn "*commutative_binary_cmp0_noout" 1077 [(set (match_operand 0 "cc_set_register" "") 1078 (match_operator 4 "zn_compare_operator" 1079 [(match_operator:SI 3 "commutative_operator" 1080 [(match_operand:SI 1 "register_operand" "%r,r") 1081 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")]) 1082 (const_int 0)]))] 1083 "" 1084 "%O3.f\\t0,%1,%2" 1085 [(set_attr "type" "compare") 1086 (set_attr "cond" "set_zn") 1087 (set_attr "length" "4,8")]) 1088 1089(define_insn "*commutative_binary_cmp0" 1090 [(set (match_operand 3 "cc_set_register" "") 1091 (match_operator 5 "zn_compare_operator" 1092 [(match_operator:SI 4 "commutative_operator" 1093 [(match_operand:SI 1 "register_operand" "%0, 0,r,r") 1094 (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")]) 1095 (const_int 0)])) 1096 (set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1097 (match_dup 4))] 1098 "" 1099 "%O4.f\\t%0,%1,%2" 1100 [(set_attr "type" "compare") 1101 (set_attr "cond" "set_zn") 1102 (set_attr "predicable" "yes,yes,no,no") 1103 (set_attr "length" "4,4,4,8")]) 1104 1105; for flag setting 'add' instructions like if (a+b) { ...} 1106; the combiner needs this pattern 1107(define_insn "*addsi_compare" 1108 [(set (reg:CC_ZN CC_REG) 1109 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c") 1110 (neg:SI (match_operand:SI 1 "register_operand" "c"))))] 1111 "" 1112 "add.f 0,%0,%1" 1113 [(set_attr "cond" "set") 1114 (set_attr "type" "compare") 1115 (set_attr "length" "4")]) 1116 1117; for flag setting 'add' instructions like if (a+b < a) { ...} 1118; the combiner needs this pattern 1119(define_insn "addsi_compare_2" 1120 [(set (reg:CC_C CC_REG) 1121 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c") 1122 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")) 1123 (match_dup 0)))] 1124 "" 1125 "add.f 0,%0,%1" 1126 [(set_attr "cond" "set") 1127 (set_attr "type" "compare") 1128 (set_attr "length" "4,8")]) 1129 1130(define_insn "*addsi_compare_3" 1131 [(set (reg:CC_C CC_REG) 1132 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c") 1133 (match_operand:SI 1 "register_operand" "c")) 1134 (match_dup 1)))] 1135 "" 1136 "add.f 0,%0,%1" 1137 [(set_attr "cond" "set") 1138 (set_attr "type" "compare") 1139 (set_attr "length" "4")]) 1140 1141; this pattern is needed by combiner for cases like if (c=a+b) { ... } 1142(define_insn "*commutative_binary_comparison_result_used" 1143 [(set (match_operand 3 "cc_register" "") 1144 (match_operator 5 "zn_compare_operator" 1145 ; We can accept any commutative operator except mult because 1146 ; our 'w' class below could try to use LP_COUNT. 1147 [(match_operator:SI 4 "commutative_operator_sans_mult" 1148 [(match_operand:SI 1 "register_operand" "c,0,c") 1149 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")]) 1150 (const_int 0)])) 1151 (set (match_operand:SI 0 "register_operand" "=w,w,w") 1152 (match_dup 4))] 1153 "" 1154 "%O4.f %0,%1,%2 ; non-mult commutative" 1155 [(set_attr "type" "compare,compare,compare") 1156 (set_attr "cond" "set_zn,set_zn,set_zn") 1157 (set_attr "length" "4,4,8")]) 1158 1159; a MULT-specific version of this pattern to avoid touching the 1160; LP_COUNT register 1161(define_insn "*commutative_binary_mult_comparison_result_used" 1162 [(set (match_operand 3 "cc_register" "") 1163 (match_operator 5 "zn_compare_operator" 1164 [(match_operator:SI 4 "mult_operator" 1165 [(match_operand:SI 1 "register_operand" "c,0,c") 1166 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")]) 1167 (const_int 0)])) 1168 ; Make sure to use the W class to not touch LP_COUNT. 1169 (set (match_operand:SI 0 "register_operand" "=W,W,W") 1170 (match_dup 4))] 1171 "!TARGET_ARC600_FAMILY" 1172 "%O4.f %0,%1,%2 ; mult commutative" 1173 [(set_attr "type" "compare,compare,compare") 1174 (set_attr "cond" "set_zn,set_zn,set_zn") 1175 (set_attr "length" "4,4,8")]) 1176 1177(define_insn "*noncommutative_binary_cmp0" 1178 [(set (match_operand 3 "cc_set_register" "") 1179 (match_operator 5 "zn_compare_operator" 1180 [(match_operator:SI 4 "noncommutative_operator" 1181 [(match_operand:SI 1 "register_operand" "0,r,0, 0,r") 1182 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,Cal,Cal")]) 1183 (const_int 0)])) 1184 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") 1185 (match_dup 4))] 1186 "" 1187 "%O4%?.f\\t%0,%1,%2" 1188 [(set_attr "type" "compare") 1189 (set_attr "cond" "set_zn") 1190 (set_attr "predicable" "yes,no,no,yes,no") 1191 (set_attr "length" "4,4,4,8,8")]) 1192 1193(define_insn "*noncommutative_binary_cmp0_noout" 1194 [(set (match_operand 0 "cc_set_register" "") 1195 (match_operator 3 "zn_compare_operator" 1196 [(match_operator:SI 4 "noncommutative_operator" 1197 [(match_operand:SI 1 "register_operand" "r,r") 1198 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")]) 1199 (const_int 0)]))] 1200 "" 1201 "%O4.f\\t0,%1,%2" 1202 [(set_attr "type" "compare") 1203 (set_attr "cond" "set_zn") 1204 (set_attr "length" "4,8")]) 1205 1206;;rsub variants 1207(define_insn "*rsub_cmp0" 1208 [(set (match_operand 4 "cc_set_register" "") 1209 (match_operator 3 "zn_compare_operator" 1210 [(minus:SI 1211 (match_operand:SI 1 "nonmemory_operand" "rL,Cal") 1212 (match_operand:SI 2 "register_operand" "r,r")) 1213 (const_int 0)])) 1214 (set (match_operand:SI 0 "register_operand" "=r,r") 1215 (minus:SI (match_dup 1) (match_dup 2)))] 1216 "" 1217 "rsub.f\\t%0,%2,%1" 1218 [(set_attr "type" "compare") 1219 (set_attr "cond" "set_zn") 1220 (set_attr "length" "4,8")]) 1221 1222(define_insn "*rsub_cmp0_noout" 1223 [(set (match_operand 0 "cc_set_register" "") 1224 (match_operator 3 "zn_compare_operator" 1225 [(minus:SI 1226 (match_operand:SI 1 "nonmemory_operand" "rL,Cal") 1227 (match_operand:SI 2 "register_operand" "r,r")) 1228 (const_int 0)]))] 1229 "" 1230 "rsub.f\\t0,%2,%1" 1231 [(set_attr "type" "compare") 1232 (set_attr "cond" "set_zn") 1233 (set_attr "length" "4,8")]) 1234 1235(define_expand "bic_f_zn" 1236 [(parallel 1237 [(set (reg:CC_ZN CC_REG) 1238 (compare:CC_ZN 1239 (and:SI (match_operand:SI 1 "register_operand" "") 1240 (not:SI (match_operand:SI 2 "nonmemory_operand" ""))) 1241 (const_int 0))) 1242 (set (match_operand:SI 0 "register_operand" "") 1243 (and:SI (match_dup 1) (not:SI (match_dup 2))))])] 1244 "") 1245 1246(define_insn "*bic_f" 1247 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc") 1248 (match_operator 4 "zn_compare_operator" 1249 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c") 1250 (not:SI 1251 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal"))) 1252 (const_int 0)])) 1253 (set (match_operand:SI 0 "register_operand" "=w,w,w") 1254 (and:SI (match_dup 1) (not:SI (match_dup 2))))] 1255 "" 1256 "bic.f %0,%1,%2" 1257 [(set_attr "type" "compare,compare,compare") 1258 (set_attr "cond" "set_zn,set_zn,set_zn") 1259 (set_attr "length" "4,4,8")]) 1260 1261(define_expand "movdi" 1262 [(set (match_operand:DI 0 "move_dest_operand" "") 1263 (match_operand:DI 1 "general_operand" ""))] 1264 "" 1265 " 1266 if (prepare_move_operands (operands, DImode)) 1267 DONE; 1268 ") 1269 1270(define_insn_and_split "*movdi_insn" 1271 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r, m") 1272 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,cCm3"))] 1273 "register_operand (operands[0], DImode) 1274 || register_operand (operands[1], DImode) 1275 || (satisfies_constraint_Cm3 (operands[1]) 1276 && memory_operand (operands[0], DImode))" 1277 "* 1278{ 1279 switch (which_alternative) 1280 { 1281 default: 1282 return \"#\"; 1283 1284 case 2: 1285 if (TARGET_LL64 1286 && memory_operand (operands[1], DImode) 1287 && even_register_operand (operands[0], DImode)) 1288 return \"ldd%U1%V1 %0,%1%&\"; 1289 return \"#\"; 1290 1291 case 3: 1292 if (TARGET_LL64 1293 && memory_operand (operands[0], DImode) 1294 && (even_register_operand (operands[1], DImode) 1295 || satisfies_constraint_Cm3 (operands[1]))) 1296 return \"std%U0%V0 %1,%0\"; 1297 return \"#\"; 1298 } 1299}" 1300 "reload_completed" 1301 [(const_int 0)] 1302 { 1303 arc_split_move (operands); 1304 DONE; 1305 } 1306 [(set_attr "type" "move,move,load,store") 1307 ;; ??? The ld/st values could be 4 if it's [reg,bignum]. 1308 (set_attr "length" "8,16,*,*")]) 1309 1310 1311;; Floating point move insns. 1312 1313(define_expand "movsf" 1314 [(set (match_operand:SF 0 "move_dest_operand" "") 1315 (match_operand:SF 1 "general_operand" ""))] 1316 "" 1317 "if (prepare_move_operands (operands, SFmode)) DONE;") 1318 1319(define_insn "*movsf_insn" 1320 [(set (match_operand:SF 0 "move_dest_operand" "=h,h, r,r, q,S,Usc,r,m") 1321 (match_operand:SF 1 "move_src_operand" "hCfZ,E,rCfZ,E,Uts,q, E,m,r"))] 1322 "register_operand (operands[0], SFmode) 1323 || register_operand (operands[1], SFmode)" 1324 "@ 1325 mov%?\\t%0,%1 1326 mov%?\\t%0,%1 ; %A1 1327 mov%?\\t%0,%1 1328 mov%?\\t%0,%1 ; %A1 1329 ld%?%U1\\t%0,%1 1330 st%?\\t%1,%0 1331 st%U0%V0\\t%1,%0 1332 ld%U1%V1\\t%0,%1 1333 st%U0%V0\\t%1,%0" 1334 [(set_attr "type" "move,move,move,move,load,store,store,load,store") 1335 (set_attr "predicable" "no,no,yes,yes,no,no,no,no,no") 1336 (set_attr "length" "*,*,4,*,*,*,*,*,*") 1337 (set_attr "iscompact" "true,true_limm,false,false,true,true,false,false,false")]) 1338 1339(define_expand "movdf" 1340 [(set (match_operand:DF 0 "move_dest_operand" "") 1341 (match_operand:DF 1 "general_operand" ""))] 1342 "" 1343 "if (prepare_move_operands (operands, DFmode)) DONE;") 1344 1345(define_insn_and_split "*movdf_insn" 1346 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m") 1347 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))] 1348 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" 1349 "* 1350{ 1351 switch (which_alternative) 1352 { 1353 default: 1354 return \"#\"; 1355 case 4: 1356 if (TARGET_LL64 1357 && ((even_register_operand (operands[0], DFmode) 1358 && memory_operand (operands[1], DFmode)) 1359 || (memory_operand (operands[0], DFmode) 1360 && even_register_operand (operands[1], DFmode)))) 1361 return \"ldd%U1%V1 %0,%1%&\"; 1362 return \"#\"; 1363 1364 case 5: 1365 if (TARGET_LL64 1366 && ((even_register_operand (operands[0], DFmode) 1367 && memory_operand (operands[1], DFmode)) 1368 || (memory_operand (operands[0], DFmode) 1369 && even_register_operand (operands[1], DFmode)))) 1370 return \"std%U0%V0 %1,%0\"; 1371 return \"#\"; 1372 } 1373}" 1374 "reload_completed" 1375 [(const_int 0)] 1376 { 1377 arc_split_move (operands); 1378 DONE; 1379 } 1380 [(set_attr "type" "move,move,move,move,load,store") 1381 (set_attr "predicable" "no,no,yes,yes,no,no") 1382 ;; ??? The ld/st values could be 16 if it's [reg,bignum]. 1383 (set_attr "length" "4,16,8,16,16,16")]) 1384 1385(define_insn_and_split "*movdf_insn_nolrsr" 1386 [(set (match_operand:DF 0 "register_operand" "=r") 1387 (match_operand:DF 1 "arc_double_register_operand" "D")) 1388 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx 1389 ] 1390 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR" 1391 "#" 1392 "&& 1" 1393 [ 1394 ; mov r0, 0 1395 (set (match_dup 0) (match_dup 3)) 1396 1397 ; daddh?? r1, r0, r0 1398 (parallel [ 1399 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0))) 1400 (use (const_int 1)) 1401 (use (const_int 1)) 1402 (use (match_dup 0)) ; used to block can_combine_p 1403 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0 1404 ]) 1405 1406 ; We have to do this twice, once to read the value into R0 and 1407 ; second time to put back the contents which the first DEXCLx 1408 ; will have overwritten 1409 ; dexcl2 r0, r1, r0 1410 (parallel [ 1411 (set (match_dup 4) ; aka r0result 1412 ; aka DF, r1, r0 1413 (unspec_volatile:SI [(match_dup 5) (match_dup 4)] 1414 VUNSPEC_ARC_DEXCL)) 1415 (clobber (match_dup 1)) 1416 ]) 1417 ; Generate the second, which makes sure operand5 and operand4 values 1418 ; are put back in the Dx register properly. 1419 (set (match_dup 1) (unspec_volatile:DF 1420 [(match_dup 5) (match_dup 4)] 1421 VUNSPEC_ARC_DEXCL_NORES)) 1422 1423 ; Note: we cannot use a (clobber (match_scratch)) here because 1424 ; the combine pass will end up replacing uses of it with 0 1425 ] 1426 "operands[3] = CONST0_RTX (DFmode); 1427 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0); 1428 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);" 1429 [(set_attr "type" "move")]) 1430 1431;; Load/Store with update instructions. 1432;; 1433;; Some of these we can get by using pre-decrement or pre-increment, but the 1434;; hardware can also do cases where the increment is not the size of the 1435;; object. 1436;; 1437;; In all these cases, we use operands 0 and 1 for the register being 1438;; incremented because those are the operands that local-alloc will 1439;; tie and these are the pair most likely to be tieable (and the ones 1440;; that will benefit the most). 1441;; 1442;; We use match_operator here because we need to know whether the memory 1443;; object is volatile or not. 1444 1445 1446;; Note: loadqi_update has no 16-bit variant 1447(define_insn "*loadqi_update" 1448 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r") 1449 (match_operator:QI 4 "any_mem_operand" 1450 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1451 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) 1452 (set (match_operand:SI 0 "dest_reg_operand" "=r,r") 1453 (plus:SI (match_dup 1) (match_dup 2)))] 1454 "" 1455 "ldb.a%V4 %3,[%0,%2]" 1456 [(set_attr "type" "load,load") 1457 (set_attr "length" "4,8")]) 1458 1459(define_insn "*load_zeroextendqisi_update" 1460 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") 1461 (zero_extend:SI (match_operator:QI 4 "any_mem_operand" 1462 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1463 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) 1464 (set (match_operand:SI 0 "dest_reg_operand" "=r,r") 1465 (plus:SI (match_dup 1) (match_dup 2)))] 1466 "" 1467 "ldb.a%V4 %3,[%0,%2]" 1468 [(set_attr "type" "load,load") 1469 (set_attr "length" "4,8")]) 1470 1471(define_insn "*load_signextendqisi_update" 1472 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") 1473 (sign_extend:SI (match_operator:QI 4 "any_mem_operand" 1474 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1475 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) 1476 (set (match_operand:SI 0 "dest_reg_operand" "=r,r") 1477 (plus:SI (match_dup 1) (match_dup 2)))] 1478 "" 1479 "ldb.x.a%V4 %3,[%0,%2]" 1480 [(set_attr "type" "load,load") 1481 (set_attr "length" "4,8")]) 1482 1483(define_insn "*storeqi_update" 1484 [(set (match_operator:QI 4 "any_mem_operand" 1485 [(plus:SI (match_operand:SI 1 "register_operand" "0") 1486 (match_operand:SI 2 "short_immediate_operand" "I"))]) 1487 (match_operand:QI 3 "register_operand" "c")) 1488 (set (match_operand:SI 0 "dest_reg_operand" "=w") 1489 (plus:SI (match_dup 1) (match_dup 2)))] 1490 "" 1491 "stb.a%V4 %3,[%0,%2]" 1492 [(set_attr "type" "store") 1493 (set_attr "length" "4")]) 1494 1495;; ??? pattern may have to be re-written 1496;; Note: no 16-bit variant for this pattern 1497(define_insn "*loadhi_update" 1498 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r") 1499 (match_operator:HI 4 "any_mem_operand" 1500 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1501 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) 1502 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 1503 (plus:SI (match_dup 1) (match_dup 2)))] 1504 "" 1505 "ld%_.a%V4 %3,[%0,%2]" 1506 [(set_attr "type" "load,load") 1507 (set_attr "length" "4,8")]) 1508 1509(define_insn "*load_zeroextendhisi_update" 1510 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") 1511 (zero_extend:SI (match_operator:HI 4 "any_mem_operand" 1512 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1513 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) 1514 (set (match_operand:SI 0 "dest_reg_operand" "=r,r") 1515 (plus:SI (match_dup 1) (match_dup 2)))] 1516 "" 1517 "ld%_.a%V4 %3,[%0,%2]" 1518 [(set_attr "type" "load,load") 1519 (set_attr "length" "4,8")]) 1520 1521;; Note: no 16-bit variant for this instruction 1522(define_insn "*load_signextendhisi_update" 1523 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") 1524 (sign_extend:SI (match_operator:HI 4 "any_mem_operand" 1525 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1526 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) 1527 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 1528 (plus:SI (match_dup 1) (match_dup 2)))] 1529 "" 1530 "ld%_.x.a%V4 %3,[%0,%2]" 1531 [(set_attr "type" "load,load") 1532 (set_attr "length" "4,8")]) 1533 1534(define_insn "*storehi_update" 1535 [(set (match_operator:HI 4 "any_mem_operand" 1536 [(plus:SI (match_operand:SI 1 "register_operand" "0") 1537 (match_operand:SI 2 "short_immediate_operand" "I"))]) 1538 (match_operand:HI 3 "register_operand" "c")) 1539 (set (match_operand:SI 0 "dest_reg_operand" "=w") 1540 (plus:SI (match_dup 1) (match_dup 2)))] 1541 "" 1542 "st%_.a%V4 %3,[%0,%2]" 1543 [(set_attr "type" "store") 1544 (set_attr "length" "4")]) 1545 1546;; No 16-bit variant for this instruction pattern 1547(define_insn "*loadsi_update" 1548 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") 1549 (match_operator:SI 4 "any_mem_operand" 1550 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1551 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) 1552 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 1553 (plus:SI (match_dup 1) (match_dup 2)))] 1554 "" 1555 "ld.a%V4 %3,[%0,%2]" 1556 [(set_attr "type" "load,load") 1557 (set_attr "length" "4,8")]) 1558 1559(define_insn "*storesi_update" 1560 [(set (match_operator:SI 4 "any_mem_operand" 1561 [(plus:SI (match_operand:SI 1 "register_operand" "0") 1562 (match_operand:SI 2 "short_immediate_operand" "I"))]) 1563 (match_operand:SI 3 "register_operand" "c")) 1564 (set (match_operand:SI 0 "dest_reg_operand" "=w") 1565 (plus:SI (match_dup 1) (match_dup 2)))] 1566 "" 1567 "st.a%V4 %3,[%0,%2]" 1568 [(set_attr "type" "store") 1569 (set_attr "length" "4")]) 1570 1571(define_insn "*loadsf_update" 1572 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r") 1573 (match_operator:SF 4 "any_mem_operand" 1574 [(plus:SI (match_operand:SI 1 "register_operand" "0,0") 1575 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) 1576 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 1577 (plus:SI (match_dup 1) (match_dup 2)))] 1578 "" 1579 "ld.a%V4 %3,[%0,%2]" 1580 [(set_attr "type" "load,load") 1581 (set_attr "length" "4,8")]) 1582 1583(define_insn "*storesf_update" 1584 [(set (match_operator:SF 4 "any_mem_operand" 1585 [(plus:SI (match_operand:SI 1 "register_operand" "0") 1586 (match_operand:SI 2 "short_immediate_operand" "I"))]) 1587 (match_operand:SF 3 "register_operand" "c")) 1588 (set (match_operand:SI 0 "dest_reg_operand" "=w") 1589 (plus:SI (match_dup 1) (match_dup 2)))] 1590 "" 1591 "st.a%V4 %3,[%0,%2]" 1592 [(set_attr "type" "store") 1593 (set_attr "length" "4")]) 1594 1595;; Conditional move instructions. 1596 1597(define_expand "movsicc" 1598 [(set (match_operand:SI 0 "dest_reg_operand" "") 1599 (if_then_else:SI (match_operand 1 "comparison_operator" "") 1600 (match_operand:SI 2 "nonmemory_operand" "") 1601 (match_operand:SI 3 "register_operand" "")))] 1602 "" 1603 "operands[1] = gen_compare_reg (operands[1], VOIDmode);") 1604 1605 1606(define_expand "movdicc" 1607 [(set (match_operand:DI 0 "dest_reg_operand" "") 1608 (if_then_else:DI(match_operand 1 "comparison_operator" "") 1609 (match_operand:DI 2 "nonmemory_operand" "") 1610 (match_operand:DI 3 "register_operand" "")))] 1611 "" 1612 "operands[1] = gen_compare_reg (operands[1], VOIDmode);") 1613 1614 1615(define_expand "movsfcc" 1616 [(set (match_operand:SF 0 "dest_reg_operand" "") 1617 (if_then_else:SF (match_operand 1 "comparison_operator" "") 1618 (match_operand:SF 2 "nonmemory_operand" "") 1619 (match_operand:SF 3 "register_operand" "")))] 1620 "" 1621 "operands[1] = gen_compare_reg (operands[1], VOIDmode);") 1622 1623(define_expand "movdfcc" 1624 [(set (match_operand:DF 0 "dest_reg_operand" "") 1625 (if_then_else:DF (match_operand 1 "comparison_operator" "") 1626 (match_operand:DF 2 "nonmemory_operand" "") 1627 (match_operand:DF 3 "register_operand" "")))] 1628 "" 1629 "operands[1] = gen_compare_reg (operands[1], VOIDmode);") 1630 1631(define_insn "*movsicc_insn" 1632 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 1633 (if_then_else:SI (match_operator 3 "proper_comparison_operator" 1634 [(match_operand 4 "cc_register" "") (const_int 0)]) 1635 (match_operand:SI 1 "nonmemory_operand" "cL,Cal") 1636 (match_operand:SI 2 "register_operand" "0,0")))] 1637 "" 1638{ 1639 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE 1640 && satisfies_constraint_Rcq (operands[0])) 1641 return "sub%?.ne %0,%0,%0"; 1642 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */ 1643 if ((optimize_size && (!TARGET_ARC600_FAMILY)) 1644 && rtx_equal_p (operands[1], constm1_rtx) 1645 && GET_CODE (operands[3]) == LTU) 1646 return "sbc.cs %0,%0,%0"; 1647 return "mov.%d3 %0,%1"; 1648} 1649 [(set_attr "type" "cmove,cmove") 1650 (set_attr "length" "4,8")]) 1651 1652;; When there's a mask of a single bit, and then a compare to 0 or 1, 1653;; if the single bit is the sign bit, then GCC likes to convert this 1654;; into a sign extend and a compare less than, or greater to zero. 1655;; This is usually fine, except for the NXP400 where we have access to 1656;; a bit test instruction, along with a special short load instruction 1657;; (from CMEM), that doesn't support sign-extension on load. 1658;; 1659;; This peephole optimisation attempts to restore the use of bit-test 1660;; in those cases where it is useful to do so. 1661(define_peephole2 1662 [(set (match_operand:SI 0 "register_operand" "") 1663 (sign_extend:SI 1664 (match_operand:QI 1 "any_mem_operand" ""))) 1665 (set (reg:CC_ZN CC_REG) 1666 (compare:CC_ZN (match_dup 0) 1667 (const_int 0))) 1668 (set (pc) 1669 (if_then_else (match_operator 2 "ge_lt_comparison_operator" 1670 [(reg:CC_ZN CC_REG) (const_int 0)]) 1671 (match_operand 3 "" "") 1672 (match_operand 4 "" "")))] 1673 "TARGET_NPS_CMEM 1674 && cmem_address (XEXP (operands[1], 0), SImode) 1675 && peep2_reg_dead_p (2, operands[0]) 1676 && peep2_regno_dead_p (3, CC_REG)" 1677 [(set (match_dup 0) 1678 (zero_extend:SI 1679 (match_dup 1))) 1680 (set (reg:CC_ZN CC_REG) 1681 (compare:CC_ZN (zero_extract:SI 1682 (match_dup 0) 1683 (const_int 1) 1684 (const_int 7)) 1685 (const_int 0))) 1686 (set (pc) 1687 (if_then_else (match_dup 2) 1688 (match_dup 3) 1689 (match_dup 4)))] 1690 "if (GET_CODE (operands[2]) == GE) 1691 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx); 1692 else 1693 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);") 1694 1695; Try to generate more short moves, and/or less limms, by substituting a 1696; conditional move with a conditional sub. 1697(define_peephole2 1698 [(set (match_operand:SI 0 "compact_register_operand") 1699 (match_operand:SI 1 "const_int_operand")) 1700 (set (match_dup 0) 1701 (if_then_else:SI (match_operator 3 "proper_comparison_operator" 1702 [(match_operand 4 "cc_register" "") (const_int 0)]) 1703 (match_operand:SI 2 "const_int_operand" "") 1704 (match_dup 0)))] 1705 "!satisfies_constraint_P (operands[1]) 1706 && satisfies_constraint_P (operands[2]) 1707 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))" 1708 [(set (match_dup 0) (match_dup 2)) 1709 (cond_exec 1710 (match_dup 3) 1711 (set (match_dup 0) 1712 (plus:SI (match_dup 0) (match_dup 1))))] 1713 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]), 1714 GET_MODE (operands[4])), 1715 VOIDmode, operands[4], const0_rtx); 1716 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));") 1717 1718(define_insn "*movdicc_insn" 1719 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w") 1720 (if_then_else:DI (match_operator 3 "proper_comparison_operator" 1721 [(match_operand 4 "cc_register" "") (const_int 0)]) 1722 (match_operand:DI 1 "nonmemory_operand" "c,i") 1723 (match_operand:DI 2 "register_operand" "0,0")))] 1724 "" 1725 "* 1726{ 1727 switch (which_alternative) 1728 { 1729 default: 1730 case 0 : 1731 /* We normally copy the low-numbered register first. However, if 1732 the first register operand 0 is the same as the second register of 1733 operand 1, we must copy in the opposite order. */ 1734 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 1735 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\"; 1736 else 1737 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\"; 1738 case 1 : 1739 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\"; 1740 1741 1742 } 1743}" 1744 [(set_attr "type" "cmove,cmove") 1745 (set_attr "length" "8,16")]) 1746 1747 1748(define_insn "*movsfcc_insn" 1749 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w") 1750 (if_then_else:SF (match_operator 3 "proper_comparison_operator" 1751 [(match_operand 4 "cc_register" "") (const_int 0)]) 1752 (match_operand:SF 1 "nonmemory_operand" "c,E") 1753 (match_operand:SF 2 "register_operand" "0,0")))] 1754 "" 1755 "@ 1756 mov.%d3 %0,%1 1757 mov.%d3 %0,%1 ; %A1" 1758 [(set_attr "type" "cmove,cmove")]) 1759 1760(define_insn "*movdfcc_insn" 1761 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w") 1762 (if_then_else:DF (match_operator 1 "proper_comparison_operator" 1763 [(match_operand 4 "cc_register" "") (const_int 0)]) 1764 (match_operand:DF 2 "nonmemory_operand" "c,E") 1765 (match_operand:DF 3 "register_operand" "0,0")))] 1766 "" 1767 "* 1768{ 1769 switch (which_alternative) 1770 { 1771 default: 1772 case 0 : 1773 /* We normally copy the low-numbered register first. However, if 1774 the first register operand 0 is the same as the second register of 1775 operand 1, we must copy in the opposite order. */ 1776 if (REGNO (operands[0]) == REGNO (operands[2]) + 1) 1777 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\"; 1778 else 1779 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\"; 1780 case 1 : 1781 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \"; 1782 1783 } 1784}" 1785 [(set_attr "type" "cmove,cmove") 1786 (set_attr "length" "8,16")]) 1787 1788 1789(define_insn "*zero_extendqihi2_i" 1790 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r") 1791 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))] 1792 "" 1793 "@ 1794 extb%? %0,%1%& 1795 extb%? %0,%1%& 1796 bmsk%? %0,%1,7 1797 extb %0,%1 1798 xldb%U1 %0,%1 1799 ldb%U1 %0,%1" 1800 [(set_attr "type" "unary,unary,unary,unary,load,load") 1801 (set_attr "iscompact" "maybe,true,false,false,false,false") 1802 (set_attr "predicable" "no,no,yes,no,no,no")]) 1803 1804(define_expand "zero_extendqihi2" 1805 [(set (match_operand:HI 0 "dest_reg_operand" "") 1806 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] 1807 "" 1808 "" 1809) 1810 1811(define_insn "*zero_extendqisi2_ac" 1812 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r") 1813 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))] 1814 "" 1815 "@ 1816 extb%? %0,%1%& 1817 extb%? %0,%1%& 1818 bmsk%? %0,%1,7 1819 extb %0,%1 1820 ldb%? %0,%1%& 1821 ldb%? %0,%1%& 1822 xldb%U1 %0,%1 1823 ldb%U1 %0,%1" 1824 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") 1825 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") 1826 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) 1827 1828(define_expand "zero_extendqisi2" 1829 [(set (match_operand:SI 0 "dest_reg_operand" "") 1830 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] 1831 "" 1832 "" 1833) 1834 1835(define_insn "*zero_extendhisi2_i" 1836 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r") 1837 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))] 1838 "" 1839 "@ 1840 ext%_%? %0,%1%& 1841 ext%_%? %0,%1%& 1842 bmsk%? %0,%1,15 1843 ext%_ %0,%1 1844 ld%_%? %0,%1 1845 ld%_%? %0,%1 1846 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\"; 1847 ld%_%U1%V1 %0,%1" 1848 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") 1849 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") 1850 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) 1851 1852 1853(define_expand "zero_extendhisi2" 1854 [(set (match_operand:SI 0 "dest_reg_operand" "") 1855 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))] 1856 "" 1857 "" 1858) 1859 1860;; Sign extension instructions. 1861 1862(define_insn "*extendqihi2_i" 1863 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r") 1864 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))] 1865 "" 1866 "@ 1867 sexb%? %0,%1%& 1868 sexb %0,%1 1869 ldb.x%U1 %0,%1 1870 ldb.x%U1 %0,%1" 1871 [(set_attr "type" "unary,unary,load,load") 1872 (set_attr "iscompact" "true,false,false,false") 1873 (set_attr "length" "*,*,*,8")]) 1874 1875 1876(define_expand "extendqihi2" 1877 [(set (match_operand:HI 0 "dest_reg_operand" "") 1878 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] 1879 "" 1880 "" 1881) 1882 1883(define_insn "*extendqisi2_ac" 1884 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") 1885 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] 1886 "" 1887 "@ 1888 sexb%? %0,%1%& 1889 sexb %0,%1 1890 ldb.x%U1 %0,%1 1891 ldb.x%U1 %0,%1" 1892 [(set_attr "type" "unary,unary,load,load") 1893 (set_attr "iscompact" "true,false,false,false") 1894 (set_attr "length" "*,*,*,8")]) 1895 1896(define_expand "extendqisi2" 1897 [(set (match_operand:SI 0 "dest_reg_operand" "") 1898 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] 1899 "" 1900 "" 1901) 1902 1903(define_insn "*extendhisi2_i" 1904 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r") 1905 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))] 1906 "" 1907 "@ 1908 sex%_%? %0,%1%& 1909 sex%_ %0,%1 1910 ldh%?.x %0,%1%& 1911 ld%_.x%U1%V1 %0,%1 1912 ld%_.x%U1%V1 %0,%1" 1913 [(set_attr "type" "unary,unary,load,load,load") 1914 (set_attr "iscompact" "true,false,true,false,false") 1915 (set_attr "length" "*,*,*,4,8")]) 1916 1917(define_expand "extendhisi2" 1918 [(set (match_operand:SI 0 "dest_reg_operand" "") 1919 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))] 1920 "" 1921 "" 1922) 1923 1924;; Unary arithmetic insns 1925 1926;; We allow constant operands to enable late constant propagation, but it is 1927;; not worth while to have more than one dedicated alternative to output them - 1928;; if we are really worried about getting these the maximum benefit of all 1929;; the available alternatives, we should add an extra pass to fold such 1930;; operations to movsi. 1931 1932;; Absolute instructions 1933 1934(define_insn "*abssi2_mixed" 1935 [(set (match_operand:SI 0 "compact_register_operand" "=q") 1936 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))] 1937 "TARGET_MIXED_CODE" 1938 "abs%? %0,%1%&" 1939 [(set_attr "type" "two_cycle_core") 1940 (set_attr "iscompact" "true")]) 1941 1942(define_insn "abssi2" 1943 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w") 1944 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))] 1945 "" 1946 "abs%? %0,%1%&" 1947 [(set_attr "type" "two_cycle_core") 1948 (set_attr "length" "*,4,8") 1949 (set_attr "iscompact" "true,false,false")]) 1950 1951;; Maximum and minimum insns 1952 1953(define_insn "smaxsi3" 1954 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w") 1955 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c") 1956 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))] 1957 "" 1958 "max%? %0,%1,%2" 1959 [(set_attr "type" "two_cycle_core") 1960 (set_attr "length" "4,4,8") 1961 (set_attr "predicable" "yes,no,no")] 1962) 1963 1964(define_insn "sminsi3" 1965 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w") 1966 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c") 1967 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))] 1968 "" 1969 "min%? %0,%1,%2" 1970 [(set_attr "type" "two_cycle_core") 1971 (set_attr "length" "4,4,8") 1972 (set_attr "predicable" "yes,no,no")] 1973) 1974 1975;; Arithmetic instructions. 1976 1977; We say an insn can be conditionalized if this doesn't introduce a long 1978; immediate. We set the type such that we still have good scheduling if the 1979; insn is conditionalized. 1980; ??? It would make sense to allow introduction of long immediates, but 1981; we'd need to communicate to the ccfsm machinery the extra cost. 1982; The alternatives in the constraints still serve three purposes: 1983; - estimate insn size assuming conditional execution 1984; - guide reload to re-order the second and third operand to get a better fit. 1985; - give tentative insn type to guide scheduling 1986; N.B. "%" for commutativity doesn't help when there is another matching 1987; (but longer) alternative. 1988; We avoid letting this pattern use LP_COUNT as a register by specifying 1989; register class 'W' instead of 'w'. 1990(define_insn_and_split "*addsi3_mixed" 1991 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 1992 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq, h,!*Rsd,Rcq,Rcb,Rcq, Rcqq,Rcqq,Rcw,Rcw, Rcw, W, W,W, W,Rcqq,Rcw, W") 1993 (plus:SI (match_operand:SI 1 "register_operand" "%0, c, 0, Rcqq, 0, 0,Rcb, Rcqq, 0, 0, c, 0, c, c,0, 0, 0, 0, c") 1994 (match_operand:SI 2 "nonmemory_operand" "cL, 0, Cm1, L,CL2,Csp,CM4,RcqqK, cO, cL, 0,cCca,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))] 1995 "" 1996{ 1997 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true); 1998 return ""; 1999} 2000 "&& reload_completed && get_attr_length (insn) == 8 2001 && satisfies_constraint_I (operands[2]) 2002 && GET_CODE (PATTERN (insn)) != COND_EXEC" 2003 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))] 2004 "split_addsi (operands);" 2005 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*") 2006 (set (attr "iscompact") 2007 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2") 2008 (const_string "false") 2009 (match_operand 2 "long_immediate_operand" "") 2010 (const_string "maybe_limm")] 2011 (const_string "maybe"))) 2012 (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8") 2013 (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no") 2014 (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond") 2015]) 2016 2017;; ARCv2 MPYW and MPYUW 2018(define_expand "mulhisi3" 2019 [(set (match_operand:SI 0 "register_operand" "") 2020 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "")) 2021 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))] 2022 "TARGET_MPYW" 2023 "{ 2024 if (CONSTANT_P (operands[2])) 2025 { 2026 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2])); 2027 DONE; 2028 } 2029 }" 2030) 2031 2032(define_insn "mulhisi3_imm" 2033 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r") 2034 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r")) 2035 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))] 2036 "TARGET_MPYW" 2037 "mpyw%? %0,%1,%2" 2038 [(set_attr "length" "4,4,4,8,8") 2039 (set_attr "iscompact" "false") 2040 (set_attr "type" "mul16_em") 2041 (set_attr "predicable" "yes,no,no,yes,no") 2042 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond") 2043 ]) 2044 2045(define_insn "mulhisi3_reg" 2046 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r") 2047 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r")) 2048 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))] 2049 "TARGET_MPYW" 2050 "mpyw%? %0,%1,%2" 2051 [(set_attr "length" "*,4,4") 2052 (set_attr "iscompact" "maybe,false,false") 2053 (set_attr "type" "mul16_em") 2054 (set_attr "predicable" "yes,yes,no") 2055 (set_attr "cond" "canuse,canuse,nocond") 2056 ]) 2057 2058(define_expand "umulhisi3" 2059 [(set (match_operand:SI 0 "register_operand" "") 2060 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) 2061 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))] 2062 "TARGET_MPYW" 2063 "{ 2064 if (CONSTANT_P (operands[2])) 2065 { 2066 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2])); 2067 DONE; 2068 } 2069 }" 2070) 2071 2072(define_insn "umulhisi3_imm" 2073 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r") 2074 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r")) 2075 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))] 2076 "TARGET_MPYW" 2077 "mpyuw%? %0,%1,%2" 2078 [(set_attr "length" "4,4,4,8,8") 2079 (set_attr "iscompact" "false") 2080 (set_attr "type" "mul16_em") 2081 (set_attr "predicable" "yes,no,no,yes,no") 2082 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond") 2083 ]) 2084 2085(define_insn "umulhisi3_reg" 2086 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r") 2087 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r")) 2088 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))] 2089 "TARGET_MPYW" 2090 "mpyuw%? %0,%1,%2" 2091 [(set_attr "length" "*,4,4") 2092 (set_attr "iscompact" "maybe,false,false") 2093 (set_attr "type" "mul16_em") 2094 (set_attr "predicable" "yes,yes,no") 2095 (set_attr "cond" "canuse,canuse,nocond") 2096 ]) 2097 2098;; ARC700/ARC600/V2 multiply 2099;; SI <- SI * SI 2100 2101(define_expand "mulsi3" 2102 [(set (match_operand:SI 0 "register_operand" "") 2103 (mult:SI (match_operand:SI 1 "register_operand" "") 2104 (match_operand:SI 2 "nonmemory_operand" "")))] 2105 "TARGET_ANY_MPY" 2106{ 2107 if (TARGET_MUL64_SET) 2108 { 2109 emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2])); 2110 DONE; 2111 } 2112 else if (TARGET_MULMAC_32BY16_SET) 2113 { 2114 emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2])); 2115 DONE; 2116 } 2117}) 2118 2119(define_insn_and_split "mulsi32x16" 2120 [(set (match_operand:SI 0 "register_operand" "=w") 2121 (mult:SI (match_operand:SI 1 "register_operand" "%c") 2122 (match_operand:SI 2 "nonmemory_operand" "ci"))) 2123 (clobber (reg:DI MUL32x16_REG))] 2124 "TARGET_MULMAC_32BY16_SET" 2125 "#" 2126 "TARGET_MULMAC_32BY16_SET && reload_completed" 2127 [(const_int 0)] 2128 { 2129 if (immediate_operand (operands[2], SImode) 2130 && INTVAL (operands[2]) >= 0 2131 && INTVAL (operands[2]) <= 65535) 2132 { 2133 emit_insn (gen_umul_600 (operands[1], operands[2], 2134 gen_acc2 (), gen_acc1 ())); 2135 emit_move_insn (operands[0], gen_acc2 ()); 2136 DONE; 2137 } 2138 emit_insn (gen_umul_600 (operands[1], operands[2], 2139 gen_acc2 (), gen_acc1 ())); 2140 emit_insn (gen_mac_600 (operands[1], operands[2], 2141 gen_acc2 (), gen_acc1 ())); 2142 emit_move_insn (operands[0], gen_acc2 ()); 2143 DONE; 2144 } 2145 [(set_attr "type" "multi") 2146 (set_attr "length" "8")]) 2147 2148; mululw conditional execution without a LIMM clobbers an input register; 2149; we'd need a different pattern to describe this. 2150; To make the conditional execution valid for the LIMM alternative, we 2151; have to emit the LIMM before the register operand. 2152(define_insn "umul_600" 2153 [(set (match_operand:SI 2 "acc2_operand" "") 2154 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c") 2155 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" 2156 "c,L,Cal") 2157 (const_int 16) 2158 (const_int 0)))) 2159 (clobber (match_operand:SI 3 "acc1_operand" ""))] 2160 "TARGET_MULMAC_32BY16_SET" 2161 "mululw 0, %0, %1" 2162 [(set_attr "length" "4,4,8") 2163 (set_attr "type" "mulmac_600") 2164 (set_attr "predicable" "no") 2165 (set_attr "cond" "nocond")]) 2166 2167(define_insn "mac_600" 2168 [(set (match_operand:SI 2 "acc2_operand" "") 2169 (plus:SI 2170 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c") 2171 (ashift:SI 2172 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal") 2173 (const_int 16) 2174 (const_int 16)) 2175 (const_int 16))) 2176 (match_dup 2))) 2177 (clobber (match_operand:SI 3 "acc1_operand" ""))] 2178 "TARGET_MULMAC_32BY16_SET" 2179 "machlw%? 0, %0, %1" 2180 [(set_attr "length" "4,4,8") 2181 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600") 2182 (set_attr "predicable" "no, no, yes") 2183 (set_attr "cond" "nocond, canuse_limm, canuse")]) 2184 2185(define_insn_and_split "mulsi64" 2186 [(set (match_operand:SI 0 "register_operand" "=w") 2187 (mult:SI (match_operand:SI 1 "register_operand" "%c") 2188 (match_operand:SI 2 "nonmemory_operand" "ci"))) 2189 (clobber (reg:DI MUL64_OUT_REG))] 2190 "TARGET_MUL64_SET" 2191 "#" 2192 "TARGET_MUL64_SET && reload_completed" 2193 [(const_int 0)] 2194{ 2195 emit_insn (gen_mulsi_600 (operands[1], operands[2], 2196 gen_mlo (), gen_mhi ())); 2197 emit_move_insn (operands[0], gen_mlo ()); 2198 DONE; 2199} 2200 [(set_attr "type" "multi") 2201 (set_attr "length" "8")]) 2202 2203(define_insn "mulsi_600" 2204 [(set (match_operand:SI 2 "mlo_operand" "") 2205 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c") 2206 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal"))) 2207 (clobber (match_operand:SI 3 "mhi_operand" ""))] 2208 "TARGET_MUL64_SET" 2209; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants, 2210; using a machine code pattern that only allows "L" constraint constants. 2211; "mul64%? \t0, %0, %1%&" 2212{ 2213 if (satisfies_constraint_I (operands[1]) 2214 && !satisfies_constraint_L (operands[1])) 2215 { 2216 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */ 2217 int n = true_regnum (operands[0]); 2218 int i = INTVAL (operands[1]); 2219 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8)); 2220 asm_fprintf (asm_out_file, "\t.short %d`", 2221 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9)); 2222 return "; mul64%? \t0, %0, %1%&"; 2223 } 2224 return "mul64%? \t0, %0, %1%&"; 2225} 2226 [(set_attr "length" "*,4,4,8") 2227 (set_attr "iscompact" "maybe,false,false,false") 2228 (set_attr "type" "multi,multi,multi,multi") 2229 (set_attr "predicable" "yes,yes,no,yes") 2230 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")]) 2231 2232(define_insn_and_split "mulsidi_600" 2233 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c") 2234 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c")) 2235 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32")))) 2236 (clobber (reg:DI MUL64_OUT_REG))] 2237 "TARGET_MUL64_SET" 2238 "#" 2239 "TARGET_MUL64_SET" 2240 [(const_int 0)] 2241 "emit_insn (gen_mul64 (operands[1], operands[2])); 2242 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); 2243 DONE;" 2244 [(set_attr "type" "multi") 2245 (set_attr "length" "8")]) 2246 2247(define_insn "mul64" 2248 [(set (reg:DI MUL64_OUT_REG) 2249 (mult:DI 2250 (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c, c")) 2251 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))] 2252 "TARGET_MUL64_SET" 2253 "mul64%? \t0, %0, %1%&" 2254 [(set_attr "length" "*,4,4,8") 2255 (set_attr "iscompact" "maybe,false,false,false") 2256 (set_attr "type" "multi,multi,multi,multi") 2257 (set_attr "predicable" "yes,yes,no,yes") 2258 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")]) 2259 2260(define_insn_and_split "umulsidi_600" 2261 [(set (match_operand:DI 0 "register_operand" "=c,c, c") 2262 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c,c, c")) 2263 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "cL,L,C32")))) 2264 (clobber (reg:DI MUL64_OUT_REG))] 2265 "TARGET_MUL64_SET" 2266 "#" 2267 "TARGET_MUL64_SET" 2268 [(const_int 0)] 2269 "emit_insn (gen_mulu64 (operands[1], operands[2])); 2270 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); 2271 DONE;" 2272 [(set_attr "type" "umulti") 2273 (set_attr "length" "8")]) 2274 2275(define_insn "mulu64" 2276 [(set (reg:DI MUL64_OUT_REG) 2277 (mult:DI 2278 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c")) 2279 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))] 2280 "TARGET_MUL64_SET" 2281 "mulu64%? \t0, %0, %1%&" 2282 [(set_attr "length" "4,4,8") 2283 (set_attr "iscompact" "false") 2284 (set_attr "type" "umulti") 2285 (set_attr "predicable" "yes,no,yes") 2286 (set_attr "cond" "canuse,canuse_limm,canuse")]) 2287 2288; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w' 2289; may not be used as destination constraint. 2290 2291; The result of mpy and mpyu is the same except for flag setting (if enabled), 2292; but mpyu is faster for the standard multiplier. 2293; Note: we must make sure LP_COUNT is not one of the destination 2294; registers, since it cannot be the destination of a multi-cycle insn 2295; like MPY or MPYU. 2296(define_insn "mulsi3_700" 2297 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r") 2298 (mult:SI (match_operand:SI 1 "register_operand" "%0,c,0,0,c") 2299 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))] 2300 "TARGET_ARC700_MPY" 2301 "mpyu%? %0,%1,%2" 2302 [(set_attr "length" "4,4,4,8,8") 2303 (set_attr "type" "umulti") 2304 (set_attr "predicable" "yes,no,no,yes,no") 2305 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")]) 2306 2307; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its 2308; short variant. LP_COUNT constraints are still valid. 2309(define_insn "mulsi3_v2" 2310 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r") 2311 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c") 2312 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))] 2313 "TARGET_MULTI" 2314 "mpy%? %0,%1,%2" 2315 [(set_attr "length" "*,4,4,4,8,8") 2316 (set_attr "iscompact" "maybe,false,false,false,false,false") 2317 (set_attr "type" "umulti") 2318 (set_attr "predicable" "no,yes,no,no,yes,no") 2319 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")]) 2320 2321(define_expand "mulsidi3" 2322 [(set (match_operand:DI 0 "register_operand" "") 2323 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 2324 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] 2325 "TARGET_ANY_MPY" 2326 { 2327 if (TARGET_PLUS_MACD) 2328 { 2329 if (CONST_INT_P (operands[2])) 2330 { 2331 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2])); 2332 } 2333 else 2334 { 2335 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2])); 2336 } 2337 DONE; 2338 } 2339 if (TARGET_MPY) 2340 { 2341 operands[2] = force_reg (SImode, operands[2]); 2342 if (!register_operand (operands[0], DImode)) 2343 { 2344 rtx result = gen_reg_rtx (DImode); 2345 2346 operands[2] = force_reg (SImode, operands[2]); 2347 emit_insn (gen_mulsidi3 (result, operands[1], operands[2])); 2348 emit_move_insn (operands[0], result); 2349 DONE; 2350 } 2351 } 2352 else if (TARGET_MUL64_SET) 2353 { 2354 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2])); 2355 DONE; 2356 } 2357 else if (TARGET_MULMAC_32BY16_SET) 2358 { 2359 operands[2] = force_reg (SImode, operands[2]); 2360 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2])); 2361 DONE; 2362 } 2363 operands[2] = force_reg (SImode, operands[2]); 2364 }) 2365 2366(define_insn_and_split "mulsidi64" 2367 [(set (match_operand:DI 0 "register_operand" "=w") 2368 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c")) 2369 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci")))) 2370 (clobber (reg:DI MUL32x16_REG))] 2371 "TARGET_MULMAC_32BY16_SET" 2372 "#" 2373 "TARGET_MULMAC_32BY16_SET && reload_completed" 2374 [(const_int 0)] 2375 { 2376 rtx result_hi = gen_highpart (SImode, operands[0]); 2377 rtx result_low = gen_lowpart (SImode, operands[0]); 2378 2379 emit_insn (gen_mul64_600 (operands[1], operands[2])); 2380 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2])); 2381 emit_move_insn (result_low, gen_acc2 ()); 2382 DONE; 2383 } 2384 [(set_attr "type" "multi") 2385 (set_attr "length" "8")]) 2386 2387 2388(define_insn "mul64_600" 2389 [(set (reg:DI MUL32x16_REG) 2390 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" 2391 "c,c,c")) 2392 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand" 2393 "c,L,Cal") 2394 (const_int 16) 2395 (const_int 0)))) 2396 ] 2397 "TARGET_MULMAC_32BY16_SET" 2398 "mullw%? 0, %0, %1" 2399 [(set_attr "length" "4,4,8") 2400 (set_attr "type" "mulmac_600") 2401 (set_attr "predicable" "no,no,yes") 2402 (set_attr "cond" "nocond, canuse_limm, canuse")]) 2403 2404 2405;; ??? check if this is canonical rtl 2406(define_insn "mac64_600" 2407 [(set (reg:DI MUL32x16_REG) 2408 (plus:DI 2409 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c")) 2410 (ashift:DI 2411 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal") 2412 (const_int 16) (const_int 16)) 2413 (const_int 16))) 2414 (reg:DI MUL32x16_REG))) 2415 (set (match_operand:SI 0 "register_operand" "=w,w,w") 2416 (zero_extract:SI 2417 (plus:DI 2418 (mult:DI (sign_extend:DI (match_dup 1)) 2419 (ashift:DI 2420 (sign_extract:DI (match_dup 2) 2421 (const_int 16) (const_int 16)) 2422 (const_int 16))) 2423 (reg:DI MUL32x16_REG)) 2424 (const_int 32) (const_int 32)))] 2425 "TARGET_MULMAC_32BY16_SET" 2426 "machlw%? %0, %1, %2" 2427 [(set_attr "length" "4,4,8") 2428 (set_attr "type" "mulmac_600") 2429 (set_attr "predicable" "no,no,yes") 2430 (set_attr "cond" "nocond, canuse_limm, canuse")]) 2431 2432 2433;; DI <- DI(signed SI) * DI(signed SI) 2434(define_insn_and_split "mulsidi3_700" 2435 [(set (match_operand:DI 0 "register_operand" "=&r") 2436 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c")) 2437 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] 2438 "TARGET_MPY && !TARGET_PLUS_MACD" 2439 "#" 2440 "&& reload_completed" 2441 [(const_int 0)] 2442{ 2443 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 2444 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 2445 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo); 2446 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi); 2447 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2])); 2448 emit_insn (gen_mulsi3 (l0, operands[1], operands[2])); 2449 DONE; 2450} 2451 [(set_attr "type" "multi") 2452 (set_attr "length" "8")]) 2453 2454(define_insn "mulsi3_highpart" 2455 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r") 2456 (truncate:SI 2457 (lshiftrt:DI 2458 (mult:DI 2459 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c")) 2460 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i"))) 2461 (const_int 32))))] 2462 "TARGET_MPY" 2463 "mpy%+%? %0,%1,%2" 2464 [(set_attr "length" "4,4,8,8") 2465 (set_attr "type" "multi") 2466 (set_attr "predicable" "yes,no,yes,no") 2467 (set_attr "cond" "canuse,nocond,canuse,nocond")]) 2468 2469; Note that mpyhu has the same latency as mpy / mpyh, 2470; thus we use the type multi. 2471(define_insn "*umulsi3_highpart_i" 2472 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r") 2473 (truncate:SI 2474 (lshiftrt:DI 2475 (mult:DI 2476 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c")) 2477 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i"))) 2478 (const_int 32))))] 2479 "TARGET_MPY" 2480 "mpy%+u%? %0,%1,%2" 2481 [(set_attr "length" "4,4,8,8") 2482 (set_attr "type" "multi") 2483 (set_attr "predicable" "yes,no,yes,no") 2484 (set_attr "cond" "canuse,nocond,canuse,nocond")]) 2485 2486;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we 2487;; need a separate pattern for immediates 2488;; ??? This is fine for combine, but not for reload. 2489(define_insn "umulsi3_highpart_int" 2490 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r") 2491 (truncate:SI 2492 (lshiftrt:DI 2493 (mult:DI 2494 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c")) 2495 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal")) 2496 (const_int 32))))] 2497 "TARGET_MPY" 2498 "mpy%+u%? %0,%1,%2" 2499 [(set_attr "length" "4,4,4,8,8") 2500 (set_attr "type" "multi") 2501 (set_attr "predicable" "yes,no,no,yes,no") 2502 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")]) 2503 2504(define_expand "umulsi3_highpart" 2505 [(set (match_operand:SI 0 "general_operand" "") 2506 (truncate:SI 2507 (lshiftrt:DI 2508 (mult:DI 2509 (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 2510 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))) 2511 (const_int 32))))] 2512 "TARGET_MPY" 2513 " 2514{ 2515 rtx target = operands[0]; 2516 2517 if (!register_operand (target, SImode)) 2518 target = gen_reg_rtx (SImode); 2519 2520 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 2521 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode, 2522 operands[2], SImode); 2523 else if (!immediate_operand (operands[2], SImode)) 2524 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]); 2525 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2])); 2526 if (target != operands[0]) 2527 emit_move_insn (operands[0], target); 2528 DONE; 2529}") 2530 2531(define_expand "umulsidi3" 2532 [(set (match_operand:DI 0 "register_operand" "") 2533 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 2534 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] 2535 "TARGET_ANY_MPY" 2536{ 2537 if (TARGET_PLUS_MACD) 2538 { 2539 if (CONST_INT_P (operands[2])) 2540 { 2541 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2])); 2542 } 2543 else 2544 { 2545 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2])); 2546 } 2547 DONE; 2548 } 2549 if (TARGET_MPY) 2550 { 2551 operands[2] = force_reg (SImode, operands[2]); 2552 if (!register_operand (operands[0], DImode)) 2553 { 2554 rtx result = gen_reg_rtx (DImode); 2555 2556 emit_insn (gen_umulsidi3 (result, operands[1], operands[2])); 2557 emit_move_insn (operands[0], result); 2558 DONE; 2559 } 2560 } 2561 else if (TARGET_MUL64_SET) 2562 { 2563 operands[2] = force_reg (SImode, operands[2]); 2564 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2])); 2565 DONE; 2566 } 2567 else if (TARGET_MULMAC_32BY16_SET) 2568 { 2569 operands[2] = force_reg (SImode, operands[2]); 2570 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2])); 2571 DONE; 2572 } 2573 else 2574 { 2575 gcc_unreachable (); 2576 } 2577}) 2578 2579(define_insn_and_split "umulsidi64" 2580 [(set (match_operand:DI 0 "register_operand" "=w") 2581 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) 2582 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci")))) 2583 (clobber (reg:DI MUL32x16_REG))] 2584 "TARGET_MULMAC_32BY16_SET" 2585 "#" 2586 "TARGET_MULMAC_32BY16_SET && reload_completed" 2587 [(const_int 0)] 2588 { 2589 rtx result_hi; 2590 rtx result_low; 2591 2592 result_hi = gen_highpart (SImode, operands[0]); 2593 result_low = gen_lowpart (SImode, operands[0]); 2594 2595 emit_insn (gen_umul64_600 (operands[1], operands[2])); 2596 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2])); 2597 emit_move_insn (result_low, gen_acc2 ()); 2598 DONE; 2599 } 2600 [(set_attr "type" "multi") 2601 (set_attr "length" "8")]) 2602 2603(define_insn "umul64_600" 2604 [(set (reg:DI MUL32x16_REG) 2605 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" 2606 "c,c,c")) 2607 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand" 2608 "c,L,Cal") 2609 (const_int 16) 2610 (const_int 0)))) 2611 ] 2612 "TARGET_MULMAC_32BY16_SET" 2613 "mululw 0, %0, %1" 2614 [(set_attr "length" "4,4,8") 2615 (set_attr "type" "mulmac_600") 2616 (set_attr "predicable" "no") 2617 (set_attr "cond" "nocond")]) 2618 2619 2620(define_insn "umac64_600" 2621 [(set (reg:DI MUL32x16_REG) 2622 (plus:DI 2623 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c")) 2624 (ashift:DI 2625 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal") 2626 (const_int 16) (const_int 16)) 2627 (const_int 16))) 2628 (reg:DI MUL32x16_REG))) 2629 (set (match_operand:SI 0 "register_operand" "=w,w,w") 2630 (zero_extract:SI 2631 (plus:DI 2632 (mult:DI (zero_extend:DI (match_dup 1)) 2633 (ashift:DI 2634 (zero_extract:DI (match_dup 2) 2635 (const_int 16) (const_int 16)) 2636 (const_int 16))) 2637 (reg:DI MUL32x16_REG)) 2638 (const_int 32) (const_int 32)))] 2639 "TARGET_MULMAC_32BY16_SET" 2640 "machulw%? %0, %1, %2" 2641 [(set_attr "length" "4,4,8") 2642 (set_attr "type" "mulmac_600") 2643 (set_attr "predicable" "no,no,yes") 2644 (set_attr "cond" "nocond, canuse_limm, canuse")]) 2645 2646;; DI <- DI(unsigned SI) * DI(unsigned SI) 2647(define_insn_and_split "umulsidi3_700" 2648 [(set (match_operand:DI 0 "dest_reg_operand" "=&r") 2649 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) 2650 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] 2651 "TARGET_MPY && !TARGET_PLUS_MACD" 2652 "#" 2653 "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed" 2654 [(const_int 0)] 2655{ 2656 int hi = !TARGET_BIG_ENDIAN; 2657 int lo = !hi; 2658 rtx l0 = operand_subword (operands[0], lo, 0, DImode); 2659 rtx h0 = operand_subword (operands[0], hi, 0, DImode); 2660 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2])); 2661 emit_insn (gen_mulsi3 (l0, operands[1], operands[2])); 2662 DONE; 2663} 2664 [(set_attr "type" "umulti") 2665 (set_attr "length" "8")]) 2666 2667(define_expand "addsi3" 2668 [(set (match_operand:SI 0 "dest_reg_operand" "") 2669 (plus:SI (match_operand:SI 1 "register_operand" "") 2670 (match_operand:SI 2 "nonmemory_operand" "")))] 2671 "" 2672 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false)) 2673 { 2674 operands[2]=force_reg(SImode, operands[2]); 2675 } 2676 ") 2677 2678(define_expand "adddi3" 2679 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "") 2680 (plus:DI (match_operand:DI 1 "register_operand" "") 2681 (match_operand:DI 2 "nonmemory_operand" ""))) 2682 (clobber (reg:CC CC_REG))])] 2683 "" 2684{}) 2685 2686; This assumes that there can be no strictly partial overlap between 2687; operands[1] and operands[2]. 2688(define_insn_and_split "*adddi3_i" 2689 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w") 2690 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c") 2691 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i"))) 2692 (clobber (reg:CC CC_REG))] 2693 "" 2694 "#" 2695 "reload_completed" 2696 [(const_int 0)] 2697{ 2698 int hi = !TARGET_BIG_ENDIAN; 2699 int lo = !hi; 2700 rtx l0 = operand_subword (operands[0], lo, 0, DImode); 2701 rtx h0 = operand_subword (operands[0], hi, 0, DImode); 2702 rtx l1 = operand_subword (operands[1], lo, 0, DImode); 2703 rtx h1 = operand_subword (operands[1], hi, 0, DImode); 2704 rtx l2 = operand_subword (operands[2], lo, 0, DImode); 2705 rtx h2 = operand_subword (operands[2], hi, 0, DImode); 2706 2707 2708 if (l2 == const0_rtx) 2709 { 2710 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1)) 2711 emit_move_insn (l0, l1); 2712 emit_insn (gen_addsi3 (h0, h1, h2)); 2713 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1)) 2714 emit_move_insn (l0, l1); 2715 DONE; 2716 } 2717 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0 2718 && INTVAL (operands[2]) >= -0x7fffffff) 2719 { 2720 emit_insn (gen_subdi3_i (operands[0], operands[1], 2721 GEN_INT (-INTVAL (operands[2])))); 2722 DONE; 2723 } 2724 if (rtx_equal_p (l0, h1)) 2725 { 2726 if (h2 != const0_rtx) 2727 emit_insn (gen_addsi3 (h0, h1, h2)); 2728 else if (!rtx_equal_p (h0, h1)) 2729 emit_move_insn (h0, h1); 2730 emit_insn (gen_add_f (l0, l1, l2)); 2731 emit_insn 2732 (gen_rtx_COND_EXEC 2733 (VOIDmode, 2734 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)), 2735 gen_rtx_SET (h0, plus_constant (SImode, h0, 1)))); 2736 DONE; 2737 } 2738 emit_insn (gen_add_f (l0, l1, l2)); 2739 emit_insn (gen_adc (h0, h1, h2)); 2740 DONE; 2741} 2742 [(set_attr "cond" "clob") 2743 (set_attr "type" "binary") 2744 (set_attr "length" "16,16,20")]) 2745 2746(define_insn "add_f" 2747 [(set (reg:CC_C CC_REG) 2748 (compare:CC_C 2749 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c") 2750 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal")) 2751 (match_dup 1))) 2752 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w") 2753 (plus:SI (match_dup 1) (match_dup 2)))] 2754 "" 2755 "add.f %0,%1,%2" 2756 [(set_attr "cond" "set") 2757 (set_attr "type" "compare") 2758 (set_attr "length" "4,4,8")]) 2759 2760(define_insn "*add_f_2" 2761 [(set (reg:CC_C CC_REG) 2762 (compare:CC_C 2763 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c") 2764 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal")) 2765 (match_dup 2))) 2766 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w") 2767 (plus:SI (match_dup 1) (match_dup 2)))] 2768 "" 2769 "add.f %0,%1,%2" 2770 [(set_attr "cond" "set") 2771 (set_attr "type" "compare") 2772 (set_attr "length" "4,4,8")]) 2773 2774; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end 2775; needlessly prioritizing the matching constraint. 2776; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional 2777; execution is used where possible. 2778(define_insn_and_split "adc" 2779 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w") 2780 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0)) 2781 (match_operand:SI 1 "nonmemory_operand" 2782 "%c,0,c,0,cCal")) 2783 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))] 2784 "register_operand (operands[1], SImode) 2785 || register_operand (operands[2], SImode)" 2786 "@ 2787 adc %0,%1,%2 2788 add.cs %0,%1,1 2789 adc %0,%1,%2 2790 adc %0,%1,%2 2791 adc %0,%1,%2" 2792 ; if we have a bad schedule after sched2, split. 2793 "reload_completed 2794 && !optimize_size && (!TARGET_ARC600_FAMILY) 2795 && arc_scheduling_not_expected () 2796 && arc_sets_cc_p (prev_nonnote_insn (insn)) 2797 /* If next comes a return or other insn that needs a delay slot, 2798 expect the adc to get into the delay slot. */ 2799 && next_nonnote_insn (insn) 2800 && !arc_need_delay (next_nonnote_insn (insn)) 2801 /* Restore operands before emitting. */ 2802 && (extract_insn_cached (insn), 1)" 2803 [(set (match_dup 0) (match_dup 3)) 2804 (cond_exec 2805 (ltu (reg:CC_C CC_REG) (const_int 0)) 2806 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))] 2807 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);" 2808 [(set_attr "cond" "use") 2809 (set_attr "type" "cc_arith") 2810 (set_attr "length" "4,4,4,4,8")]) 2811 2812; combiner-splitter cmp / scc -> cmp / adc 2813(define_split 2814 [(set (match_operand:SI 0 "dest_reg_operand" "") 2815 (gtu:SI (match_operand:SI 1 "register_operand" "") 2816 (match_operand:SI 2 "register_operand" ""))) 2817 (clobber (reg CC_REG))] 2818 "" 2819 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1))) 2820 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))]) 2821 2822; combine won't work when an intermediate result is used later... 2823; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2 2824(define_peephole2 2825 [(set (match_operand:SI 0 "dest_reg_operand" "") 2826 (plus:SI (match_operand:SI 1 "register_operand" "") 2827 (match_operand:SI 2 "nonmemory_operand" ""))) 2828 (set (reg:CC_C CC_REG) 2829 (compare:CC_C (match_dup 0) 2830 (match_operand:SI 3 "nonmemory_operand" "")))] 2831 "rtx_equal_p (operands[1], operands[3]) 2832 || rtx_equal_p (operands[2], operands[3])" 2833 [(parallel 2834 [(set (reg:CC_C CC_REG) 2835 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1))) 2836 (set (match_dup 0) 2837 (plus:SI (match_dup 1) (match_dup 2)))])]) 2838 2839; ??? need to delve into combine to find out why this is not useful. 2840; We'd like to be able to grok various C idioms for carry bit usage. 2841;(define_insn "*adc_0" 2842; [(set (match_operand:SI 0 "dest_reg_operand" "=w") 2843; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0)) 2844; (match_operand:SI 1 "register_operand" "c")))] 2845; "" 2846; "adc %0,%1,0" 2847; [(set_attr "cond" "use") 2848; (set_attr "type" "cc_arith") 2849; (set_attr "length" "4")]) 2850; 2851;(define_split 2852; [(set (match_operand:SI 0 "dest_reg_operand" "=w") 2853; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c") 2854; (match_operand:SI 2 "register_operand" "c")) 2855; (match_operand:SI 3 "register_operand" "c"))) 2856; (clobber (reg CC_REG))] 2857; "" 2858; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1))) 2859; (set (match_dup 0) 2860; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0)) 2861; (match_dup 3)))]) 2862 2863(define_expand "subsi3" 2864 [(set (match_operand:SI 0 "dest_reg_operand" "") 2865 (minus:SI (match_operand:SI 1 "nonmemory_operand" "") 2866 (match_operand:SI 2 "nonmemory_operand" "")))] 2867 "" 2868 " 2869{ 2870 int c = 1; 2871 2872 if (!register_operand (operands[2], SImode)) 2873 { 2874 operands[1] = force_reg (SImode, operands[1]); 2875 c = 2; 2876 } 2877 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false)) 2878 operands[c] = force_reg (SImode, operands[c]); 2879}") 2880 2881; the casesi expander might generate a sub of zero, so we have to recognize it. 2882; combine should make such an insn go away. 2883(define_insn_and_split "subsi3_insn" 2884 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,Rcw,w,w,w, w, w, w") 2885 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,Rcqq, 0, cL,c,L,I,Cal,Cal, c") 2886 (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq, c, 0,c,c,0, 0, c,Cal")))] 2887 "register_operand (operands[1], SImode) 2888 || register_operand (operands[2], SImode)" 2889 "@ 2890 sub%? %0,%1,%2%& 2891 sub%? %0,%1,%2%& 2892 sub%? %0,%1,%2 2893 rsub%? %0,%2,%1 2894 sub %0,%1,%2 2895 rsub %0,%2,%1 2896 rsub %0,%2,%1 2897 rsub%? %0,%2,%1 2898 rsub %0,%2,%1 2899 sub %0,%1,%2" 2900 "reload_completed && get_attr_length (insn) == 8 2901 && satisfies_constraint_I (operands[1]) 2902 && GET_CODE (PATTERN (insn)) != COND_EXEC" 2903 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))] 2904 "split_subsi (operands);" 2905 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false") 2906 (set_attr "length" "*,*,4,4,4,4,4,8,8,8") 2907 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no") 2908 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond") 2909 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") 2910 ]) 2911 2912(define_expand "subdi3" 2913 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "") 2914 (minus:DI (match_operand:DI 1 "nonmemory_operand" "") 2915 (match_operand:DI 2 "nonmemory_operand" ""))) 2916 (clobber (reg:CC CC_REG))])] 2917 "" 2918{ 2919 if (!register_operand (operands[2], DImode)) 2920 operands[1] = force_reg (DImode, operands[1]); 2921}) 2922 2923(define_insn_and_split "subdi3_i" 2924 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w") 2925 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i") 2926 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c"))) 2927 (clobber (reg:CC CC_REG))] 2928 "register_operand (operands[1], DImode) 2929 || register_operand (operands[2], DImode)" 2930 "#" 2931 "reload_completed" 2932 [(const_int 0)] 2933{ 2934 int hi = !TARGET_BIG_ENDIAN; 2935 int lo = !hi; 2936 rtx l0 = operand_subword (operands[0], lo, 0, DImode); 2937 rtx h0 = operand_subword (operands[0], hi, 0, DImode); 2938 rtx l1 = operand_subword (operands[1], lo, 0, DImode); 2939 rtx h1 = operand_subword (operands[1], hi, 0, DImode); 2940 rtx l2 = operand_subword (operands[2], lo, 0, DImode); 2941 rtx h2 = operand_subword (operands[2], hi, 0, DImode); 2942 2943 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2)) 2944 { 2945 h1 = simplify_gen_binary (MINUS, SImode, h1, h2); 2946 if (!rtx_equal_p (h0, h1)) 2947 emit_insn (gen_rtx_SET (h0, h1)); 2948 emit_insn (gen_sub_f (l0, l1, l2)); 2949 emit_insn 2950 (gen_rtx_COND_EXEC 2951 (VOIDmode, 2952 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)), 2953 gen_rtx_SET (h0, plus_constant (SImode, h0, -1)))); 2954 DONE; 2955 } 2956 emit_insn (gen_sub_f (l0, l1, l2)); 2957 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG))); 2958 DONE; 2959} 2960 [(set_attr "cond" "clob") 2961 (set_attr "length" "16,16,16,20,20")]) 2962 2963(define_insn "*sbc_0" 2964 [(set (match_operand:SI 0 "dest_reg_operand" "=w") 2965 (minus:SI (match_operand:SI 1 "register_operand" "c") 2966 (ltu:SI (match_operand:CC_C 2 "cc_use_register") 2967 (const_int 0))))] 2968 "" 2969 "sbc %0,%1,0" 2970 [(set_attr "cond" "use") 2971 (set_attr "type" "cc_arith") 2972 (set_attr "length" "4")]) 2973 2974; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end 2975; needlessly prioritizing the matching constraint. 2976; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution 2977; is used where possible. 2978(define_insn_and_split "sbc" 2979 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w") 2980 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand" 2981 "c,0,c,0,cCal") 2982 (ltu:SI (match_operand:CC_C 3 "cc_use_register") 2983 (const_int 0))) 2984 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))] 2985 "register_operand (operands[1], SImode) 2986 || register_operand (operands[2], SImode)" 2987 "@ 2988 sbc %0,%1,%2 2989 sub.cs %0,%1,1 2990 sbc %0,%1,%2 2991 sbc %0,%1,%2 2992 sbc %0,%1,%2" 2993 ; if we have a bad schedule after sched2, split. 2994 "reload_completed 2995 && !optimize_size && (!TARGET_ARC600_FAMILY) 2996 && arc_scheduling_not_expected () 2997 && arc_sets_cc_p (prev_nonnote_insn (insn)) 2998 /* If next comes a return or other insn that needs a delay slot, 2999 expect the adc to get into the delay slot. */ 3000 && next_nonnote_insn (insn) 3001 && !arc_need_delay (next_nonnote_insn (insn)) 3002 /* Restore operands before emitting. */ 3003 && (extract_insn_cached (insn), 1)" 3004 [(set (match_dup 0) (match_dup 4)) 3005 (cond_exec 3006 (ltu (reg:CC_C CC_REG) (const_int 0)) 3007 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))] 3008 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);" 3009 [(set_attr "cond" "use") 3010 (set_attr "type" "cc_arith") 3011 (set_attr "length" "4,4,4,4,8")]) 3012 3013(define_insn "sub_f" 3014 [(set (reg:CC CC_REG) 3015 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal") 3016 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c"))) 3017 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w") 3018 (minus:SI (match_dup 1) (match_dup 2)))] 3019 "register_operand (operands[1], SImode) 3020 || register_operand (operands[2], SImode)" 3021 "@ 3022 sub.f %0,%1,%2 3023 rsub.f %0,%2,%1 3024 sub.f %0,%1,%2 3025 rsub.f %0,%2,%1 3026 sub.f %0,%1,%2 3027 sub.f %0,%1,%2" 3028 [(set_attr "type" "compare") 3029 (set_attr "length" "4,4,4,4,8,8")]) 3030 3031; combine won't work when an intermediate result is used later... 3032; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2 3033(define_peephole2 3034 [(set (reg:CC CC_REG) 3035 (compare:CC (match_operand:SI 1 "register_operand" "") 3036 (match_operand:SI 2 "nonmemory_operand" ""))) 3037 (set (match_operand:SI 0 "dest_reg_operand" "") 3038 (minus:SI (match_dup 1) (match_dup 2)))] 3039 "" 3040 [(parallel 3041 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2))) 3042 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])]) 3043 3044(define_peephole2 3045 [(set (reg:CC CC_REG) 3046 (compare:CC (match_operand:SI 1 "register_operand" "") 3047 (match_operand:SI 2 "nonmemory_operand" ""))) 3048 (set (match_operand 3 "" "") (match_operand 4 "" "")) 3049 (set (match_operand:SI 0 "dest_reg_operand" "") 3050 (minus:SI (match_dup 1) (match_dup 2)))] 3051 "!reg_overlap_mentioned_p (operands[3], operands[1]) 3052 && !reg_overlap_mentioned_p (operands[3], operands[2]) 3053 && !reg_overlap_mentioned_p (operands[0], operands[4]) 3054 && !reg_overlap_mentioned_p (operands[0], operands[3])" 3055 [(parallel 3056 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2))) 3057 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 3058 (set (match_dup 3) (match_dup 4))]) 3059 3060(define_insn "*add_n" 3061 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r") 3062 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r") 3063 (match_operand:SI 2 "_2_4_8_operand" "")) 3064 (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] 3065 "" 3066 "add%z2%?\\t%0,%3,%1%&" 3067 [(set_attr "type" "shift") 3068 (set_attr "length" "*,4,8") 3069 (set_attr "predicable" "yes,no,no") 3070 (set_attr "cond" "canuse,nocond,nocond") 3071 (set_attr "iscompact" "maybe,false,false")]) 3072 3073;; N.B. sub[123] has the operands of the MINUS in the opposite order from 3074;; what synth_mult likes. 3075(define_insn "*sub_n" 3076 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3077 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") 3078 (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c") 3079 (match_operand:SI 3 "_1_2_3_operand" ""))))] 3080 "" 3081 "sub%c3%? %0,%1,%2" 3082 [(set_attr "type" "shift") 3083 (set_attr "length" "4,4,8") 3084 (set_attr "predicable" "yes,no,no") 3085 (set_attr "cond" "canuse,nocond,nocond") 3086 (set_attr "iscompact" "false")]) 3087 3088(define_insn "*sub_n" 3089 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3090 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") 3091 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c") 3092 (match_operand:SI 3 "_2_4_8_operand" ""))))] 3093 "" 3094 "sub%z3%? %0,%1,%2" 3095 [(set_attr "type" "shift") 3096 (set_attr "length" "4,4,8") 3097 (set_attr "predicable" "yes,no,no") 3098 (set_attr "cond" "canuse,nocond,nocond") 3099 (set_attr "iscompact" "false")]) 3100 3101; ??? check if combine matches this. 3102(define_insn "*bset" 3103 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3104 (ior:SI (ashift:SI (const_int 1) 3105 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")) 3106 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))] 3107 "" 3108 "bset%? %0,%2,%1" 3109 [(set_attr "length" "4,4,8") 3110 (set_attr "predicable" "yes,no,no") 3111 (set_attr "cond" "canuse,nocond,nocond")] 3112) 3113 3114; ??? check if combine matches this. 3115(define_insn "*bxor" 3116 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3117 (xor:SI (ashift:SI (const_int 1) 3118 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")) 3119 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))] 3120 "" 3121 "bxor%? %0,%2,%1" 3122 [(set_attr "length" "4,4,8") 3123 (set_attr "predicable" "yes,no,no") 3124 (set_attr "cond" "canuse,nocond,nocond")] 3125) 3126 3127; ??? check if combine matches this. 3128(define_insn "*bclr" 3129 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3130 (and:SI (not:SI (ashift:SI (const_int 1) 3131 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))) 3132 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))] 3133 "" 3134 "bclr%? %0,%2,%1" 3135 [(set_attr "length" "4,4,8") 3136 (set_attr "predicable" "yes,no,no") 3137 (set_attr "cond" "canuse,nocond,nocond")] 3138) 3139 3140; ??? FIXME: find combine patterns for bmsk. 3141 3142;;Following are the define_insns added for the purpose of peephole2's 3143 3144; see also iorsi3 for use with constant bit number. 3145(define_insn "*bset_insn" 3146 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3147 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal") 3148 (ashift:SI (const_int 1) 3149 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ] 3150 "" 3151 "@ 3152 bset%? %0,%1,%2 ;;peep2, constr 1 3153 bset %0,%1,%2 ;;peep2, constr 2 3154 bset %0,%1,%2 ;;peep2, constr 3" 3155 [(set_attr "length" "4,4,8") 3156 (set_attr "predicable" "yes,no,no") 3157 (set_attr "cond" "canuse,nocond,nocond")] 3158) 3159 3160; see also xorsi3 for use with constant bit number. 3161(define_insn "*bxor_insn" 3162 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3163 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal") 3164 (ashift:SI (const_int 1) 3165 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ] 3166 "" 3167 "@ 3168 bxor%? %0,%1,%2 3169 bxor %0,%1,%2 3170 bxor %0,%1,%2" 3171 [(set_attr "length" "4,4,8") 3172 (set_attr "predicable" "yes,no,no") 3173 (set_attr "cond" "canuse,nocond,nocond")] 3174) 3175 3176; see also andsi3 for use with constant bit number. 3177(define_insn "*bclr_insn" 3178 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3179 (and:SI (not:SI (ashift:SI (const_int 1) 3180 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r"))) 3181 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))] 3182 "" 3183 "@ 3184 bclr%? %0,%1,%2 3185 bclr %0,%1,%2 3186 bclr %0,%1,%2" 3187 [(set_attr "length" "4,4,8") 3188 (set_attr "predicable" "yes,no,no") 3189 (set_attr "cond" "canuse,nocond,nocond")] 3190) 3191 3192; see also andsi3 for use with constant bit number. 3193(define_insn "*bmsk_insn" 3194 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") 3195 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal") 3196 (plus:SI (ashift:SI (const_int 1) 3197 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r") 3198 (const_int 1))) 3199 (const_int -1))))] 3200 "" 3201 "@ 3202 bmsk%? %0,%1,%2 3203 bmsk %0,%1,%2 3204 bmsk %0,%1,%2" 3205 [(set_attr "length" "4,4,8") 3206 (set_attr "predicable" "yes,no,no") 3207 (set_attr "cond" "canuse,nocond,nocond")] 3208) 3209 3210;;Instructions added for peephole2s end 3211 3212;; Boolean instructions. 3213 3214(define_expand "andsi3" 3215 [(set (match_operand:SI 0 "dest_reg_operand" "") 3216 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 3217 (match_operand:SI 2 "nonmemory_operand" "")))] 3218 "" 3219 "if (!satisfies_constraint_Cux (operands[2])) 3220 operands[1] = force_reg (SImode, operands[1]); 3221 ") 3222 3223(define_insn "andsi3_i" 3224 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W") 3225 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o") 3226 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] 3227 "(register_operand (operands[1], SImode) 3228 && nonmemory_operand (operands[2], SImode)) 3229 || (memory_operand (operands[1], SImode) 3230 && satisfies_constraint_Cux (operands[2]))" 3231{ 3232 switch (which_alternative) 3233 { 3234 case 0: case 5: case 10: case 11: case 16: case 17: case 18: 3235 return "and%? %0,%1,%2%&"; 3236 case 1: case 6: 3237 return "and%? %0,%2,%1%&"; 3238 case 2: 3239 return "bmsk%? %0,%1,%Z2%&"; 3240 case 7: case 12: 3241 if (satisfies_constraint_C2p (operands[2])) 3242 { 3243 operands[2] = GEN_INT ((~INTVAL (operands[2]))); 3244 return "bmskn%? %0,%1,%Z2%&"; 3245 } 3246 else 3247 { 3248 return "bmsk%? %0,%1,%Z2%&"; 3249 } 3250 case 3: case 8: case 13: 3251 return "bclr%? %0,%1,%M2%&"; 3252 case 4: 3253 return (INTVAL (operands[2]) == 0xff 3254 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&"); 3255 case 9: case 14: return \"bic%? %0,%1,%n2-1\"; 3256 case 15: 3257 return "movb.cl %0,%1,%p2,%p2,%s2"; 3258 3259 case 19: 3260 const char *tmpl; 3261 3262 if (satisfies_constraint_Ucm (operands[1])) 3263 tmpl = (INTVAL (operands[2]) == 0xff 3264 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1"); 3265 else 3266 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1"; 3267 3268 if (TARGET_BIG_ENDIAN) 3269 { 3270 rtx xop[2]; 3271 3272 xop[0] = operands[0]; 3273 xop[1] = adjust_address (operands[1], QImode, 3274 INTVAL (operands[2]) == 0xff ? 3 : 2); 3275 output_asm_insn (tmpl, xop); 3276 return ""; 3277 } 3278 return tmpl; 3279 default: 3280 gcc_unreachable (); 3281 } 3282} 3283 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false") 3284 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load") 3285 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*") 3286 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no") 3287 (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) 3288 3289; combiner splitter, pattern found in ldtoa.c . 3290; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1 3291(define_split 3292 [(set (reg:CC_Z CC_REG) 3293 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "") 3294 (match_operand 1 "const_int_operand" "")) 3295 (match_operand 2 "const_int_operand" ""))) 3296 (clobber (match_operand:SI 3 "register_operand" ""))] 3297 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0" 3298 [(set (match_dup 3) 3299 (plus:SI (match_dup 0) (match_dup 4))) 3300 (set (reg:CC_Z CC_REG) 3301 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1)) 3302 (const_int 0)))] 3303 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));") 3304 3305;;bic define_insn that allows limm to be the first operand 3306(define_insn "*bicsi3_insn" 3307 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w") 3308 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c")) 3309 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))] 3310 "" 3311 "@ 3312 bic%? %0, %2, %1%& ;;constraint 0 3313 bic%? %0,%2,%1 ;;constraint 1 3314 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ??? 3315 bic%? %0,%2,%1 ;;constraint 3, FIXME: will it ever get generated ??? 3316 bic %0,%2,%1 ;;constraint 4 3317 bic %0,%2,%1 ;;constraint 5, FIXME: will it ever get generated ??? 3318 bic %0,%2,%1 ;;constraint 6" 3319 [(set_attr "length" "*,4,4,8,4,8,8") 3320 (set_attr "iscompact" "maybe, false, false, false, false, false, false") 3321 (set_attr "predicable" "no,yes,no,yes,no,no,no") 3322 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")]) 3323 3324(define_insn "iorsi3" 3325 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w") 3326 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c") 3327 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))] 3328 "" 3329 "* 3330 switch (which_alternative) 3331 { 3332 case 0: case 3: case 6: case 7: case 9: case 10: case 11: 3333 return \"or%? %0,%1,%2%&\"; 3334 case 1: case 4: 3335 return \"or%? %0,%2,%1%&\"; 3336 case 2: case 5: case 8: 3337 return \"bset%? %0,%1,%z2%&\"; 3338 default: 3339 gcc_unreachable (); 3340 }" 3341 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false") 3342 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8") 3343 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no") 3344 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")]) 3345 3346(define_insn "xorsi3" 3347 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w") 3348 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c") 3349 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))] 3350 "" 3351 "* 3352 switch (which_alternative) 3353 { 3354 case 0: case 2: case 5: case 6: case 8: case 9: case 10: 3355 return \"xor%? %0,%1,%2%&\"; 3356 case 1: case 3: 3357 return \"xor%? %0,%2,%1%&\"; 3358 case 4: case 7: 3359 return \"bxor%? %0,%1,%z2\"; 3360 default: 3361 gcc_unreachable (); 3362 } 3363 " 3364 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false") 3365 (set_attr "type" "binary") 3366 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8") 3367 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no") 3368 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")]) 3369 3370(define_insn "negsi2" 3371 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w") 3372 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))] 3373 "" 3374 "neg%? %0,%1%&" 3375 [(set_attr "type" "unary") 3376 (set_attr "iscompact" "maybe,true,false,false") 3377 (set_attr "predicable" "no,no,yes,no")]) 3378 3379(define_insn "one_cmplsi2" 3380 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") 3381 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))] 3382 "" 3383 "not%? %0,%1%&" 3384 [(set_attr "type" "unary,unary") 3385 (set_attr "iscompact" "true,false")]) 3386 3387(define_insn_and_split "one_cmpldi2" 3388 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w") 3389 (not:DI (match_operand:DI 1 "register_operand" "q,c")))] 3390 "" 3391 "#" 3392 "&& reload_completed" 3393 [(set (match_dup 2) (not:SI (match_dup 3))) 3394 (set (match_dup 4) (not:SI (match_dup 5)))] 3395{ 3396 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1); 3397 3398 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode); 3399 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode); 3400 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode); 3401 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode); 3402} 3403 [(set_attr "type" "unary,unary") 3404 (set_attr "cond" "nocond,nocond") 3405 (set_attr "length" "4,8")]) 3406 3407;; Shift instructions. 3408 3409(define_expand "ashlsi3" 3410 [(set (match_operand:SI 0 "dest_reg_operand" "") 3411 (ashift:SI (match_operand:SI 1 "register_operand" "") 3412 (match_operand:SI 2 "nonmemory_operand" "")))] 3413 "" 3414 " 3415{ 3416 if (!TARGET_BARREL_SHIFTER) 3417 { 3418 emit_shift (ASHIFT, operands[0], operands[1], operands[2]); 3419 DONE; 3420 } 3421}") 3422 3423(define_expand "ashrsi3" 3424 [(set (match_operand:SI 0 "dest_reg_operand" "") 3425 (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 3426 (match_operand:SI 2 "nonmemory_operand" "")))] 3427 "" 3428 " 3429{ 3430 if (!TARGET_BARREL_SHIFTER) 3431 { 3432 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]); 3433 DONE; 3434 } 3435}") 3436 3437(define_expand "lshrsi3" 3438 [(set (match_operand:SI 0 "dest_reg_operand" "") 3439 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 3440 (match_operand:SI 2 "nonmemory_operand" "")))] 3441 "" 3442 " 3443{ 3444 if (!TARGET_BARREL_SHIFTER) 3445 { 3446 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]); 3447 DONE; 3448 } 3449}") 3450 3451(define_insn "shift_si3" 3452 [(set (match_operand:SI 0 "dest_reg_operand" "=r") 3453 (match_operator:SI 3 "shift4_operator" 3454 [(match_operand:SI 1 "register_operand" "0") 3455 (match_operand:SI 2 "const_int_operand" "n")])) 3456 (clobber (match_scratch:SI 4 "=&r")) 3457 (clobber (reg:CC CC_REG)) 3458 ] 3459 "!TARGET_BARREL_SHIFTER" 3460 "* return output_shift (operands);" 3461 [(set_attr "type" "shift") 3462 (set_attr "length" "16")]) 3463 3464(define_insn "shift_si3_loop" 3465 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r") 3466 (match_operator:SI 3 "shift_operator" 3467 [(match_operand:SI 1 "register_operand" "0,0") 3468 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")])) 3469 (clobber (match_scratch:SI 4 "=X,X")) 3470 (clobber (reg:SI LP_COUNT)) 3471 (clobber (reg:CC CC_REG)) 3472 ] 3473 "!TARGET_BARREL_SHIFTER" 3474 "* return output_shift (operands);" 3475 [(set_attr "type" "shift") 3476 (set_attr "length" "16,20")]) 3477 3478; asl, asr, lsr patterns: 3479; There is no point in including an 'I' alternative since only the lowest 5 3480; bits are used for the shift. OTOH Cal can be useful if the shift amount 3481; is defined in an external symbol, as we don't have special relocations 3482; to truncate a symbol in a u6 immediate; but that's rather exotic, so only 3483; provide one alternatice for this, without condexec support. 3484(define_insn "*ashlsi3_insn" 3485 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w") 3486 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz") 3487 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))] 3488 "TARGET_BARREL_SHIFTER 3489 && (register_operand (operands[1], SImode) 3490 || register_operand (operands[2], SImode))" 3491 "asl%? %0,%1,%2%&" 3492 [(set_attr "type" "shift") 3493 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false") 3494 (set_attr "predicable" "no,no,no,yes,no,no") 3495 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")]) 3496 3497(define_insn "*ashrsi3_insn" 3498 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w") 3499 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz") 3500 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))] 3501 "TARGET_BARREL_SHIFTER 3502 && (register_operand (operands[1], SImode) 3503 || register_operand (operands[2], SImode))" 3504 "asr%? %0,%1,%2%&" 3505 [(set_attr "type" "shift") 3506 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false") 3507 (set_attr "predicable" "no,no,no,yes,no,no") 3508 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")]) 3509 3510(define_insn "*lshrsi3_insn" 3511 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w") 3512 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal") 3513 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))] 3514 "TARGET_BARREL_SHIFTER 3515 && (register_operand (operands[1], SImode) 3516 || register_operand (operands[2], SImode))" 3517 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p () 3518 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");" 3519 [(set_attr "type" "shift") 3520 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false") 3521 (set_attr "predicable" "no,no,no,yes,no,no") 3522 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")]) 3523 3524(define_insn "rotrsi3" 3525 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w") 3526 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCsz") 3527 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))] 3528 "TARGET_BARREL_SHIFTER" 3529 "ror%? %0,%1,%2" 3530 [(set_attr "type" "shift,shift,shift") 3531 (set_attr "predicable" "yes,no,no") 3532 (set_attr "length" "4,4,8")]) 3533 3534;; Compare / branch instructions. 3535 3536(define_expand "cbranchsi4" 3537 [(set (reg:CC CC_REG) 3538 (compare:CC (match_operand:SI 1 "nonmemory_operand" "") 3539 (match_operand:SI 2 "nonmemory_operand" ""))) 3540 (set (pc) 3541 (if_then_else 3542 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG) 3543 (const_int 0)]) 3544 (label_ref (match_operand 3 "" "")) 3545 (pc)))] 3546 "" 3547{ 3548 gcc_assert (XEXP (operands[0], 0) == operands[1]); 3549 gcc_assert (XEXP (operands[0], 1) == operands[2]); 3550 operands[0] = gen_compare_reg (operands[0], VOIDmode); 3551 emit_jump_insn (gen_branch_insn (operands[3], operands[0])); 3552 DONE; 3553}) 3554 3555;; ??? Could add a peephole to generate compare with swapped operands and 3556;; modifed cc user if second, but not first operand is a compact register. 3557(define_insn "cmpsi_cc_insn_mixed" 3558 [(set (reg:CC CC_REG) 3559 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq, h, c, c,qRcq,c") 3560 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI,cL, Cal,Cal")))] 3561 "" 3562 "cmp%? %0,%B1%&" 3563 [(set_attr "type" "compare") 3564 (set_attr "iscompact" "true,true,true,false,false,true_limm,false") 3565 (set_attr "predicable" "no,no,no,no,yes,no,yes") 3566 (set_attr "cond" "set") 3567 (set_attr "length" "*,*,*,4,4,*,8") 3568 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")]) 3569 3570(define_insn "*cmpsi_cc_zn_insn" 3571 [(set (reg:CC_ZN CC_REG) 3572 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c") 3573 (const_int 0)))] 3574 "" 3575 "tst%? %0,%0%&" 3576 [(set_attr "type" "compare,compare") 3577 (set_attr "iscompact" "true,false") 3578 (set_attr "predicable" "no,yes") 3579 (set_attr "cond" "set_zn") 3580 (set_attr "length" "*,4")]) 3581 3582; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes. 3583(define_insn "*btst" 3584 [(set (reg:CC_ZN CC_REG) 3585 (compare:CC_ZN 3586 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c") 3587 (const_int 1) 3588 (match_operand:SI 1 "nonmemory_operand" "L,Lc")) 3589 (const_int 0)))] 3590 "" 3591 "btst%? %0,%1" 3592 [(set_attr "iscompact" "true,false") 3593 (set_attr "predicable" "no,yes") 3594 (set_attr "cond" "set") 3595 (set_attr "type" "compare") 3596 (set_attr "length" "*,4")]) 3597 3598; combine suffers from 'simplifications' that replace a one-bit zero 3599; extract with a shift if it can prove that the upper bits are zero. 3600; arc_reorg sees the code after sched2, which can have caused our 3601; inputs to be clobbered even if they were not clobbered before. 3602; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1} 3603; OTOH, this is somewhat marginal, and can leat to out-of-range 3604; bbit (i.e. bad scheduling) and missed conditional execution, 3605; so make this an option. 3606(define_peephole2 3607 [(set (reg:CC_ZN CC_REG) 3608 (compare:CC_ZN 3609 (zero_extract:SI (match_operand:SI 0 "register_operand" "") 3610 (const_int 1) 3611 (match_operand:SI 1 "nonmemory_operand" "")) 3612 (const_int 0))) 3613 (set (pc) 3614 (if_then_else (match_operator 3 "equality_comparison_operator" 3615 [(reg:CC_ZN CC_REG) (const_int 0)]) 3616 (label_ref (match_operand 2 "" "")) 3617 (pc)))] 3618 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)" 3619 [(parallel [(set (pc) 3620 (if_then_else 3621 (match_op_dup 3 3622 [(zero_extract:SI (match_dup 0) 3623 (const_int 1) (match_dup 1)) 3624 (const_int 0)]) 3625 (label_ref (match_dup 2)) 3626 (pc))) 3627 (clobber (reg:CC_ZN CC_REG))])]) 3628 3629(define_insn "*cmpsi_cc_z_insn" 3630 [(set (reg:CC_Z CC_REG) 3631 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c") 3632 (match_operand:SI 1 "p2_immediate_operand" "O,n")))] 3633 "" 3634 "@ 3635 cmp%? %0,%1%& 3636 bxor.f 0,%0,%z1" 3637 [(set_attr "type" "compare,compare") 3638 (set_attr "iscompact" "true,false") 3639 (set_attr "cond" "set,set_zn") 3640 (set_attr "length" "*,4")]) 3641 3642(define_insn "*cmpsi_cc_c_insn" 3643 [(set (reg:CC_C CC_REG) 3644 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c") 3645 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))] 3646 "" 3647 "cmp%? %0,%1%&" 3648 [(set_attr "type" "compare") 3649 (set_attr "iscompact" "true,true,true,false,true_limm,false") 3650 (set_attr "cond" "set") 3651 (set_attr "length" "*,*,*,4,*,8") 3652 (set_attr "cpu_facility" "av1,av2,*,*,*,*")]) 3653 3654;; Next come the scc insns. 3655 3656(define_expand "cstoresi4" 3657 [(set (match_operand:SI 0 "dest_reg_operand" "") 3658 (match_operator:SI 1 "ordered_comparison_operator" 3659 [(match_operand:SI 2 "nonmemory_operand" "") 3660 (match_operand:SI 3 "nonmemory_operand" "")]))] 3661 "" 3662{ 3663 if (!TARGET_CODE_DENSITY) 3664 { 3665 gcc_assert (XEXP (operands[1], 0) == operands[2]); 3666 gcc_assert (XEXP (operands[1], 1) == operands[3]); 3667 operands[1] = gen_compare_reg (operands[1], SImode); 3668 emit_insn (gen_scc_insn (operands[0], operands[1])); 3669 DONE; 3670 } 3671 if (!register_operand (operands[2], SImode)) 3672 operands[2] = force_reg (SImode, operands[2]); 3673 3674}) 3675 3676(define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE") 3677 (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")]) 3678 3679(define_expand "cstore<mode>4" 3680 [(set (reg:CC CC_REG) 3681 (compare:CC (match_operand:SDF 2 "register_operand" "") 3682 (match_operand:SDF 3 "register_operand" ""))) 3683 (set (match_operand:SI 0 "dest_reg_operand" "") 3684 (match_operator:SI 1 "comparison_operator" [(reg CC_REG) 3685 (const_int 0)]))] 3686 3687 "TARGET_HARD_FLOAT || TARGET_OPTFPE" 3688{ 3689 gcc_assert (XEXP (operands[1], 0) == operands[2]); 3690 gcc_assert (XEXP (operands[1], 1) == operands[3]); 3691 operands[1] = gen_compare_reg (operands[1], SImode); 3692 emit_insn (gen_scc_insn (operands[0], operands[1])); 3693 DONE; 3694}) 3695 3696; We need a separate expander for this lest we loose the mode of CC_REG 3697; when match_operator substitutes the literal operand into the comparison. 3698(define_expand "scc_insn" 3699 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))]) 3700 3701(define_insn_and_split "*scc_insn" 3702 [(set (match_operand:SI 0 "dest_reg_operand" "=w") 3703 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))] 3704 "" 3705 "#" 3706 "reload_completed" 3707 [(set (match_dup 0) (const_int 1)) 3708 (cond_exec 3709 (match_dup 1) 3710 (set (match_dup 0) (const_int 0)))] 3711{ 3712 operands[1] 3713 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]), 3714 GET_MODE (XEXP (operands[1], 0))), 3715 VOIDmode, 3716 XEXP (operands[1], 0), XEXP (operands[1], 1)); 3717} 3718 [(set_attr "type" "unary")]) 3719 3720;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value 3721;; that is one lower if the carry flag is set. 3722 3723;; ??? Look up negscc insn. See pa.md for example. 3724(define_insn "*neg_scc_insn" 3725 [(set (match_operand:SI 0 "dest_reg_operand" "=w") 3726 (neg:SI (match_operator:SI 1 "proper_comparison_operator" 3727 [(reg CC_REG) (const_int 0)])))] 3728 "" 3729 "mov %0,-1\;sub.%D1 %0,%0,%0" 3730 [(set_attr "type" "unary") 3731 (set_attr "length" "8")]) 3732 3733(define_insn "*not_scc_insn" 3734 [(set (match_operand:SI 0 "dest_reg_operand" "=w") 3735 (not:SI (match_operator:SI 1 "proper_comparison_operator" 3736 [(reg CC_REG) (const_int 0)])))] 3737 "" 3738 "mov %0,1\;sub.%d1 %0,%0,%0" 3739 [(set_attr "type" "unary") 3740 (set_attr "length" "8")]) 3741 3742; cond_exec patterns 3743(define_insn "*movsi_ne" 3744 [(cond_exec 3745 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0)) 3746 (set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, q, r") 3747 (match_operand:SI 1 "nonmemory_operand" "C_0, h, Lr,Cal,Cal")))] 3748 "" 3749 "@ 3750 * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\"; 3751 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\"; 3752 mov.ne\\t%0,%1 3753 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\"; 3754 mov.ne\\t%0,%1" 3755 [(set_attr "type" "cmove") 3756 (set_attr "iscompact" "true,true,false,true_limm,false") 3757 (set_attr "length" "2,2,4,6,8") 3758 (set_attr "cpu_facility" "*,av2,*,av2,*")]) 3759 3760(define_insn "*movsi_cond_exec" 3761 [(cond_exec 3762 (match_operator 3 "proper_comparison_operator" 3763 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)]) 3764 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 3765 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))] 3766 "" 3767 "mov.%d3 %0,%1" 3768 [(set_attr "type" "cmove") 3769 (set_attr "length" "4,8")]) 3770 3771(define_insn "*commutative_cond_exec" 3772 [(cond_exec 3773 (match_operator 5 "proper_comparison_operator" 3774 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)]) 3775 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 3776 (match_operator:SI 3 "commutative_operator" 3777 [(match_operand:SI 1 "register_operand" "%0,0") 3778 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))] 3779 "" 3780{ 3781 arc_output_commutative_cond_exec (operands, true); 3782 return ""; 3783} 3784 [(set_attr "cond" "use") 3785 (set_attr "type" "cmove") 3786 (set_attr_alternative "length" 3787 [(const_int 4) 3788 (cond 3789 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)") 3790 (const_int 4)) 3791 (const_int 4)] 3792 (const_int 8))])]) 3793 3794(define_insn "*sub_cond_exec" 3795 [(cond_exec 3796 (match_operator 4 "proper_comparison_operator" 3797 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)]) 3798 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w") 3799 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal") 3800 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))] 3801 "" 3802 "@ 3803 sub.%d4 %0,%1,%2 3804 rsub.%d4 %0,%2,%1 3805 rsub.%d4 %0,%2,%1" 3806 [(set_attr "cond" "use") 3807 (set_attr "type" "cmove") 3808 (set_attr "length" "4,4,8")]) 3809 3810(define_insn "*noncommutative_cond_exec" 3811 [(cond_exec 3812 (match_operator 5 "proper_comparison_operator" 3813 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)]) 3814 (set (match_operand:SI 0 "dest_reg_operand" "=w,w") 3815 (match_operator:SI 3 "noncommutative_operator" 3816 [(match_operand:SI 1 "register_operand" "0,0") 3817 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))] 3818 "" 3819 "%O3.%d5 %0,%1,%2" 3820 [(set_attr "cond" "use") 3821 (set_attr "type" "cmove") 3822 (set_attr "length" "4,8")]) 3823 3824;; These control RTL generation for conditional jump insns 3825;; Match both normal and inverted jump. 3826 3827; We need a separate expander for this lest we loose the mode of CC_REG 3828; when match_operator substitutes the literal operand into the comparison. 3829(define_expand "branch_insn" 3830 [(set (pc) 3831 (if_then_else (match_operand 1 "" "") 3832 (label_ref (match_operand 0 "" "")) 3833 (pc)))]) 3834 3835; When estimating sizes during arc_reorg, when optimizing for speed, there 3836; are three reasons why we need to consider branches to be length 6: 3837; - annull-false delay slot insns are implemented using conditional execution, 3838; thus preventing short insn formation where used. 3839; - for ARC600: annull-true delay slot isnns are implemented where possile 3840; using conditional execution, preventing short insn formation where used. 3841; - for ARC700: likely or somewhat likely taken branches are made long and 3842; unaligned if possible to avoid branch penalty. 3843(define_insn "*branch_insn" 3844 [(set (pc) 3845 (if_then_else (match_operator 1 "proper_comparison_operator" 3846 [(reg CC_REG) (const_int 0)]) 3847 (label_ref (match_operand 0 "" "")) 3848 (pc)))] 3849 "" 3850 "* 3851{ 3852 if (arc_ccfsm_branch_deleted_p ()) 3853 { 3854 arc_ccfsm_record_branch_deleted (); 3855 return \"; branch deleted, next insns conditionalized\"; 3856 } 3857 else 3858 { 3859 arc_ccfsm_record_condition (operands[1], false, insn, 0); 3860 if (get_attr_length (insn) == 2) 3861 return \"b%d1%? %^%l0%&\"; 3862 else 3863 return \"b%d1%# %^%l0\"; 3864 } 3865}" 3866 [(set_attr "type" "branch") 3867 (set 3868 (attr "length") 3869 (cond [ 3870 (eq_attr "delay_slot_filled" "yes") 3871 (const_int 4) 3872 3873 (ne 3874 (if_then_else 3875 (match_operand 1 "equality_comparison_operator" "") 3876 (ior (lt (minus (match_dup 0) (pc)) (const_int -512)) 3877 (gt (minus (match_dup 0) (pc)) 3878 (minus (const_int 506) 3879 (symbol_ref "get_attr_delay_slot_length (insn)")))) 3880 (ior (match_test "!arc_short_comparison_p (operands[1], -64)") 3881 (lt (minus (match_dup 0) (pc)) (const_int -64)) 3882 (gt (minus (match_dup 0) (pc)) 3883 (minus (const_int 58) 3884 (symbol_ref "get_attr_delay_slot_length (insn)"))))) 3885 (const_int 0)) 3886 (const_int 4)] 3887 (const_int 2))) 3888 3889 (set (attr "iscompact") 3890 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")] 3891 (const_string "false")))]) 3892 3893(define_insn "*rev_branch_insn" 3894 [(set (pc) 3895 (if_then_else (match_operator 1 "proper_comparison_operator" 3896 [(reg CC_REG) (const_int 0)]) 3897 (pc) 3898 (label_ref (match_operand 0 "" ""))))] 3899 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))" 3900 "* 3901{ 3902 if (arc_ccfsm_branch_deleted_p ()) 3903 { 3904 arc_ccfsm_record_branch_deleted (); 3905 return \"; branch deleted, next insns conditionalized\"; 3906 } 3907 else 3908 { 3909 arc_ccfsm_record_condition (operands[1], true, insn, 0); 3910 if (get_attr_length (insn) == 2) 3911 return \"b%D1%? %^%l0\"; 3912 else 3913 return \"b%D1%# %^%l0\"; 3914 } 3915}" 3916 [(set_attr "type" "branch") 3917 (set 3918 (attr "length") 3919 (cond [ 3920 (eq_attr "delay_slot_filled" "yes") 3921 (const_int 4) 3922 3923 (ne 3924 (if_then_else 3925 (match_operand 1 "equality_comparison_operator" "") 3926 (ior (lt (minus (match_dup 0) (pc)) (const_int -512)) 3927 (gt (minus (match_dup 0) (pc)) 3928 (minus (const_int 506) 3929 (symbol_ref "get_attr_delay_slot_length (insn)")))) 3930 (ior (match_test "!arc_short_comparison_p (operands[1], -64)") 3931 (lt (minus (match_dup 0) (pc)) (const_int -64)) 3932 (gt (minus (match_dup 0) (pc)) 3933 (minus (const_int 58) 3934 (symbol_ref "get_attr_delay_slot_length (insn)"))))) 3935 (const_int 0)) 3936 (const_int 4)] 3937 (const_int 2))) 3938 3939 (set (attr "iscompact") 3940 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")] 3941 (const_string "false")))]) 3942 3943;; Unconditional and other jump instructions. 3944 3945(define_expand "jump" 3946 [(set (pc) (label_ref (match_operand 0 "" "")))] 3947 "" 3948 "") 3949 3950(define_insn "jump_i" 3951 [(set (pc) (label_ref (match_operand 0 "" "")))] 3952 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)" 3953 "b%!%* %^%l0%&" 3954 [(set_attr "type" "uncond_branch") 3955 (set (attr "iscompact") 3956 (if_then_else (match_test "get_attr_length (insn) == 2") 3957 (const_string "true") (const_string "false"))) 3958 (set_attr "cond" "canuse") 3959 (set (attr "length") 3960 (cond [ 3961 ; In arc_reorg we just guesstimate; might be more or less than 4. 3962 (match_test "arc_branch_size_unknown_p ()") 3963 (const_int 4) 3964 3965 (eq_attr "delay_slot_filled" "yes") 3966 (const_int 4) 3967 3968 (match_test "CROSSING_JUMP_P (insn)") 3969 (const_int 4) 3970 3971 (ior (lt (minus (match_dup 0) (pc)) (const_int -512)) 3972 (gt (minus (match_dup 0) (pc)) 3973 (minus (const_int 506) 3974 (symbol_ref "get_attr_delay_slot_length (insn)")))) 3975 (const_int 4)] 3976 (const_int 2)))]) 3977 3978(define_insn "indirect_jump" 3979 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))] 3980 "" 3981 "@ 3982 j%!%* %0%& 3983 j%!%* %0%& 3984 j%!%* %0%& 3985 j%!%* [%0]%& 3986 j%!%* [%0]%&" 3987 [(set_attr "type" "jump") 3988 (set_attr "iscompact" "false,false,false,maybe,false") 3989 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")]) 3990 3991;; Implement a switch statement. 3992(define_expand "casesi" 3993 [(match_operand:SI 0 "register_operand" "") ; Index 3994 (match_operand:SI 1 "const_int_operand" "") ; Lower bound 3995 (match_operand:SI 2 "const_int_operand" "") ; Total range 3996 (match_operand:SI 3 "" "") ; Table label 3997 (match_operand:SI 4 "" "")] ; Out of range label 3998 "" 3999{ 4000 if (operands[1] != const0_rtx) 4001 { 4002 rtx reg = gen_reg_rtx (SImode); 4003 emit_insn (gen_subsi3 (reg, operands[0], operands[1])); 4004 operands[0] = reg; 4005 } 4006 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0], 4007 operands[2]), 4008 operands[0], operands[2], operands[4])); 4009 if (TARGET_BI_BIH) 4010 emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3])); 4011 else 4012 { 4013 rtx reg = gen_reg_rtx (SImode); 4014 rtx lbl = operands[3]; 4015 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]); 4016 if (flag_pic) 4017 operands[3] = force_reg (Pmode, operands[3]); 4018 emit_insn (gen_casesi_load (reg, 4019 operands[3], operands[0], lbl)); 4020 if (CASE_VECTOR_PC_RELATIVE || flag_pic) 4021 emit_insn (gen_addsi3 (reg, reg, operands[3])); 4022 emit_jump_insn (gen_casesi_jump (reg, lbl)); 4023 } 4024 DONE; 4025}) 4026 4027(define_insn "casesi_dispatch" 4028 [(set (pc) 4029 (unspec:SI [(match_operand:SI 0 "register_operand" "r") 4030 (label_ref (match_operand 1 "" ""))] 4031 UNSPEC_ARC_CASESI))] 4032 "TARGET_BI_BIH" 4033{ 4034 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1]))); 4035 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 4036 switch (GET_MODE (diff_vec)) 4037 { 4038 case E_SImode: 4039 return \"bi\\t[%0]\"; 4040 case E_HImode: 4041 case E_QImode: 4042 return \"bih\\t[%0]\"; 4043 default: gcc_unreachable (); 4044 } 4045} 4046 [(set_attr "type" "brcc_no_delay_slot") 4047 (set_attr "iscompact" "false") 4048 (set_attr "length" "4")]) 4049 4050(define_insn "casesi_load" 4051 [(set (match_operand:SI 0 "register_operand" "=q,r,r") 4052 (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal") 4053 (match_operand:SI 2 "register_operand" "q,r,r")] 4054 UNSPEC_ARC_CASESI))) 4055 (use (label_ref (match_operand 3 "" "")))] 4056 "" 4057 "* 4058{ 4059 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3]))); 4060 4061 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC) 4062 { 4063 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC); 4064 gcc_assert (GET_MODE (diff_vec) == SImode); 4065 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic); 4066 } 4067 4068 switch (GET_MODE (diff_vec)) 4069 { 4070 case E_SImode: 4071 return \"ld.as\\t%0,[%1,%2]%&\"; 4072 case E_HImode: 4073 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 4074 return \"ld%_.as\\t%0,[%1,%2]\"; 4075 return \"ld%_.x.as\\t%0,[%1,%2]\"; 4076 case E_QImode: 4077 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) 4078 return \"ldb%?\\t%0,[%1,%2]%&\"; 4079 return \"ldb.x\\t%0,[%1,%2]\"; 4080 default: 4081 gcc_unreachable (); 4082 } 4083}" 4084 [(set_attr "type" "load") 4085 (set_attr_alternative "iscompact" 4086 [(cond 4087 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn 4088 (as_a<rtx_insn *> (operands[3]))))") 4089 (symbol_ref "QImode")) 4090 (const_string "false") 4091 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn 4092 (as_a<rtx_insn *> (operands[3])))).offset_unsigned") 4093 (const_string "false")] 4094 (const_string "true")) 4095 (const_string "false") 4096 (const_string "false")]) 4097 (set_attr_alternative "length" 4098 [(cond 4099 [(eq_attr "iscompact" "false") (const_int 4) 4100 ; We have to mention (match_dup 3) to convince genattrtab.c that this 4101 ; is a varying length insn. 4102 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2) 4103 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)] 4104 (const_int 2)) 4105 (const_int 4) 4106 (const_int 8)])]) 4107 4108; Unlike the canonical tablejump, this pattern always uses a jump address, 4109; even for CASE_VECTOR_PC_RELATIVE. 4110(define_insn "casesi_jump" 4111 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c")) 4112 (use (label_ref (match_operand 1 "" "")))] 4113 "" 4114 "j%!%* [%0]%&" 4115 [(set_attr "type" "jump") 4116 (set_attr "iscompact" "false,maybe,false") 4117 (set_attr "cond" "canuse")]) 4118 4119(define_expand "call" 4120 ;; operands[1] is stack_size_rtx 4121 ;; operands[2] is next_arg_register 4122 [(parallel [(call (match_operand:SI 0 "call_operand" "") 4123 (match_operand 1 "" "")) 4124 (clobber (reg:SI 31))])] 4125 "" 4126 "{ 4127 rtx callee; 4128 4129 gcc_assert (MEM_P (operands[0])); 4130 callee = XEXP (operands[0], 0); 4131 /* This is to decide if we should generate indirect calls by loading the 4132 32 bit address of the callee into a register before performing the 4133 branch and link - this exposes cse opportunities. 4134 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */ 4135 if (GET_CODE (callee) != REG 4136 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee))) 4137 XEXP (operands[0], 0) = force_reg (Pmode, callee); 4138 } 4139") 4140 4141; Rcq, which is used in alternative 0, checks for conditional execution. 4142; At instruction output time, if it doesn't match and we end up with 4143; alternative 1 ("q"), that means that we can't use the short form. 4144(define_insn "*call_i" 4145 [(call (mem:SI (match_operand:SI 0 4146 "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal")) 4147 (match_operand 1 "" "")) 4148 (clobber (reg:SI 31))] 4149 "" 4150 "@ 4151 jl%!%* [%0]%& 4152 jl%!%* [%0]%& 4153 jl%!%* [%0] 4154 jli_s %S0 4155 sjli %S0 4156 bl%!%* %P0 4157 bl%!%* %P0 4158 jl%!%* %0 4159 jl%* %0 4160 jl%! %0" 4161 [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot") 4162 (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*,*") 4163 (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes") 4164 (set_attr "length" "*,*,4,2,4,4,4,4,4,8")]) 4165 4166(define_expand "call_value" 4167 ;; operand 2 is stack_size_rtx 4168 ;; operand 3 is next_arg_register 4169 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r") 4170 (call (match_operand:SI 1 "call_operand" "") 4171 (match_operand 2 "" ""))) 4172 (clobber (reg:SI 31))])] 4173 "" 4174 " 4175 { 4176 rtx callee; 4177 4178 gcc_assert (MEM_P (operands[1])); 4179 callee = XEXP (operands[1], 0); 4180 /* See the comment in define_expand \"call\". */ 4181 if (GET_CODE (callee) != REG 4182 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee))) 4183 XEXP (operands[1], 0) = force_reg (Pmode, callee); 4184 }") 4185 4186; Rcq, which is used in alternative 0, checks for conditional execution. 4187; At instruction output time, if it doesn't match and we end up with 4188; alternative 1 ("q"), that means that we can't use the short form. 4189(define_insn "*call_value_i" 4190 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w, w, w,w,w, w") 4191 (call (mem:SI (match_operand:SI 1 4192 "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal")) 4193 (match_operand 2 "" ""))) 4194 (clobber (reg:SI 31))] 4195 "" 4196 "@ 4197 jl%!%* [%1]%& 4198 jl%!%* [%1]%& 4199 jl%!%* [%1] 4200 jli_s %S1 4201 sjli %S1 4202 bl%!%* %P1;1 4203 bl%!%* %P1;1 4204 jl%!%* %1 4205 jl%* %1 4206 jl%! %1" 4207 [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot") 4208 (set_attr "iscompact" "maybe,false,*,true,false,*,*,*,*,*") 4209 (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes") 4210 (set_attr "length" "*,*,4,2,4,4,4,4,4,8")]) 4211 4212; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't 4213; use it for lack of inter-procedural branch shortening. 4214; Link-time relaxation would help... 4215 4216(define_insn "trap" 4217 [(trap_if (const_int 1) (const_int 0))] 4218 "!TARGET_ARC600_FAMILY" 4219 "trap_s\\t5" 4220 [(set_attr "type" "misc") 4221 (set_attr "length" "2")]) 4222 4223(define_insn "nop" 4224 [(const_int 0)] 4225 "" 4226 "nop%?" 4227 [(set_attr "type" "misc") 4228 (set_attr "iscompact" "true") 4229 (set_attr "cond" "canuse") 4230 (set_attr "length" "2")]) 4231 4232(define_insn "nopv" 4233 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)] 4234 "" 4235 "nop%?" 4236 [(set_attr "type" "misc") 4237 (set_attr "iscompact" "maybe") 4238 (set_attr "length" "*")]) 4239 4240(define_insn "blockage" 4241 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)] 4242 "" 4243 "" 4244 [(set_attr "length" "0") 4245 (set_attr "type" "block")] 4246) 4247 4248;; Split up troublesome insns for better scheduling. 4249 4250;; Peepholes go at the end. 4251;;asl followed by add can be replaced by an add{1,2,3} 4252;; Three define_peepholes have been added for this optimization 4253;; ??? This used to target non-canonical rtl. Now we use add_n, which 4254;; can be generated by combine. Check if these peepholes still provide 4255;; any benefit. 4256 4257;; ------------------------------------------------------------- 4258;; Pattern 1 : r0 = r1 << {i} 4259;; r3 = r4/INT + r0 ;;and commutative 4260;; || 4261;; \/ 4262;; add{i} r3,r4/INT,r1 4263;; ------------------------------------------------------------- 4264;; ??? This should be covered by combine, alas, at times combine gets 4265;; too clever for it's own good: when the shifted input is known to be 4266;; either 0 or 1, the operation will be made into an if-then-else, and 4267;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in 4268;; newlib/libc/time/mktm_r.c . 4269 4270(define_peephole2 4271 [(set (match_operand:SI 0 "dest_reg_operand" "") 4272 (ashift:SI (match_operand:SI 1 "register_operand" "") 4273 (match_operand:SI 2 "_1_2_3_operand" ""))) 4274 (set (match_operand:SI 3 "dest_reg_operand" "") 4275 (plus:SI (match_operand:SI 4 "nonmemory_operand" "") 4276 (match_operand:SI 5 "nonmemory_operand" "")))] 4277 "(true_regnum (operands[4]) == true_regnum (operands[0]) 4278 || true_regnum (operands[5]) == true_regnum (operands[0])) 4279 && (peep2_reg_dead_p (2, operands[0]) 4280 || (true_regnum (operands[3]) == true_regnum (operands[0]))) 4281 && !(optimize_size && satisfies_constraint_I (operands[4])) 4282 && !(optimize_size && satisfies_constraint_I (operands[5]))" 4283 ;; the preparation statements take care to put proper operand in operands[4] 4284 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity 4285 [(set (match_dup 3) 4286 (plus:SI (mult:SI (match_dup 1) 4287 (match_dup 2)) 4288 (match_dup 4)))] 4289 "if (true_regnum (operands[4]) == true_regnum (operands[0])) 4290 operands[4] = operands[5]; 4291 operands[2] = GEN_INT (1 << INTVAL (operands[2]));" 4292) 4293 4294;; ------------------------------------------------------------- 4295;; Pattern 1 : r0 = r1 << {i} 4296;; r3 = r4 - r0 4297;; || 4298;; \/ 4299;; sub{i} r3,r4,r1 4300;; ------------------------------------------------------------- 4301;; ??? This should be covered by combine, alas, at times combine gets 4302;; too clever for it's own good: when the shifted input is known to be 4303;; either 0 or 1, the operation will be made into an if-then-else, and 4304;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in 4305;; newlib/libm/math/e_jn.c . 4306 4307(define_peephole2 4308 [(set (match_operand:SI 0 "dest_reg_operand" "") 4309 (ashift:SI (match_operand:SI 1 "register_operand" "") 4310 (match_operand:SI 2 "const_int_operand" ""))) 4311 (set (match_operand:SI 3 "dest_reg_operand" "") 4312 (minus:SI (match_operand:SI 4 "nonmemory_operand" "") 4313 (match_dup 0)))] 4314 "(INTVAL (operands[2]) == 1 4315 || INTVAL (operands[2]) == 2 4316 || INTVAL (operands[2]) == 3) 4317 && (peep2_reg_dead_p (2, operands[0]) 4318 || (true_regnum (operands[3]) == true_regnum (operands[0])))" 4319 [(set (match_dup 3) 4320 (minus:SI (match_dup 4) 4321 (mult:SI (match_dup 1) 4322 (match_dup 2))))] 4323 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));" 4324) 4325 4326 4327 4328; When using the high single bit, the result of a multiply is either 4329; the original number or zero. But MPY costs 4 cycles, which we 4330; can replace with the 2 cycles for the pair of TST_S and ADD.NE. 4331(define_peephole2 4332 [(set (match_operand:SI 0 "dest_reg_operand" "") 4333 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 4334 (const_int 31))) 4335 (set (match_operand:SI 4 "register_operand" "") 4336 (mult:SI (match_operand:SI 2 "register_operand") 4337 (match_operand:SI 3 "nonmemory_operand" "")))] 4338 "TARGET_ARC700_MPY 4339 && (rtx_equal_p (operands[0], operands[2]) 4340 || rtx_equal_p (operands[0], operands[3])) 4341 && peep2_regno_dead_p (0, CC_REG) 4342 && (rtx_equal_p (operands[0], operands[4]) 4343 || (peep2_reg_dead_p (2, operands[0]) 4344 && peep2_reg_dead_p (1, operands[4])))" 4345 [(parallel [(set (reg:CC_Z CC_REG) 4346 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31)) 4347 (const_int 0))) 4348 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))]) 4349 (cond_exec 4350 (ne (reg:CC_Z CC_REG) (const_int 0)) 4351 (set (match_dup 4) (match_dup 5)))] 4352{ 4353 if (!rtx_equal_p (operands[0], operands[2])) 4354 operands[5] = operands[2]; 4355 else if (!rtx_equal_p (operands[0], operands[3])) 4356 operands[5] = operands[3]; 4357 else 4358 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */ 4359}) 4360 4361(define_peephole2 4362 [(set (match_operand:SI 0 "dest_reg_operand" "") 4363 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 4364 (const_int 31))) 4365 (set (match_operand:SI 4 "register_operand" "") 4366 (mult:SI (match_operand:SI 2 "register_operand") 4367 (match_operand:SI 3 "nonmemory_operand" "")))] 4368 "TARGET_ARC700_MPY 4369 && (rtx_equal_p (operands[0], operands[2]) 4370 || rtx_equal_p (operands[0], operands[3])) 4371 && peep2_regno_dead_p (2, CC_REG)" 4372 [(parallel [(set (reg:CC_Z CC_REG) 4373 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31)) 4374 (const_int 0))) 4375 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))]) 4376 (set (match_dup 4) (match_dup 5)) 4377 (cond_exec 4378 (eq (reg:CC_Z CC_REG) (const_int 0)) 4379 (set (match_dup 4) (const_int 0)))] 4380 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];") 4381 4382;; Instructions generated through builtins 4383 4384(define_insn "clrsbsi2" 4385 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 4386 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))] 4387 "TARGET_NORM" 4388 "@ 4389 norm \t%0, %1 4390 norm \t%0, %1" 4391 [(set_attr "length" "4,8") 4392 (set_attr "type" "two_cycle_core,two_cycle_core")]) 4393 4394(define_insn "norm_f" 4395 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 4396 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal"))) 4397 (set (reg:CC_ZN CC_REG) 4398 (compare:CC_ZN (match_dup 1) (const_int 0)))] 4399 "TARGET_NORM" 4400 "@ 4401 norm.f\t%0, %1 4402 norm.f\t%0, %1" 4403 [(set_attr "length" "4,8") 4404 (set_attr "type" "two_cycle_core,two_cycle_core")]) 4405 4406(define_insn_and_split "clrsbhi2" 4407 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w") 4408 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))] 4409 "TARGET_NORM" 4410 "#" 4411 "reload_completed" 4412 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))] 4413 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);") 4414 4415(define_insn "normw" 4416 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 4417 (zero_extend:SI 4418 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))] 4419 "TARGET_NORM" 4420 "@ 4421 norm%_ \t%0, %1 4422 norm%_ \t%0, %1" 4423 [(set_attr "length" "4,8") 4424 (set_attr "type" "two_cycle_core,two_cycle_core")]) 4425 4426(define_expand "clzsi2" 4427 [(parallel 4428 [(set (match_operand:SI 0 "register_operand" "") 4429 (clz:SI (match_operand:SI 1 "register_operand" ""))) 4430 (clobber (match_dup 2))])] 4431 "TARGET_NORM" 4432 "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);") 4433 4434(define_insn_and_split "*arc_clzsi2" 4435 [(set (match_operand:SI 0 "register_operand" "=r") 4436 (clz:SI (match_operand:SI 1 "register_operand" "r"))) 4437 (clobber (reg:CC_ZN CC_REG))] 4438 "TARGET_NORM" 4439 "#" 4440 "reload_completed" 4441 [(const_int 0)] 4442{ 4443 emit_insn (gen_norm_f (operands[0], operands[1])); 4444 emit_insn 4445 (gen_rtx_COND_EXEC 4446 (VOIDmode, 4447 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), 4448 gen_rtx_SET (operands[0], const0_rtx))); 4449 emit_insn 4450 (gen_rtx_COND_EXEC 4451 (VOIDmode, 4452 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), 4453 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1)))); 4454 DONE; 4455} 4456[(set_attr "type" "unary") 4457 (set_attr "length" "12")]) 4458 4459(define_expand "ctzsi2" 4460 [(match_operand:SI 0 "register_operand" "") 4461 (match_operand:SI 1 "register_operand" "")] 4462 "TARGET_NORM" 4463 " 4464 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1])); 4465 DONE; 4466") 4467 4468(define_insn_and_split "arc_ctzsi2" 4469 [(set (match_operand:SI 0 "register_operand" "=r") 4470 (ctz:SI (match_operand:SI 1 "register_operand" "r"))) 4471 (clobber (reg:CC_ZN CC_REG)) 4472 (clobber (match_scratch:SI 2 "=&r"))] 4473 "TARGET_NORM" 4474 "#" 4475 "reload_completed" 4476 [(const_int 0)] 4477{ 4478 rtx temp = operands[0]; 4479 4480 if (reg_overlap_mentioned_p (temp, operands[1]) 4481 || (REGNO (temp) < FIRST_PSEUDO_REGISTER 4482 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 4483 REGNO (temp)))) 4484 temp = operands[2]; 4485 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx)); 4486 emit_insn (gen_bic_f_zn (temp, temp, operands[1])); 4487 emit_insn (gen_clrsbsi2 (operands[0], temp)); 4488 emit_insn 4489 (gen_rtx_COND_EXEC 4490 (VOIDmode, 4491 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), 4492 gen_rtx_SET (operands[0], GEN_INT (32)))); 4493 emit_insn 4494 (gen_rtx_COND_EXEC 4495 (VOIDmode, 4496 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), 4497 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), 4498 operands[0])))); 4499 DONE; 4500} 4501[(set_attr "type" "unary") 4502 (set_attr "length" "20")]) 4503 4504(define_insn "swap" 4505 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w") 4506 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")] 4507 UNSPEC_ARC_SWAP))] 4508 "TARGET_SWAP" 4509 "@ 4510 swap \t%0, %1 4511 swap \t%0, %1 4512 swap \t%0, %1" 4513 [(set_attr "length" "4,8,4") 4514 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")]) 4515 4516(define_insn "divaw" 4517 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w") 4518 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r") 4519 (match_operand:SI 2 "general_operand" "r,r,Cal"))] 4520 UNSPEC_ARC_DIVAW))] 4521 "TARGET_ARC700 || TARGET_EA_SET" 4522 "@ 4523 divaw \t%0, %1, %2 4524 divaw \t%0, %1, %2 4525 divaw \t%0, %1, %2" 4526 [(set_attr "length" "4,8,8") 4527 (set_attr "type" "divaw,divaw,divaw")]) 4528 4529(define_insn "flag" 4530 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")] 4531 VUNSPEC_ARC_FLAG)] 4532 "" 4533 "@ 4534 flag%? %0 4535 flag %0 4536 flag%? %0" 4537 [(set_attr "length" "4,4,8") 4538 (set_attr "type" "misc,misc,misc") 4539 (set_attr "predicable" "yes,no,yes") 4540 (set_attr "cond" "clob,clob,clob")]) 4541 4542(define_insn "brk" 4543 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] 4544 VUNSPEC_ARC_BRK)] 4545 "" 4546 "brk" 4547 [(set_attr "length" "4") 4548 (set_attr "type" "misc")]) 4549 4550(define_insn "rtie" 4551 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] 4552 VUNSPEC_ARC_RTIE)] 4553 "" 4554 "rtie" 4555 [(set_attr "length" "4") 4556 (set_attr "type" "misc") 4557 (set_attr "cond" "clob")]) 4558 4559(define_insn "sync" 4560 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] 4561 VUNSPEC_ARC_SYNC)] 4562 "" 4563 "sync" 4564 [(set_attr "length" "4") 4565 (set_attr "type" "misc")]) 4566 4567(define_insn "swi" 4568 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] 4569 VUNSPEC_ARC_SWI)] 4570 "" 4571 "* 4572{ 4573 if(TARGET_ARC700) 4574 return \"trap0\"; 4575 else 4576 return \"swi\"; 4577}" 4578 [(set_attr "length" "4") 4579 (set_attr "type" "misc")]) 4580 4581 4582(define_insn "sleep" 4583 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "Lr")] 4584 VUNSPEC_ARC_SLEEP)] 4585 "" 4586 "sleep %0" 4587 [(set_attr "length" "4") 4588 (set_attr "type" "misc")]) 4589 4590(define_insn "core_read" 4591 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r") 4592 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")] 4593 VUNSPEC_ARC_CORE_READ))] 4594 "" 4595 "* 4596 if (check_if_valid_regno_const (operands, 1)) 4597 return \"mov \t%0, r%1\"; 4598 return \"mov \t%0, r%1\"; 4599 " 4600 [(set_attr "length" "4") 4601 (set_attr "type" "unary")]) 4602 4603(define_insn "core_write" 4604 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r") 4605 (match_operand:SI 1 "general_operand" "Hn,!r")] 4606 VUNSPEC_ARC_CORE_WRITE)] 4607 "" 4608 "* 4609 if (check_if_valid_regno_const (operands, 1)) 4610 return \"mov \tr%1, %0\"; 4611 return \"mov \tr%1, %0\"; 4612 " 4613 [(set_attr "length" "4") 4614 (set_attr "type" "unary")]) 4615 4616(define_insn "lr" 4617 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r") 4618 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")] 4619 VUNSPEC_ARC_LR))] 4620 "" 4621 "lr\t%0, [%1]" 4622 [(set_attr "length" "4,8,4,8") 4623 (set_attr "type" "lr,lr,lr,lr")]) 4624 4625(define_insn "sr" 4626 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r") 4627 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")] 4628 VUNSPEC_ARC_SR)] 4629 "" 4630 "sr\t%0, [%1]" 4631 [(set_attr "length" "8,4,8,4") 4632 (set_attr "type" "sr,sr,sr,sr")]) 4633 4634(define_insn "trap_s" 4635 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")] 4636 VUNSPEC_ARC_TRAP_S)] 4637 "!TARGET_ARC600_FAMILY" 4638{ 4639 if (which_alternative == 0) 4640 { 4641 arc_toggle_unalign (); 4642 return \"trap_s %0\"; 4643 } 4644 4645 /* Keep this message in sync with the one in arc.c:arc_expand_builtin, 4646 because *.md files do not get scanned by exgettext. */ 4647 fatal_error (input_location, 4648 \"operand to trap_s should be an unsigned 6-bit value\"); 4649} 4650 [(set_attr "length" "2") 4651 (set_attr "type" "misc")]) 4652 4653(define_insn "unimp_s" 4654 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] 4655 VUNSPEC_ARC_UNIMP_S)] 4656 "!TARGET_ARC600_FAMILY" 4657 "unimp_s" 4658 [(set_attr "length" "4") 4659 (set_attr "type" "misc")]) 4660 4661;; End of instructions generated through builtins 4662 4663; Since the demise of REG_N_SETS as reliable data readily available to the 4664; target, it is no longer possible to find out 4665; in the prologue / epilogue expanders how many times blink is set. 4666; Using df_regs_ever_live_p to decide if blink needs saving means that 4667; any explicit use of blink will cause it to be saved; hence we cannot 4668; represent the blink use in return / sibcall instructions themselves, and 4669; instead have to show it in EPILOGUE_USES and must explicitly 4670; forbid instructions that change blink in the return / sibcall delay slot. 4671(define_expand "sibcall" 4672 [(parallel [(call (match_operand 0 "memory_operand" "") 4673 (match_operand 1 "general_operand" "")) 4674 (simple_return) 4675 (use (match_operand 2 "" ""))])] 4676 "" 4677 " 4678 { 4679 rtx callee = XEXP (operands[0], 0); 4680 4681 if (operands[2] == NULL_RTX) 4682 operands[2] = const0_rtx; 4683 if (GET_CODE (callee) != REG 4684 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee))) 4685 XEXP (operands[0], 0) = force_reg (Pmode, callee); 4686 }" 4687) 4688 4689(define_expand "sibcall_value" 4690 [(parallel [(set (match_operand 0 "dest_reg_operand" "") 4691 (call (match_operand 1 "memory_operand" "") 4692 (match_operand 2 "general_operand" ""))) 4693 (simple_return) 4694 (use (match_operand 3 "" ""))])] 4695 "" 4696 " 4697 { 4698 rtx callee = XEXP (operands[1], 0); 4699 4700 if (operands[3] == NULL_RTX) 4701 operands[3] = const0_rtx; 4702 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee)) 4703 XEXP (operands[1], 0) = force_reg (Pmode, callee); 4704 }" 4705) 4706 4707(define_insn "*sibcall_insn" 4708 [(call (mem:SI (match_operand:SI 0 "call_address_operand" 4709 "Cbp,Cbr,!Rcd,Rsc,Cal")) 4710 (match_operand 1 "" "")) 4711 (simple_return) 4712 (use (match_operand 2 "" ""))] 4713 "" 4714 "@ 4715 b%!%*\\t%P0 4716 b%!%*\\t%P0 4717 j%!%*\\t[%0] 4718 j%!%*\\t[%0] 4719 j%!\\t%P0" 4720 [(set_attr "type" "call,call,call,call,call_no_delay_slot") 4721 (set_attr "predicable" "yes,no,no,yes,yes") 4722 (set_attr "iscompact" "false,false,maybe,false,false") 4723 (set_attr "is_SIBCALL" "yes")] 4724) 4725 4726(define_insn "*sibcall_value_insn" 4727 [(set (match_operand 0 "dest_reg_operand" "") 4728 (call (mem:SI (match_operand:SI 1 "call_address_operand" 4729 "Cbp,Cbr,!Rcd,Rsc,Cal")) 4730 (match_operand 2 "" ""))) 4731 (simple_return) 4732 (use (match_operand 3 "" ""))] 4733 "" 4734 "@ 4735 b%!%*\\t%P1 4736 b%!%*\\t%P1 4737 j%!%*\\t[%1] 4738 j%!%*\\t[%1] 4739 j%!\\t%P1" 4740 [(set_attr "type" "call,call,call,call,call_no_delay_slot") 4741 (set_attr "predicable" "yes,no,no,yes,yes") 4742 (set_attr "iscompact" "false,false,maybe,false,false") 4743 (set_attr "is_SIBCALL" "yes")] 4744) 4745 4746(define_expand "prologue" 4747 [(pc)] 4748 "" 4749{ 4750 arc_expand_prologue (); 4751 DONE; 4752}) 4753 4754(define_expand "epilogue" 4755 [(pc)] 4756 "" 4757{ 4758 arc_expand_epilogue (0); 4759 DONE; 4760}) 4761 4762(define_expand "sibcall_epilogue" 4763 [(pc)] 4764 "" 4765{ 4766 arc_expand_epilogue (1); 4767 DONE; 4768}) 4769 4770; Since the demise of REG_N_SETS, it is no longer possible to find out 4771; in the prologue / epilogue expanders how many times blink is set. 4772; Using df_regs_ever_live_p to decide if blink needs saving means that 4773; any explicit use of blink will cause it to be saved; hence we cannot 4774; represent the blink use in return / sibcall instructions themselves, and 4775; instead have to show it in EPILOGUE_USES and must explicitly 4776; forbid instructions that change blink in the return / sibcall delay slot. 4777(define_insn "simple_return" 4778 [(simple_return)] 4779 "reload_completed" 4780{ 4781 rtx reg 4782 = gen_rtx_REG (Pmode, 4783 arc_return_address_register (arc_compute_function_type 4784 (cfun))); 4785 4786 if (TARGET_V2 4787 && ARC_INTERRUPT_P (arc_compute_function_type (cfun))) 4788 { 4789 return \"rtie\"; 4790 } 4791 output_asm_insn (\"j%!%* [%0]%&\", ®); 4792 return \"\"; 4793} 4794 [(set (attr "type") 4795 (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))") 4796 (match_test "TARGET_V2")) 4797 (const_string "brcc_no_delay_slot")] 4798 (const_string "return"))) 4799 ; predicable won't help here since the canonical rtl looks different 4800 ; for branches. 4801 (set (attr "cond") 4802 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)") 4803 (symbol_ref "ARC_FUNCTION_ILINK1")) 4804 (match_test "TARGET_V2")) 4805 (const_string "nocond")] 4806 (const_string "canuse"))) 4807 (set (attr "iscompact") 4808 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)") 4809 (symbol_ref "ARC_FUNCTION_NORMAL")) 4810 (const_string "maybe")] 4811 (const_string "false"))) 4812 (set (attr "length") 4813 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)") 4814 (symbol_ref "ARC_FUNCTION_NORMAL")) 4815 (const_int 4)] 4816 (const_int 2)))]) 4817 4818(define_insn "p_return_i" 4819 [(set (pc) 4820 (if_then_else (match_operator 0 "proper_comparison_operator" 4821 [(reg CC_REG) (const_int 0)]) 4822 (simple_return) (pc)))] 4823 "reload_completed 4824 && !(TARGET_V2 4825 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))" 4826{ 4827 rtx xop[2]; 4828 xop[0] = operands[0]; 4829 xop[1] 4830 = gen_rtx_REG (Pmode, 4831 arc_return_address_register (arc_compute_function_type 4832 (cfun))); 4833 4834 output_asm_insn (\"j%d0%!%# [%1]%&\", xop); 4835 /* record the condition in case there is a delay insn. */ 4836 arc_ccfsm_record_condition (xop[0], false, insn, 0); 4837 return \"\"; 4838} 4839 [(set_attr "type" "return") 4840 (set_attr "cond" "use") 4841 (set (attr "iscompact") 4842 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)") 4843 (symbol_ref "ARC_FUNCTION_NORMAL")) 4844 (const_string "maybe")] 4845 (const_string "false"))) 4846 (set (attr "length") 4847 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)") 4848 (symbol_ref "ARC_FUNCTION_NORMAL")) 4849 (const_int 4) 4850 (not (match_operand 0 "equality_comparison_operator" "")) 4851 (const_int 4) 4852 (eq_attr "delay_slot_filled" "yes") 4853 (const_int 4)] 4854 (const_int 2)))]) 4855 4856;; ??? #ifdefs in function.c require the presence of this pattern, with a 4857;; non-constant predicate. 4858(define_expand "return" 4859 [(return)] 4860 "optimize < 0") 4861 4862 ;; Comment in final.c (insn_current_reference_address) says 4863 ;; forward branch addresses are calculated from the next insn after branch 4864 ;; and for backward branches, it is calculated from the branch insn start. 4865 ;; The shortening logic here is tuned to accomodate this behavior 4866;; ??? This should be grokked by the ccfsm machinery. 4867(define_insn "cbranchsi4_scratch" 4868 [(set (pc) 4869 (if_then_else (match_operator 0 "proper_comparison_operator" 4870 [(match_operand:SI 1 "register_operand" "c,c, c") 4871 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")]) 4872 (label_ref (match_operand 3 "" "")) 4873 (pc))) 4874 (clobber (match_operand 4 "cc_register" ""))] 4875 "(reload_completed 4876 || (TARGET_EARLY_CBRANCHSI 4877 && brcc_nolimm_operator (operands[0], VOIDmode))) 4878 && !CROSSING_JUMP_P (insn)" 4879 "* 4880 switch (get_attr_length (insn)) 4881 { 4882 case 2: return \"br%d0%? %1, %2, %^%l3%&\"; 4883 case 4: return \"br%d0%* %1, %B2, %^%l3\"; 4884 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode)) 4885 return \"br%d0%* %1, %B2, %^%l3\"; 4886 /* FALLTHRU */ 4887 case 6: case 10: 4888 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\"; 4889 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable (); 4890 } 4891 " 4892 [(set_attr "cond" "clob, clob, clob") 4893 (set (attr "type") 4894 (if_then_else 4895 (match_test "valid_brcc_with_delay_p (operands)") 4896 (const_string "brcc") 4897 (const_string "brcc_no_delay_slot"))) 4898 ; For forward branches, we need to account not only for the distance to 4899 ; the target, but also the difference between pcl and pc, the instruction 4900 ; length, and any delay insn, if present. 4901 (set 4902 (attr "length") 4903 (cond ; the outer cond does a test independent of branch shortening. 4904 [(match_operand 0 "brcc_nolimm_operator" "") 4905 (cond 4906 [(and (match_operand:CC_Z 4 "cc_register") 4907 (eq_attr "delay_slot_filled" "no") 4908 (ge (minus (match_dup 3) (pc)) (const_int -128)) 4909 (le (minus (match_dup 3) (pc)) 4910 (minus (const_int 122) 4911 (symbol_ref "get_attr_delay_slot_length (insn)")))) 4912 (const_int 2) 4913 (and (ge (minus (match_dup 3) (pc)) (const_int -256)) 4914 (le (minus (match_dup 3) (pc)) 4915 (minus (const_int 244) 4916 (symbol_ref "get_attr_delay_slot_length (insn)")))) 4917 (const_int 4) 4918 (and (match_operand:SI 1 "compact_register_operand" "") 4919 (match_operand:SI 2 "compact_hreg_operand" "")) 4920 (const_int 6)] 4921 (const_int 8))] 4922 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256)) 4923 (le (minus (match_dup 3) (pc)) (const_int 244))) 4924 (const_int 8) 4925 (and (match_operand:SI 1 "compact_register_operand" "") 4926 (match_operand:SI 2 "compact_hreg_operand" "")) 4927 (const_int 10)] 4928 (const_int 12)))) 4929 (set (attr "iscompact") 4930 (if_then_else (match_test "get_attr_length (insn) & 2") 4931 (const_string "true") (const_string "false")))]) 4932 4933; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes. 4934(define_insn "*bbit" 4935 [(set (pc) 4936 (if_then_else 4937 (match_operator 3 "equality_comparison_operator" 4938 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c") 4939 (const_int 1) 4940 (match_operand:SI 2 "nonmemory_operand" "L,Lc")) 4941 (const_int 0)]) 4942 (label_ref (match_operand 0 "" "")) 4943 (pc))) 4944 (clobber (reg:CC_ZN CC_REG))] 4945 "!CROSSING_JUMP_P (insn)" 4946{ 4947 switch (get_attr_length (insn)) 4948 { 4949 case 4: return (GET_CODE (operands[3]) == EQ 4950 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\"); 4951 case 6: 4952 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\"; 4953 default: gcc_unreachable (); 4954 } 4955} 4956 [(set_attr "type" "brcc") 4957 (set_attr "cond" "clob") 4958 (set (attr "length") 4959 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254)) 4960 (le (minus (match_dup 0) (pc)) 4961 (minus (const_int 248) 4962 (symbol_ref "get_attr_delay_slot_length (insn)")))) 4963 (const_int 4) 4964 (eq (symbol_ref "which_alternative") (const_int 0)) 4965 (const_int 6)] 4966 (const_int 8))) 4967 (set (attr "iscompact") 4968 (if_then_else (match_test "get_attr_length (insn) == 6") 4969 (const_string "true") (const_string "false")))]) 4970 4971; ??? When testing a bit from a DImode register, combine creates a 4972; zero_extract in DImode. This goes via an AND with a DImode constant, 4973; so can only be observed on 64 bit hosts. 4974(define_insn_and_split "*bbit_di" 4975 [(set (pc) 4976 (if_then_else 4977 (match_operator 3 "equality_comparison_operator" 4978 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c") 4979 (const_int 1) 4980 (match_operand 2 "immediate_operand" "L,L")) 4981 (const_int 0)]) 4982 (label_ref (match_operand 0 "" "")) 4983 (pc))) 4984 (clobber (reg:CC_ZN CC_REG))] 4985 "!CROSSING_JUMP_P (insn)" 4986 "#" 4987 "" 4988 [(parallel 4989 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc))) 4990 (clobber (reg:CC_ZN CC_REG))])] 4991{ 4992 rtx xtr; 4993 4994 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]); 4995 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 4996 xtr, const0_rtx); 4997}) 4998 4999;; ------------------------------------------------------------------- 5000;; Hardware loop 5001;; ------------------------------------------------------------------- 5002 5003; operand 0 is the loop count pseudo register 5004; operand 1 is the label to jump to at the top of the loop 5005(define_expand "doloop_end" 5006 [(parallel [(set (pc) 5007 (if_then_else 5008 (ne (match_operand 0 "" "") 5009 (const_int 1)) 5010 (label_ref (match_operand 1 "" "")) 5011 (pc))) 5012 (set (match_dup 0) (plus (match_dup 0) (const_int -1))) 5013 (unspec [(const_int 0)] UNSPEC_ARC_LP) 5014 (clobber (match_dup 2))])] 5015 "" 5016{ 5017 if (GET_MODE (operands[0]) != SImode) 5018 FAIL; 5019 operands[2] = gen_rtx_SCRATCH (SImode); 5020}) 5021 5022(define_insn "arc_lp" 5023 [(unspec:SI [(reg:SI LP_COUNT)] 5024 UNSPEC_ARC_LP) 5025 (use (label_ref (match_operand 0 "" ""))) 5026 (use (label_ref (match_operand 1 "" "")))] 5027 "" 5028 "lp\\t@%l1\\t; lp_count:@%l0->@%l1" 5029 [(set_attr "type" "loop_setup") 5030 (set_attr "length" "4")]) 5031 5032;; if by any chance the lp_count is not used, then use an 'r' 5033;; register, instead of going to memory. 5034(define_insn "loop_end" 5035 [(set (pc) 5036 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,m") 5037 (const_int 1)) 5038 (label_ref (match_operand 1 "" "")) 5039 (pc))) 5040 (set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 5041 (plus (match_dup 2) (const_int -1))) 5042 (unspec [(const_int 0)] UNSPEC_ARC_LP) 5043 (clobber (match_scratch:SI 3 "=X,&r"))] 5044 "" 5045 "; ZOL_END, begins @%l1" 5046 [(set_attr "length" "0") 5047 (set_attr "predicable" "no") 5048 (set_attr "type" "loop_end")]) 5049 5050;; split pattern for the very slim chance when the loop register is 5051;; memory. 5052(define_split 5053 [(set (pc) 5054 (if_then_else (ne (match_operand:SI 0 "memory_operand") 5055 (const_int 1)) 5056 (label_ref (match_operand 1 "")) 5057 (pc))) 5058 (set (match_dup 0) (plus (match_dup 0) (const_int -1))) 5059 (unspec [(const_int 0)] UNSPEC_ARC_LP) 5060 (clobber (match_scratch:SI 2))] 5061 "memory_operand (operands[0], SImode)" 5062 [(set (match_dup 2) (match_dup 0)) 5063 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) 5064 (set (match_dup 0) (match_dup 2)) 5065 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0))) 5066 (set (pc) 5067 (if_then_else (ne (reg:CC CC_REG) 5068 (const_int 0)) 5069 (label_ref (match_dup 1)) 5070 (pc)))] 5071 "") 5072 5073(define_insn "loop_fail" 5074 [(set (reg:SI LP_COUNT) 5075 (plus:SI (reg:SI LP_COUNT) (const_int -1))) 5076 (set (reg:CC_ZN CC_REG) 5077 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1)) 5078 (const_int 0)))] 5079 "" 5080 "sub.f%?\\tlp_count,lp_count,1" 5081 [(set_attr "iscompact" "false") 5082 (set_attr "type" "compare") 5083 (set_attr "cond" "set_zn") 5084 (set_attr "length" "4") 5085 (set_attr "predicable" "yes")]) 5086 5087(define_insn_and_split "dbnz" 5088 [(set (pc) 5089 (if_then_else 5090 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m") 5091 (const_int -1)) 5092 (const_int 0)) 5093 (label_ref (match_operand 1 "" "")) 5094 (pc))) 5095 (set (match_dup 0) 5096 (plus:SI (match_dup 0) 5097 (const_int -1))) 5098 (clobber (match_scratch:SI 2 "=X,r"))] 5099 "TARGET_DBNZ" 5100 "@ 5101 dbnz%#\\t%0,%l1 5102 #" 5103 "TARGET_DBNZ && reload_completed && memory_operand (operands[0], SImode)" 5104 [(set (match_dup 2) (match_dup 0)) 5105 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) 5106 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0))) 5107 (set (match_dup 0) (match_dup 2)) 5108 (set (pc) (if_then_else (ge (reg:CC CC_REG) 5109 (const_int 0)) 5110 (label_ref (match_dup 1)) 5111 (pc)))] 5112 "" 5113 [(set_attr "iscompact" "false") 5114 (set_attr "type" "loop_end") 5115 (set_attr "length" "4,20")]) 5116 5117(define_expand "movmemsi" 5118 [(match_operand:BLK 0 "" "") 5119 (match_operand:BLK 1 "" "") 5120 (match_operand:SI 2 "nonmemory_operand" "") 5121 (match_operand 3 "immediate_operand" "")] 5122 "" 5123 "if (arc_expand_movmem (operands)) DONE; else FAIL;") 5124 5125;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works 5126;; to the point that we can generate cmove instructions. 5127(define_expand "cbranch<mode>4" 5128 [(set (reg:CC CC_REG) 5129 (compare:CC (match_operand:SDF 1 "register_operand" "") 5130 (match_operand:SDF 2 "register_operand" ""))) 5131 (set (pc) 5132 (if_then_else 5133 (match_operator 0 "comparison_operator" [(reg CC_REG) 5134 (const_int 0)]) 5135 (label_ref (match_operand 3 "" "")) 5136 (pc)))] 5137 5138 "TARGET_FP_SP_BASE || TARGET_OPTFPE" 5139{ 5140 gcc_assert (XEXP (operands[0], 0) == operands[1]); 5141 gcc_assert (XEXP (operands[0], 1) == operands[2]); 5142 operands[0] = gen_compare_reg (operands[0], VOIDmode); 5143 emit_jump_insn (gen_branch_insn (operands[3], operands[0])); 5144 DONE; 5145}) 5146 5147(define_expand "cmp_float" 5148 [(parallel [(set (match_operand 0 "") (match_operand 1 "")) 5149 (clobber (reg:SI RETURN_ADDR_REGNUM)) 5150 (clobber (reg:SI R12_REG))])] 5151 "" 5152 "") 5153 5154(define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD]) 5155(define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge") 5156 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")]) 5157 5158(define_insn "*cmpsf_<cmp>" 5159 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1))) 5160 (clobber (reg:SI RETURN_ADDR_REGNUM)) 5161 (clobber (reg:SI R12_REG))] 5162 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP) 5163 && SFUNC_CHECK_PREDICABLE" 5164 "*return arc_output_libcall (\"__<cmp>sf2\");" 5165 [(set_attr "is_sfunc" "yes") 5166 (set_attr "predicable" "yes")]) 5167 5168;; N.B. for "*cmpdf_ord": 5169;; double precision fpx sets bit 31 for NaNs. We need bit 51 set 5170;; for the floating point emulation to recognize the NaN. 5171(define_insn "*cmpdf_<cmp>" 5172 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2))) 5173 (clobber (reg:SI RETURN_ADDR_REGNUM)) 5174 (clobber (reg:SI R12_REG))] 5175 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP) 5176 && SFUNC_CHECK_PREDICABLE" 5177 "*return arc_output_libcall (\"__<cmp>df2\");" 5178 [(set_attr "is_sfunc" "yes") 5179 (set_attr "predicable" "yes")]) 5180 5181(define_insn "abssf2" 5182 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w") 5183 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))] 5184 "" 5185 "bclr%? %0,%1,31%&" 5186 [(set_attr "type" "unary") 5187 (set_attr "iscompact" "maybe,false,false") 5188 (set_attr "length" "2,4,4") 5189 (set_attr "predicable" "no,yes,no")]) 5190 5191(define_insn "negsf2" 5192 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w") 5193 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))] 5194 "" 5195 "bxor%? %0,%1,31" 5196 [(set_attr "type" "unary") 5197 (set_attr "predicable" "yes,no")]) 5198 5199;; ??? Should this use arc_output_libcall and set is_sfunc? 5200(define_insn "*millicode_thunk_st" 5201 [(match_parallel 0 "millicode_store_operation" 5202 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])] 5203 "" 5204{ 5205 output_asm_insn ("bl%* __st_r13_to_%0", 5206 &SET_SRC (XVECEXP (operands[0], 0, 5207 XVECLEN (operands[0], 0) - 2))); 5208 return ""; 5209} 5210 [(set_attr "type" "call")]) 5211 5212(define_insn "*millicode_thunk_ld" 5213 [(match_parallel 0 "millicode_load_clob_operation" 5214 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])] 5215 "" 5216{ 5217 output_asm_insn ("bl%* __ld_r13_to_%0", 5218 &SET_DEST (XVECEXP (operands[0], 0, 5219 XVECLEN (operands[0], 0) - 2))); 5220 return ""; 5221} 5222 [(set_attr "type" "call")]) 5223 5224; the sibthunk restores blink, so we use the return rtx. 5225(define_insn "*millicode_sibthunk_ld" 5226 [(match_parallel 0 "millicode_load_operation" 5227 [(return) 5228 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12))) 5229 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])] 5230 "" 5231{ 5232 output_asm_insn ("b%* __ld_r13_to_%0_ret", 5233 &SET_DEST (XVECEXP (operands[0], 0, 5234 XVECLEN (operands[0], 0) - 1))); 5235 return ""; 5236} 5237 [(set_attr "type" "call") 5238 (set_attr "is_SIBCALL" "yes")]) 5239 5240;; For thread pointer builtins 5241(define_expand "get_thread_pointersi" 5242 [(set (match_operand:SI 0 "register_operand") (match_dup 1))] 5243 "" 5244 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);") 5245 5246(define_expand "set_thread_pointersi" 5247 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))] 5248 "" 5249 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);") 5250 5251;; If hardware floating point is available, don't define a negdf pattern; 5252;; it would be something like: 5253;;(define_insn "negdf2" 5254;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r") 5255;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D"))) 5256;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))] 5257;; "" 5258;; "@ 5259;; bxor%? %H0,%H1,31 5260;; bxor %H0,%H1,31 ` mov %L0,%L1 5261;; drsubh%F0%F1 0,0,0 5262;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0" 5263;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub") 5264;; (set_attr "iscompact" "false,false,false,false") 5265;; (set_attr "length" "4,4,8,12") 5266;; (set_attr "cond" "canuse,nocond,nocond,nocond")]) 5267;; and this suffers from always requiring a long immediate when using 5268;; the floating point hardware. 5269;; We then want the sub[sd]f patterns to be used, so that we can load the 5270;; constant zero efficiently into a register when we want to do the 5271;; computation using the floating point hardware. There should be a special 5272;; subdf alternative that matches a zero operand 1, which then can allow 5273;; to use bxor to flip the high bit of an integer register. 5274;; ??? we actually can't use the floating point hardware for neg, because 5275;; this would not work right for -0. OTOH optabs.c has already code 5276;; to synthesyze negate by flipping the sign bit. 5277 5278;;V2 instructions 5279(define_insn "bswapsi2" 5280 [(set (match_operand:SI 0 "register_operand" "= r,r") 5281 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))] 5282 "TARGET_V2 && TARGET_SWAP" 5283 "swape %0, %1" 5284 [(set_attr "length" "4,8") 5285 (set_attr "type" "two_cycle_core")]) 5286 5287(define_expand "prefetch" 5288 [(prefetch (match_operand:SI 0 "address_operand" "") 5289 (match_operand:SI 1 "const_int_operand" "") 5290 (match_operand:SI 2 "const_int_operand" ""))] 5291 "TARGET_HS" 5292 "") 5293 5294(define_insn "prefetch_1" 5295 [(prefetch (match_operand:SI 0 "register_operand" "r") 5296 (match_operand:SI 1 "const_int_operand" "n") 5297 (match_operand:SI 2 "const_int_operand" "n"))] 5298 "TARGET_HS" 5299 { 5300 if (INTVAL (operands[1])) 5301 return "prefetchw [%0]"; 5302 else 5303 return "prefetch [%0]"; 5304 } 5305 [(set_attr "type" "load") 5306 (set_attr "length" "4")]) 5307 5308(define_insn "prefetch_2" 5309 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r") 5310 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal")) 5311 (match_operand:SI 2 "const_int_operand" "n,n,n") 5312 (match_operand:SI 3 "const_int_operand" "n,n,n"))] 5313 "TARGET_HS" 5314 { 5315 if (INTVAL (operands[2])) 5316 return "prefetchw [%0, %1]"; 5317 else 5318 return "prefetch [%0, %1]"; 5319 } 5320 [(set_attr "type" "load") 5321 (set_attr "length" "4,4,8")]) 5322 5323(define_insn "prefetch_3" 5324 [(prefetch (match_operand:SI 0 "address_operand" "p") 5325 (match_operand:SI 1 "const_int_operand" "n") 5326 (match_operand:SI 2 "const_int_operand" "n"))] 5327 "TARGET_HS" 5328 { 5329 operands[0] = gen_rtx_MEM (SImode, operands[0]); 5330 if (INTVAL (operands[1])) 5331 return "prefetchw%U0 %0"; 5332 else 5333 return "prefetch%U0 %0"; 5334 } 5335 [(set_attr "type" "load") 5336 (set_attr "length" "8")]) 5337 5338(define_insn "divsi3" 5339 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r") 5340 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r") 5341 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))] 5342 "TARGET_DIVREM" 5343 "div%? %0, %1, %2" 5344 [(set_attr "length" "4,4,8,4,4,4,8,8") 5345 (set_attr "iscompact" "false") 5346 (set_attr "type" "div_rem") 5347 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no") 5348 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond") 5349 ]) 5350 5351(define_insn "udivsi3" 5352 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r") 5353 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r") 5354 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))] 5355 "TARGET_DIVREM" 5356 "divu%? %0, %1, %2" 5357 [(set_attr "length" "4,4,8,4,4,4,8,8") 5358 (set_attr "iscompact" "false") 5359 (set_attr "type" "div_rem") 5360 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no") 5361 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond") 5362 ]) 5363 5364(define_insn "modsi3" 5365 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r") 5366 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r") 5367 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))] 5368 "TARGET_DIVREM" 5369 "rem%? %0, %1, %2" 5370 [(set_attr "length" "4,4,8,4,4,4,8,8") 5371 (set_attr "iscompact" "false") 5372 (set_attr "type" "div_rem") 5373 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no") 5374 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond") 5375 ]) 5376 5377(define_insn "umodsi3" 5378 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r") 5379 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r") 5380 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))] 5381 "TARGET_DIVREM" 5382 "remu%? %0, %1, %2" 5383 [(set_attr "length" "4,4,8,4,4,4,8,8") 5384 (set_attr "iscompact" "false") 5385 (set_attr "type" "div_rem") 5386 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no") 5387 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond") 5388 ]) 5389 5390;; SETcc instructions 5391(define_code_iterator arcCC_cond [eq ne gt lt ge le]) 5392 5393(define_insn "arcset<code>" 5394 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") 5395 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r") 5396 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))] 5397 "TARGET_V2 && TARGET_CODE_DENSITY" 5398 "set<code>%? %0, %1, %2" 5399 [(set_attr "length" "4,4,4,4,4,8,8") 5400 (set_attr "iscompact" "false") 5401 (set_attr "type" "compare") 5402 (set_attr "predicable" "yes,no,yes,no,no,yes,no") 5403 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond") 5404 ]) 5405 5406(define_insn "arcsetltu" 5407 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r") 5408 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r") 5409 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))] 5410 "TARGET_V2 && TARGET_CODE_DENSITY" 5411 "setlo%? %0, %1, %2" 5412 [(set_attr "length" "4,4,4,4,4,8,8") 5413 (set_attr "iscompact" "false") 5414 (set_attr "type" "compare") 5415 (set_attr "predicable" "yes,no,yes,no,no,yes,no") 5416 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond") 5417 ]) 5418 5419(define_insn "arcsetgeu" 5420 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r") 5421 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r") 5422 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))] 5423 "TARGET_V2 && TARGET_CODE_DENSITY" 5424 "seths%? %0, %1, %2" 5425 [(set_attr "length" "4,4,4,4,4,8,8") 5426 (set_attr "iscompact" "false") 5427 (set_attr "type" "compare") 5428 (set_attr "predicable" "yes,no,yes,no,no,yes,no") 5429 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond") 5430 ]) 5431 5432;; Special cases of SETCC 5433(define_insn_and_split "arcsethi" 5434 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r") 5435 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r") 5436 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))] 5437 "TARGET_V2 && TARGET_CODE_DENSITY" 5438 "setlo%? %0, %2, %1" 5439 "reload_completed 5440 && CONST_INT_P (operands[2]) 5441 && satisfies_constraint_C62 (operands[2])" 5442 [(const_int 0)] 5443 "{ 5444 /* sethi a,b,u6 => seths a,b,u6 + 1. */ 5445 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 5446 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2])); 5447 DONE; 5448 }" 5449 [(set_attr "length" "4,4,4,8") 5450 (set_attr "iscompact" "false") 5451 (set_attr "type" "compare") 5452 (set_attr "predicable" "yes,no,no,no") 5453 (set_attr "cond" "canuse,nocond,nocond,nocond")] 5454) 5455 5456(define_insn_and_split "arcsetls" 5457 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r") 5458 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r") 5459 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))] 5460 "TARGET_V2 && TARGET_CODE_DENSITY" 5461 "seths%? %0, %2, %1" 5462 "reload_completed 5463 && CONST_INT_P (operands[2]) 5464 && satisfies_constraint_C62 (operands[2])" 5465 [(const_int 0)] 5466 "{ 5467 /* setls a,b,u6 => setlo a,b,u6 + 1. */ 5468 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 5469 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2])); 5470 DONE; 5471 }" 5472 [(set_attr "length" "4,4,4,8") 5473 (set_attr "iscompact" "false") 5474 (set_attr "type" "compare") 5475 (set_attr "predicable" "yes,no,no,no") 5476 (set_attr "cond" "canuse,nocond,nocond,nocond")] 5477) 5478 5479; Any mode that needs to be solved by secondary reload 5480(define_mode_iterator SRI [QI HI]) 5481 5482(define_expand "reload_<mode>_load" 5483 [(parallel [(match_operand:SRI 0 "register_operand" "=r") 5484 (match_operand:SRI 1 "memory_operand" "m") 5485 (match_operand:SI 2 "register_operand" "=&r")])] 5486 "" 5487{ 5488 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false); 5489 DONE; 5490}) 5491 5492(define_expand "reload_<mode>_store" 5493 [(parallel [(match_operand:SRI 0 "memory_operand" "=m") 5494 (match_operand:SRI 1 "register_operand" "r") 5495 (match_operand:SI 2 "register_operand" "=&r")])] 5496 "" 5497{ 5498 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true); 5499 DONE; 5500}) 5501 5502(define_insn "extzvsi" 5503 [(set (match_operand:SI 0 "register_operand" "=r , r,r,r") 5504 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r,r,0") 5505 (match_operand:SI 2 "const_int_operand" "C3p,C3p,n,n") 5506 (match_operand:SI 3 "const_int_operand" "n , n,n,n")))] 5507 "TARGET_HS && TARGET_BARREL_SHIFTER" 5508 { 5509 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f); 5510 operands[2] = GEN_INT (assemble_op2); 5511 return "xbfu%?\\t%0,%1,%2"; 5512 } 5513 [(set_attr "type" "shift") 5514 (set_attr "iscompact" "false") 5515 (set_attr "length" "4,4,8,8") 5516 (set_attr "predicable" "yes,no,no,yes") 5517 (set_attr "cond" "canuse,nocond,nocond,canuse_limm")]) 5518 5519(define_insn "kflag" 5520 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")] 5521 VUNSPEC_ARC_KFLAG)] 5522 "TARGET_V2" 5523 "@ 5524 kflag%? %0 5525 kflag %0 5526 kflag%? %0" 5527 [(set_attr "length" "4,4,8") 5528 (set_attr "type" "misc,misc,misc") 5529 (set_attr "predicable" "yes,no,yes") 5530 (set_attr "cond" "clob,clob,clob")]) 5531 5532(define_insn "clri" 5533 [(set (match_operand:SI 0 "dest_reg_operand" "=r") 5534 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")] 5535 VUNSPEC_ARC_CLRI))] 5536 "TARGET_V2" 5537 "clri %0" 5538 [(set_attr "length" "4") 5539 (set_attr "type" "misc")]) 5540 5541(define_insn "ffs" 5542 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 5543 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")] 5544 UNSPEC_ARC_FFS))] 5545 "TARGET_NORM && TARGET_V2" 5546 "@ 5547 ffs \t%0, %1 5548 ffs \t%0, %1" 5549 [(set_attr "length" "4,8") 5550 (set_attr "type" "two_cycle_core,two_cycle_core")]) 5551 5552(define_insn "ffs_f" 5553 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w") 5554 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")] 5555 UNSPEC_ARC_FFS)) 5556 (set (reg:CC_ZN CC_REG) 5557 (compare:CC_ZN (match_dup 1) (const_int 0)))] 5558 "TARGET_NORM && TARGET_V2" 5559 "@ 5560 ffs.f\t%0, %1 5561 ffs.f\t%0, %1" 5562 [(set_attr "length" "4,8") 5563 (set_attr "type" "two_cycle_core,two_cycle_core")]) 5564 5565(define_expand "ffssi2" 5566 [(parallel [(set (match_dup 2) 5567 (unspec:SI [(match_operand:SI 1 "register_operand" "")] 5568 UNSPEC_ARC_FFS)) 5569 (set (reg:CC_ZN CC_REG) 5570 (compare:CC_ZN (match_dup 1) (const_int 0)))]) 5571 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1))) 5572 (set (match_operand:SI 0 "dest_reg_operand" "") 5573 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0)) 5574 (const_int 0) 5575 (match_dup 2)))] 5576 "TARGET_NORM && TARGET_V2" 5577 { 5578 operands[2] = gen_reg_rtx (SImode); 5579 }) 5580 5581(define_insn "fls" 5582 [(set (match_operand:SI 0 "register_operand" "=r,r") 5583 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "rL,Cal")] 5584 UNSPEC_ARC_FLS))] 5585 "TARGET_NORM && TARGET_V2" 5586 "fls\\t%0,%1" 5587 [(set_attr "length" "4,8") 5588 (set_attr "type" "two_cycle_core,two_cycle_core")]) 5589 5590(define_insn "seti" 5591 [(unspec_volatile:SI [(match_operand:SI 0 "nonmemory_operand" "rL")] 5592 VUNSPEC_ARC_SETI)] 5593 "TARGET_V2" 5594 "seti\\t%0" 5595 [(set_attr "length" "4") 5596 (set_attr "type" "misc")]) 5597 5598;; FPU/FPX expands 5599 5600;;add 5601(define_expand "addsf3" 5602 [(set (match_operand:SF 0 "register_operand" "") 5603 (plus:SF (match_operand:SF 1 "nonmemory_operand" "") 5604 (match_operand:SF 2 "nonmemory_operand" "")))] 5605 "TARGET_FP_SP_BASE || TARGET_SPFP" 5606 " 5607 if (!register_operand (operands[1], SFmode) 5608 && !register_operand (operands[2], SFmode)) 5609 operands[1] = force_reg (SFmode, operands[1]); 5610 ") 5611 5612;;sub 5613(define_expand "subsf3" 5614 [(set (match_operand:SF 0 "register_operand" "") 5615 (minus:SF (match_operand:SF 1 "nonmemory_operand" "") 5616 (match_operand:SF 2 "nonmemory_operand" "")))] 5617 "TARGET_FP_SP_BASE || TARGET_SPFP" 5618 " 5619 if (!register_operand (operands[1], SFmode) 5620 && !register_operand (operands[2], SFmode)) 5621 operands[1] = force_reg (SFmode, operands[1]); 5622 ") 5623 5624;;mul 5625(define_expand "mulsf3" 5626 [(set (match_operand:SF 0 "register_operand" "") 5627 (mult:SF (match_operand:SF 1 "nonmemory_operand" "") 5628 (match_operand:SF 2 "nonmemory_operand" "")))] 5629 "TARGET_FP_SP_BASE || TARGET_SPFP" 5630 " 5631 if (!register_operand (operands[1], SFmode) 5632 && !register_operand (operands[2], SFmode)) 5633 operands[1] = force_reg (SFmode, operands[1]); 5634 ") 5635 5636;;add 5637(define_expand "adddf3" 5638 [(set (match_operand:DF 0 "double_register_operand" "") 5639 (plus:DF (match_operand:DF 1 "double_register_operand" "") 5640 (match_operand:DF 2 "nonmemory_operand" "")))] 5641 "TARGET_FP_DP_BASE || TARGET_DPFP" 5642 " 5643 if (TARGET_DPFP) 5644 { 5645 if (GET_CODE (operands[2]) == CONST_DOUBLE) 5646 { 5647 rtx first, second, tmp; 5648 split_double (operands[2], &first, &second); 5649 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); 5650 emit_insn (gen_adddf3_insn (operands[0], operands[1], 5651 operands[2], tmp, const0_rtx)); 5652 } 5653 else 5654 emit_insn (gen_adddf3_insn (operands[0], operands[1], 5655 operands[2], const1_rtx, const1_rtx)); 5656 DONE; 5657 } 5658 else if (TARGET_FP_DP_BASE) 5659 { 5660 if (!even_register_operand (operands[2], DFmode)) 5661 operands[2] = force_reg (DFmode, operands[2]); 5662 5663 if (!even_register_operand (operands[1], DFmode)) 5664 operands[1] = force_reg (DFmode, operands[1]); 5665 } 5666 else 5667 gcc_unreachable (); 5668 ") 5669 5670;;sub 5671(define_expand "subdf3" 5672 [(set (match_operand:DF 0 "double_register_operand" "") 5673 (minus:DF (match_operand:DF 1 "nonmemory_operand" "") 5674 (match_operand:DF 2 "nonmemory_operand" "")))] 5675 "TARGET_FP_DP_BASE || TARGET_DPFP" 5676 " 5677 if (TARGET_DPFP) 5678 { 5679 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE)) 5680 operands[1] = force_reg (DFmode, operands[1]); 5681 if ((GET_CODE (operands[1]) == CONST_DOUBLE) 5682 || GET_CODE (operands[2]) == CONST_DOUBLE) 5683 { 5684 rtx first, second, tmp; 5685 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2); 5686 split_double (operands[const_index], &first, &second); 5687 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); 5688 emit_insn (gen_subdf3_insn (operands[0], operands[1], 5689 operands[2], tmp, const0_rtx)); 5690 } 5691 else 5692 emit_insn (gen_subdf3_insn (operands[0], operands[1], 5693 operands[2], const1_rtx, const1_rtx)); 5694 DONE; 5695 } 5696 else if (TARGET_FP_DP_BASE) 5697 { 5698 if (!even_register_operand (operands[2], DFmode)) 5699 operands[2] = force_reg (DFmode, operands[2]); 5700 5701 if (!even_register_operand (operands[1], DFmode)) 5702 operands[1] = force_reg (DFmode, operands[1]); 5703 } 5704 else 5705 gcc_unreachable (); 5706 ") 5707 5708;;mul 5709(define_expand "muldf3" 5710 [(set (match_operand:DF 0 "double_register_operand" "") 5711 (mult:DF (match_operand:DF 1 "double_register_operand" "") 5712 (match_operand:DF 2 "nonmemory_operand" "")))] 5713 "TARGET_FP_DP_BASE || TARGET_DPFP" 5714 " 5715 if (TARGET_DPFP) 5716 { 5717 if (GET_CODE (operands[2]) == CONST_DOUBLE) 5718 { 5719 rtx first, second, tmp; 5720 split_double (operands[2], &first, &second); 5721 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); 5722 emit_insn (gen_muldf3_insn (operands[0], operands[1], 5723 operands[2], tmp, const0_rtx)); 5724 } 5725 else 5726 emit_insn (gen_muldf3_insn (operands[0], operands[1], 5727 operands[2], const1_rtx, const1_rtx)); 5728 DONE; 5729 } 5730 else if (TARGET_FP_DP_BASE) 5731 { 5732 if (!even_register_operand (operands[2], DFmode)) 5733 operands[2] = force_reg (DFmode, operands[2]); 5734 5735 if (!even_register_operand (operands[1], DFmode)) 5736 operands[1] = force_reg (DFmode, operands[1]); 5737 } 5738 else 5739 gcc_unreachable (); 5740 ") 5741 5742;;div 5743(define_expand "divsf3" 5744 [(set (match_operand:SF 0 "register_operand" "") 5745 (div:SF (match_operand:SF 1 "nonmemory_operand" "") 5746 (match_operand:SF 2 "nonmemory_operand" "")))] 5747 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" 5748 " 5749 if (TARGET_FPX_QUARK) 5750 { 5751 operands[1] = force_reg (SFmode, operands[1]); 5752 operands[2] = force_reg (SFmode, operands[2]); 5753 } 5754 else 5755 { 5756 if (!register_operand (operands[1], SFmode) 5757 && !register_operand (operands[2], SFmode)) 5758 operands[1] = force_reg (SFmode, operands[1]); 5759 } 5760 ") 5761 5762;; Square root 5763(define_expand "sqrtsf2" 5764 [(set (match_operand:SF 0 "register_operand" "") 5765 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))] 5766 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" 5767 " 5768 if (TARGET_FPX_QUARK) 5769 { 5770 operands[1] = force_reg (SFmode, operands[1]); 5771 } 5772") 5773 5774;; SF->SI (using rounding towards zero) 5775(define_expand "fix_truncsfsi2" 5776 [(set (match_operand:SI 0 "register_operand" "") 5777 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))] 5778 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV" 5779 "") 5780 5781;; SI->SF 5782(define_expand "floatsisf2" 5783 [(set (match_operand:SF 0 "register_operand" "") 5784 (float:SF (match_operand:SI 1 "register_operand" "")))] 5785 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV" 5786 "") 5787 5788(define_expand "extzv" 5789 [(set (match_operand:SI 0 "register_operand" "") 5790 (zero_extract:SI (match_operand:SI 1 "register_operand" "") 5791 (match_operand:SI 2 "const_int_operand" "") 5792 (match_operand:SI 3 "const_int_operand" "")))] 5793 "TARGET_NPS_BITOPS") 5794 5795; We need a sanity check in the instuction predicate because combine 5796; will throw any old rubbish at us and see what sticks. 5797(define_insn "*extzv_i" 5798 [(set (match_operand:SI 0 "register_operand" "=Rrq") 5799 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq") 5800 (match_operand:SI 2 "const_int_operand" "n") 5801 (match_operand:SI 3 "const_int_operand" "n")))] 5802 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32" 5803 "movb.cl %0,%1,0,%3,%2" 5804 [(set_attr "type" "shift") 5805 (set_attr "length" "4")]) 5806 5807(define_expand "insv" 5808 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") 5809 (match_operand:SI 1 "const_int_operand" "") 5810 (match_operand:SI 2 "const_int_operand" "")) 5811 (match_operand:SI 3 "nonmemory_operand" ""))] 5812 "TARGET_NPS_BITOPS" 5813{ 5814 int size = INTVAL (operands[1]); 5815 5816 if (size != 1 && size != 2 && size != 4 && size != 8) 5817 operands[3] = force_reg (SImode, operands[3]); 5818}) 5819 5820(define_insn "*insv_i" 5821 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq") 5822 (match_operand:SI 1 "const_int_operand" "C18,n") 5823 (match_operand:SI 2 "const_int_operand" "n,n")) 5824 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))] 5825 "TARGET_NPS_BITOPS 5826 && (register_operand (operands[3], SImode) 5827 || satisfies_constraint_C18 (operands[1]))" 5828 "@ 5829 movbi %0,%0,%3,%2,%1 5830 movb %0,%0,%3,%2,0,%1" 5831 [(set_attr "type" "shift") 5832 (set_attr "length" "4")]) 5833 5834(define_insn "*movb" 5835 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") 5836 (match_operand:SI 1 "const_int_operand" "n") 5837 (match_operand:SI 2 "const_int_operand" "n")) 5838 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq") 5839 (match_dup 1) 5840 (match_operand:SI 4 "const_int_operand" "n")))] 5841 "TARGET_NPS_BITOPS" 5842 "movb %0,%0,%3,%2,%4,%1" 5843 [(set_attr "type" "shift") 5844 (set_attr "length" "4")]) 5845 5846(define_insn "*movb_signed" 5847 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") 5848 (match_operand:SI 1 "const_int_operand" "n") 5849 (match_operand:SI 2 "const_int_operand" "n")) 5850 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq") 5851 (match_dup 1) 5852 (match_operand:SI 4 "const_int_operand" "n")))] 5853 "TARGET_NPS_BITOPS" 5854 "movb %0,%0,%3,%2,%4,%1" 5855 [(set_attr "type" "shift") 5856 (set_attr "length" "4")]) 5857 5858(define_insn "*movb_high" 5859 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") 5860 (match_operand:SI 1 "const_int_operand" "n") 5861 (match_operand:SI 2 "const_int_operand" "n")) 5862 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") 5863 (match_operand:SI 4 "const_int_operand" "n")))] 5864 "TARGET_NPS_BITOPS 5865 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" 5866 "movb %0,%0,%3,%2,%4,%1" 5867 [(set_attr "type" "shift") 5868 (set_attr "length" "4")]) 5869 5870; N.B.: when processing signed bitfields that fit in the top half of 5871; a word, gcc will use a narrow sign extending load, and in this case 5872; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8) 5873(define_insn "*movb_high_signed" 5874 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") 5875 (match_operand:SI 1 "const_int_operand" "n") 5876 (match_operand:SI 2 "const_int_operand" "n")) 5877 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") 5878 (match_operand:SI 4 "const_int_operand" "n")))] 5879 "TARGET_NPS_BITOPS 5880 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" 5881 "movb %0,%0,%3,%2,%4,%1" 5882 [(set_attr "type" "shift") 5883 (set_attr "length" "4")]) 5884 5885(define_split 5886 [(set (match_operand:SI 0 "register_operand" "") 5887 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "") 5888 (match_operand:SI 2 "const_int_operand" "")) 5889 (subreg:SI (match_operand 3 "") 0)))] 5890 "TARGET_NPS_BITOPS 5891 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2]) 5892 && !reg_overlap_mentioned_p (operands[0], operands[1])" 5893 [(set (match_dup 0) (zero_extend:SI (match_dup 3))) 5894 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2)) 5895 (match_dup 1))] 5896 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));") 5897 5898(define_insn "*mrgb" 5899 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") 5900 (match_operand:SI 1 "const_int_operand" "n") 5901 (match_operand:SI 2 "const_int_operand" "n")) 5902 (zero_extract:SI (match_dup 0) (match_dup 1) 5903 (match_operand:SI 3 "const_int_operand" "n"))) 5904 (set (zero_extract:SI (match_dup 0) 5905 (match_operand:SI 4 "const_int_operand" "n") 5906 (match_operand:SI 5 "const_int_operand" "n")) 5907 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq") 5908 (match_dup 4) 5909 (match_operand:SI 7 "const_int_operand" "n")))] 5910 "TARGET_NPS_BITOPS" 5911{ 5912 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands); 5913 /* The ;%? updates the known unalignment. */ 5914 return arc_short_long (insn, ";%?", "nop_s"); 5915} 5916 [(set_attr "type" "shift") 5917 (set_attr "length" "6") 5918 (set_attr "iscompact" "true")]) 5919 5920;; combine fumbles combination of two movb patterns, and then the 5921;; combination is rejected by combinable_i3pat. 5922;; Thus, we can only use a peephole2 to combine two such insns. 5923 5924(define_peephole2 5925 [(set (match_operand:SI 0 "register_operand" "") 5926 (match_operand:SI 1 "register_operand" "")) 5927 (set (zero_extract:SI (match_dup 0) 5928 (match_operand:SI 2 "const_int_operand" "") 5929 (match_operand:SI 3 "const_int_operand" "")) 5930 (zero_extract:SI (match_dup 1) 5931 (match_dup 2) 5932 (match_operand:SI 4 "const_int_operand" ""))) 5933 (match_operand 9) ; unrelated insn scheduled here 5934 (set (zero_extract:SI (match_dup 0) 5935 (match_operand:SI 5 "const_int_operand" "") 5936 (match_operand:SI 6 "const_int_operand" "")) 5937 (zero_extract:SI (match_operand:SI 7 "register_operand" "") 5938 (match_dup 5) 5939 (match_operand:SI 8 "const_int_operand" "")))] 5940 "TARGET_NPS_BITOPS 5941 // Check that the second movb doesn't clobber an input of the extra insn. 5942 && !reg_overlap_mentioned_p (operands[0], operands[9]) 5943 // And vice versa. 5944 && !reg_set_p (operands[0], operands[9]) 5945 && !reg_set_p (operands[7], operands[9])" 5946 [(set (match_dup 0) (match_dup 1)) 5947 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) 5948 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4))) 5949 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) 5950 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))]) 5951 (match_dup 9)]) 5952 5953(define_peephole2 5954 [(set (match_operand:SI 0 "register_operand" "") 5955 (match_operand:SI 1 "register_operand" "")) 5956 (set (zero_extract:SI (match_dup 0) 5957 (match_operand:SI 2 "const_int_operand" "") 5958 (match_operand:SI 3 "const_int_operand" "")) 5959 (zero_extract:SI (match_dup 1) 5960 (match_dup 2) 5961 (match_operand:SI 4 "const_int_operand" ""))) 5962 (set (match_dup 1) (match_operand 8)) 5963 (set (zero_extract:SI (match_dup 0) 5964 (match_operand:SI 5 "const_int_operand" "") 5965 (match_operand:SI 6 "const_int_operand" "")) 5966 (zero_extract:SI (match_dup 1) (match_dup 5) 5967 (match_operand:SI 7 "const_int_operand" "")))] 5968 "TARGET_NPS_BITOPS 5969 && !reg_overlap_mentioned_p (operands[0], operands[8])" 5970 [(set (match_dup 0) (match_dup 1)) 5971 (set (match_dup 1) (match_dup 8)) 5972 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3)) 5973 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4))) 5974 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6)) 5975 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) 5976 (match_dup 1)]) 5977 5978(define_insn "*rotrsi3_cnt1" 5979 [(set (match_operand:SI 0 "dest_reg_operand" "=w") 5980 (rotatert:SI (match_operand:SI 1 "register_operand" "c") 5981 (const_int 1)))] 5982 "" 5983 "ror %0,%1%&" 5984 [(set_attr "type" "shift") 5985 (set_attr "predicable" "no") 5986 (set_attr "length" "4")]) 5987 5988(define_insn "*ashlsi2_cnt1" 5989 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") 5990 (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c") 5991 (const_int 1)))] 5992 "" 5993 "asl%? %0,%1%&" 5994 [(set_attr "type" "shift") 5995 (set_attr "iscompact" "maybe,false") 5996 (set_attr "predicable" "no,no")]) 5997 5998(define_insn "*lshrsi3_cnt1" 5999 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") 6000 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") 6001 (const_int 1)))] 6002 "" 6003 "lsr%? %0,%1%&" 6004 [(set_attr "type" "shift") 6005 (set_attr "iscompact" "maybe,false") 6006 (set_attr "predicable" "no,no")]) 6007 6008(define_insn "*ashrsi3_cnt1" 6009 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") 6010 (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") 6011 (const_int 1)))] 6012 "" 6013 "asr%? %0,%1%&" 6014 [(set_attr "type" "shift") 6015 (set_attr "iscompact" "maybe,false") 6016 (set_attr "predicable" "no,no")]) 6017 6018(define_peephole2 6019 [(set (match_operand:SI 0 "register_operand" "") 6020 (zero_extract:SI (match_dup 0) 6021 (match_operand:SI 1 "const_int_operand" "") 6022 (match_operand:SI 2 "const_int_operand" ""))) 6023 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "") 6024 (match_dup 1) 6025 (match_dup 2)) 6026 (match_dup 0))] 6027 "TARGET_NPS_BITOPS 6028 && !reg_overlap_mentioned_p (operands[0], operands[3])" 6029 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2)) 6030 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))]) 6031 6032;; Dummy pattern used as a place holder for automatically saved 6033;; registers. 6034(define_insn "stack_irq_dwarf" 6035 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)] 6036 "" 6037 "" 6038 [(set_attr "length" "0")]) 6039 6040;; MAC and DMPY instructions 6041(define_expand "maddsidi4" 6042 [(match_operand:DI 0 "register_operand" "") 6043 (match_operand:SI 1 "register_operand" "") 6044 (match_operand:SI 2 "extend_operand" "") 6045 (match_operand:DI 3 "register_operand" "")] 6046 "TARGET_PLUS_DMPY" 6047 "{ 6048 emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3])); 6049 DONE; 6050 }") 6051 6052(define_insn_and_split "maddsidi4_split" 6053 [(set (match_operand:DI 0 "register_operand" "=r") 6054 (plus:DI 6055 (mult:DI 6056 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) 6057 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri"))) 6058 (match_operand:DI 3 "register_operand" "r"))) 6059 (clobber (reg:DI ARCV2_ACC))] 6060 "TARGET_PLUS_DMPY" 6061 "#" 6062 "TARGET_PLUS_DMPY && reload_completed" 6063 [(const_int 0)] 6064 "{ 6065 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); 6066 emit_move_insn (acc_reg, operands[3]); 6067 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)) 6068 emit_insn (gen_macd (operands[0], operands[1], operands[2])); 6069 else 6070 { 6071 emit_insn (gen_mac (operands[1], operands[2])); 6072 emit_move_insn (operands[0], acc_reg); 6073 } 6074 DONE; 6075 }" 6076 [(set_attr "type" "multi") 6077 (set_attr "length" "36")]) 6078 6079(define_insn "macd" 6080 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r") 6081 (plus:DI 6082 (mult:DI 6083 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c")) 6084 (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal"))) 6085 (reg:DI ARCV2_ACC))) 6086 (set (reg:DI ARCV2_ACC) 6087 (plus:DI 6088 (mult:DI (sign_extend:DI (match_dup 1)) 6089 (sign_extend:DI (match_dup 2))) 6090 (reg:DI ARCV2_ACC)))] 6091 "TARGET_PLUS_MACD" 6092 "macd %0,%1,%2" 6093 [(set_attr "length" "4,4,8") 6094 (set_attr "type" "multi") 6095 (set_attr "predicable" "yes,no,no") 6096 (set_attr "cond" "canuse,nocond,nocond")]) 6097 6098(define_insn "mac" 6099 [(set (reg:DI ARCV2_ACC) 6100 (plus:DI 6101 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r")) 6102 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i"))) 6103 (reg:DI ARCV2_ACC)))] 6104 "TARGET_PLUS_DMPY" 6105 "mac 0,%0,%1" 6106 [(set_attr "length" "4,8") 6107 (set_attr "type" "multi") 6108 (set_attr "predicable" "no") 6109 (set_attr "cond" "nocond")]) 6110 6111(define_peephole2 6112 [(set (reg:DI ARCV2_ACC) 6113 (plus:DI 6114 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "")) 6115 (sign_extend:DI (match_operand:SI 1 "extend_operand" ""))) 6116 (reg:DI ARCV2_ACC))) 6117 (set (match_operand:SI 2 "register_operand" "") 6118 (match_operand:SI 3 "accl_operand" ""))] 6119 "TARGET_PLUS_DMPY" 6120 [(const_int 0)] 6121 { 6122 emit_insn (gen_mac_r (operands[2], operands[0], operands[1])); 6123 DONE; 6124 }) 6125 6126(define_insn "mac_r" 6127 [(set (match_operand:SI 0 "register_operand" "=r,r") 6128 (truncate:SI 6129 (plus:DI 6130 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r")) 6131 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i"))) 6132 (reg:DI ARCV2_ACC)))) 6133 (clobber (reg:DI ARCV2_ACC))] 6134 "TARGET_PLUS_DMPY" 6135 "mac %0,%1,%2" 6136 [(set_attr "length" "4,8") 6137 (set_attr "type" "multi") 6138 (set_attr "predicable" "no") 6139 (set_attr "cond" "nocond")]) 6140 6141(define_expand "umaddsidi4" 6142 [(match_operand:DI 0 "register_operand" "") 6143 (match_operand:SI 1 "register_operand" "") 6144 (match_operand:SI 2 "extend_operand" "") 6145 (match_operand:DI 3 "register_operand" "")] 6146 "TARGET_PLUS_DMPY" 6147 "{ 6148 emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3])); 6149 DONE; 6150 }") 6151 6152(define_insn_and_split "umaddsidi4_split" 6153 [(set (match_operand:DI 0 "register_operand" "=r") 6154 (plus:DI 6155 (mult:DI 6156 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) 6157 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri"))) 6158 (match_operand:DI 3 "register_operand" "r"))) 6159 (clobber (reg:DI ARCV2_ACC))] 6160 "TARGET_PLUS_DMPY" 6161 "#" 6162 "TARGET_PLUS_DMPY && reload_completed" 6163 [(const_int 0)] 6164 "{ 6165 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); 6166 emit_move_insn (acc_reg, operands[3]); 6167 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)) 6168 emit_insn (gen_macdu (operands[0], operands[1], operands[2])); 6169 else 6170 { 6171 emit_insn (gen_macu (operands[1], operands[2])); 6172 emit_move_insn (operands[0], acc_reg); 6173 } 6174 DONE; 6175 }" 6176 [(set_attr "type" "multi") 6177 (set_attr "length" "36")]) 6178 6179(define_insn "macdu" 6180 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r") 6181 (plus:DI 6182 (mult:DI 6183 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c")) 6184 (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i"))) 6185 (reg:DI ARCV2_ACC))) 6186 (set (reg:DI ARCV2_ACC) 6187 (plus:DI 6188 (mult:DI (zero_extend:DI (match_dup 1)) 6189 (zero_extend:DI (match_dup 2))) 6190 (reg:DI ARCV2_ACC)))] 6191 "TARGET_PLUS_MACD" 6192 "macdu %0,%1,%2" 6193 [(set_attr "length" "4,4,8") 6194 (set_attr "type" "multi") 6195 (set_attr "predicable" "yes,no,no") 6196 (set_attr "cond" "canuse,nocond,nocond")]) 6197 6198(define_insn "macu" 6199 [(set (reg:DI ARCV2_ACC) 6200 (plus:DI 6201 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r")) 6202 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i"))) 6203 (reg:DI ARCV2_ACC)))] 6204 "TARGET_PLUS_DMPY" 6205 "macu 0,%0,%1" 6206 [(set_attr "length" "4,8") 6207 (set_attr "type" "multi") 6208 (set_attr "predicable" "no") 6209 (set_attr "cond" "nocond")]) 6210 6211(define_peephole2 6212 [(set (reg:DI ARCV2_ACC) 6213 (plus:DI 6214 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "")) 6215 (zero_extend:DI (match_operand:SI 1 "extend_operand" ""))) 6216 (reg:DI ARCV2_ACC))) 6217 (set (match_operand:SI 2 "register_operand" "") 6218 (match_operand:SI 3 "accl_operand" ""))] 6219 "TARGET_PLUS_DMPY" 6220 [(const_int 0)] 6221 { 6222 emit_insn (gen_macu_r (operands[2], operands[0], operands[1])); 6223 DONE; 6224 }) 6225 6226(define_insn "macu_r" 6227 [(set (match_operand:SI 0 "register_operand" "=r,r") 6228 (truncate:SI 6229 (plus:DI 6230 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r")) 6231 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i"))) 6232 (reg:DI ARCV2_ACC)))) 6233 (clobber (reg:DI ARCV2_ACC))] 6234 "TARGET_PLUS_DMPY" 6235 "macu %0,%1,%2" 6236 [(set_attr "length" "4,8") 6237 (set_attr "type" "multi") 6238 (set_attr "predicable" "no") 6239 (set_attr "cond" "nocond")]) 6240 6241(define_insn "mpyd_arcv2hs" 6242 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r") 6243 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c")) 6244 (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c")))) 6245 (set (reg:DI ARCV2_ACC) 6246 (mult:DI 6247 (sign_extend:DI (match_dup 1)) 6248 (sign_extend:DI (match_dup 2))))] 6249 "TARGET_PLUS_MACD" 6250 "mpyd%? %0,%1,%2" 6251 [(set_attr "length" "4,4") 6252 (set_attr "iscompact" "false") 6253 (set_attr "type" "multi") 6254 (set_attr "predicable" "yes,no") 6255 (set_attr "cond" "canuse,nocond")]) 6256 6257(define_insn "mpyd_imm_arcv2hs" 6258 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r") 6259 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c")) 6260 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal"))) 6261 (set (reg:DI ARCV2_ACC) 6262 (mult:DI (sign_extend:DI (match_dup 1)) 6263 (match_dup 2)))] 6264 "TARGET_PLUS_MACD" 6265 "mpyd%? %0,%1,%2" 6266 [(set_attr "length" "4,4,4,8,8") 6267 (set_attr "iscompact" "false") 6268 (set_attr "type" "multi") 6269 (set_attr "predicable" "yes,no,no,yes,no") 6270 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) 6271 6272(define_insn "mpydu_arcv2hs" 6273 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r") 6274 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c")) 6275 (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c")))) 6276 (set (reg:DI ARCV2_ACC) 6277 (mult:DI (zero_extend:DI (match_dup 1)) 6278 (zero_extend:DI (match_dup 2))))] 6279 "TARGET_PLUS_MACD" 6280 "mpydu%? %0,%1,%2" 6281 [(set_attr "length" "4,4") 6282 (set_attr "iscompact" "false") 6283 (set_attr "type" "multi") 6284 (set_attr "predicable" "yes,no") 6285 (set_attr "cond" "canuse,nocond")]) 6286 6287(define_insn "mpydu_imm_arcv2hs" 6288 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r") 6289 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c")) 6290 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal"))) 6291 (set (reg:DI ARCV2_ACC) 6292 (mult:DI (zero_extend:DI (match_dup 1)) 6293 (match_dup 2)))] 6294 "TARGET_PLUS_MACD" 6295 "mpydu%? %0,%1,%2" 6296 [(set_attr "length" "4,4,4,8,8") 6297 (set_attr "iscompact" "false") 6298 (set_attr "type" "multi") 6299 (set_attr "predicable" "yes,no,no,yes,no") 6300 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) 6301 6302(define_insn "*add_shift" 6303 [(set (match_operand:SI 0 "register_operand" "=q,r,r") 6304 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r") 6305 (match_operand:SI 2 "_1_2_3_operand" "")) 6306 (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] 6307 "" 6308 "add%2%?\\t%0,%3,%1" 6309 [(set_attr "length" "*,4,8") 6310 (set_attr "predicable" "yes,no,no") 6311 (set_attr "iscompact" "maybe,false,false") 6312 (set_attr "cond" "canuse,nocond,nocond")]) 6313 6314(define_insn "*add_shift2" 6315 [(set (match_operand:SI 0 "register_operand" "=q,r,r") 6316 (plus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal") 6317 (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r") 6318 (match_operand:SI 3 "_1_2_3_operand" ""))))] 6319 "" 6320 "add%3%?\\t%0,%1,%2" 6321 [(set_attr "length" "*,4,8") 6322 (set_attr "predicable" "yes,no,no") 6323 (set_attr "iscompact" "maybe,false,false") 6324 (set_attr "cond" "canuse,nocond,nocond")]) 6325 6326(define_insn "*sub_shift" 6327 [(set (match_operand:SI 0"register_operand" "=r,r,r") 6328 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal") 6329 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r") 6330 (match_operand:SI 3 "_1_2_3_operand" ""))))] 6331 "" 6332 "sub%3\\t%0,%1,%2" 6333 [(set_attr "length" "4,4,8") 6334 (set_attr "cond" "canuse,nocond,nocond") 6335 (set_attr "predicable" "yes,no,no")]) 6336 6337(define_insn "*sub_shift_cmp0_noout" 6338 [(set (match_operand 0 "cc_set_register" "") 6339 (compare:CC 6340 (minus:SI (match_operand:SI 1 "register_operand" "r") 6341 (ashift:SI (match_operand:SI 2 "register_operand" "r") 6342 (match_operand:SI 3 "_1_2_3_operand" ""))) 6343 (const_int 0)))] 6344 "" 6345 "sub%3.f\\t0,%1,%2" 6346 [(set_attr "length" "4")]) 6347 6348(define_insn "*compare_si_ashiftsi" 6349 [(set (match_operand 0 "cc_set_register" "") 6350 (compare:CC (match_operand:SI 1 "register_operand" "r") 6351 (ashift:SI (match_operand:SI 2 "register_operand" "r") 6352 (match_operand:SI 3 "_1_2_3_operand" ""))))] 6353 "" 6354 "sub%3.f\\t0,%1,%2" 6355 [(set_attr "length" "4")]) 6356 6357;; Convert the sequence 6358;; asl rd,rn,_1_2_3 6359;; cmp ra,rd 6360;; into 6361;; sub{123}.f 0,ra,rn 6362(define_peephole2 6363 [(set (match_operand:SI 0 "register_operand" "") 6364 (ashift:SI (match_operand:SI 1 "register_operand" "") 6365 (match_operand:SI 2 "_1_2_3_operand" ""))) 6366 (set (reg:CC CC_REG) 6367 (compare:CC (match_operand:SI 3 "register_operand" "") 6368 (match_dup 0)))] 6369 "peep2_reg_dead_p (2, operands[0])" 6370 [(set (reg:CC CC_REG) (compare:CC (match_dup 3) 6371 (ashift:SI (match_dup 1) (match_dup 2))))]) 6372 6373(define_peephole2 ; std 6374 [(set (match_operand:SI 2 "memory_operand" "") 6375 (match_operand:SI 0 "register_operand" "")) 6376 (set (match_operand:SI 3 "memory_operand" "") 6377 (match_operand:SI 1 "register_operand" ""))] 6378 "TARGET_LL64" 6379 [(const_int 0)] 6380{ 6381 if (!gen_operands_ldd_std (operands, false, false)) 6382 FAIL; 6383 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 6384 operands[2] = adjust_address (operands[2], DImode, 0); 6385 emit_insn (gen_rtx_SET (operands[2], operands[0])); 6386 DONE; 6387}) 6388 6389(define_peephole2 ; ldd 6390 [(set (match_operand:SI 0 "register_operand" "") 6391 (match_operand:SI 2 "memory_operand" "")) 6392 (set (match_operand:SI 1 "register_operand" "") 6393 (match_operand:SI 3 "memory_operand" ""))] 6394 "TARGET_LL64" 6395 [(const_int 0)] 6396{ 6397 if (!gen_operands_ldd_std (operands, true, false)) 6398 FAIL; 6399 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 6400 operands[2] = adjust_address (operands[2], DImode, 0); 6401 emit_insn (gen_rtx_SET (operands[0], operands[2])); 6402 DONE; 6403}) 6404 6405;; We require consecutive registers for LDD instruction. Check if we 6406;; can reorder them and use an LDD. 6407 6408(define_peephole2 ; swap the destination registers of two loads 6409 ; before a commutative operation. 6410 [(set (match_operand:SI 0 "register_operand" "") 6411 (match_operand:SI 2 "memory_operand" "")) 6412 (set (match_operand:SI 1 "register_operand" "") 6413 (match_operand:SI 3 "memory_operand" "")) 6414 (set (match_operand:SI 4 "register_operand" "") 6415 (match_operator:SI 5 "commutative_operator" 6416 [(match_operand 6 "register_operand" "") 6417 (match_operand 7 "register_operand" "") ]))] 6418 "TARGET_LL64 6419 && (((rtx_equal_p (operands[0], operands[6])) 6420 && (rtx_equal_p (operands[1], operands[7]))) 6421 || ((rtx_equal_p (operands[0], operands[7])) 6422 && (rtx_equal_p (operands[1], operands[6])))) 6423 && (peep2_reg_dead_p (3, operands[0]) 6424 || rtx_equal_p (operands[0], operands[4])) 6425 && (peep2_reg_dead_p (3, operands[1]) 6426 || rtx_equal_p (operands[1], operands[4]))" 6427 [(set (match_dup 0) (match_dup 2)) 6428 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))] 6429 { 6430 if (!gen_operands_ldd_std (operands, true, true)) 6431 { 6432 FAIL; 6433 } 6434 else 6435 { 6436 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 6437 operands[2] = adjust_address (operands[2], DImode, 0); 6438 } 6439 } 6440) 6441 6442(define_insn "*push_multi_fp" 6443 [(match_parallel 0 "push_multi_operand" 6444 [(set (reg:SI SP_REG) 6445 (plus:SI (reg:SI SP_REG) 6446 (match_operand 1 "immediate_operand" ""))) 6447 (set (mem:SI (plus:SI (reg:SI SP_REG) 6448 (match_operand 2 "immediate_operand" 6449 ""))) 6450 (reg:SI 13))])] 6451 "TARGET_CODE_DENSITY" 6452 { 6453 int len = XVECLEN (operands[0], 0); 6454 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6455 if (MEM_P (XEXP (tmp, 0))) 6456 { 6457 operands[3] = XEXP (tmp, 1); 6458 return "enter_s\\t{r13-%3} ; sp=sp+(%1)"; 6459 } 6460 else 6461 { 6462 tmp = XVECEXP (operands[0], 0, len - 3); 6463 operands[3] = XEXP (tmp, 1); 6464 return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)"; 6465 } 6466 } 6467 [(set_attr "type" "call_no_delay_slot") 6468 (set_attr "length" "2")]) 6469 6470(define_insn "*push_multi_fp_blink" 6471 [(match_parallel 0 "push_multi_operand" 6472 [(set (reg:SI SP_REG) 6473 (plus:SI (reg:SI SP_REG) 6474 (match_operand 1 "immediate_operand" ""))) 6475 (set (mem:SI (plus:SI (reg:SI SP_REG) 6476 (match_operand 2 "immediate_operand" 6477 ""))) 6478 (reg:SI RETURN_ADDR_REGNUM))])] 6479 "TARGET_CODE_DENSITY" 6480 { 6481 int len = XVECLEN (operands[0], 0); 6482 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6483 if (MEM_P (XEXP (tmp, 0))) 6484 { 6485 operands[3] = XEXP (tmp, 1); 6486 return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)"; 6487 } 6488 else 6489 { 6490 tmp = XVECEXP (operands[0], 0, len - 3); 6491 operands[3] = XEXP (tmp, 1); 6492 return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)"; 6493 } 6494 } 6495 [(set_attr "type" "call_no_delay_slot") 6496 (set_attr "length" "2")]) 6497 6498(define_insn "*pop_multi_fp" 6499 [(match_parallel 0 "pop_multi_operand" 6500 [(set (reg:SI SP_REG) 6501 (plus:SI (reg:SI SP_REG) 6502 (match_operand 1 "immediate_operand" ""))) 6503 (set (reg:SI 13) 6504 (mem:SI 6505 (plus:SI 6506 (reg:SI SP_REG) 6507 (match_operand 2 "immediate_operand" ""))))])] 6508 "TARGET_CODE_DENSITY" 6509 { 6510 int len = XVECLEN (operands[0], 0); 6511 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6512 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) 6513 { 6514 operands[3] = XEXP (tmp, 0); 6515 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); 6516 return "leave_s\\t{r13-%3} ; sp=sp+%1"; 6517 } 6518 else 6519 { 6520 tmp = XVECEXP (operands[0], 0, len - 2); 6521 operands[3] = XEXP (tmp, 0); 6522 return "leave_s\\t{r13-%3, fp} ; sp=sp+%1"; 6523 } 6524 } 6525 [(set_attr "type" "call_no_delay_slot") 6526 (set_attr "length" "2")]) 6527 6528(define_insn "*pop_multi_fp_blink" 6529 [(match_parallel 0 "pop_multi_operand" 6530 [(set (reg:SI SP_REG) 6531 (plus:SI (reg:SI SP_REG) 6532 (match_operand 1 "immediate_operand" ""))) 6533 (set (reg:SI RETURN_ADDR_REGNUM) 6534 (mem:SI 6535 (plus:SI 6536 (reg:SI SP_REG) 6537 (match_operand 2 "immediate_operand" ""))))])] 6538 "TARGET_CODE_DENSITY" 6539 { 6540 int len = XVECLEN (operands[0], 0); 6541 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6542 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) 6543 { 6544 operands[3] = XEXP (tmp, 0); 6545 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); 6546 return "leave_s\\t{r13-%3, blink} ; sp=sp+%1"; 6547 } 6548 else 6549 { 6550 tmp = XVECEXP (operands[0], 0, len - 2); 6551 operands[3] = XEXP (tmp, 0); 6552 return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1"; 6553 } 6554 } 6555 [(set_attr "type" "call_no_delay_slot") 6556 (set_attr "length" "2")]) 6557 6558(define_insn "*pop_multi_fp_ret" 6559 [(match_parallel 0 "pop_multi_operand" 6560 [(return) 6561 (set (reg:SI SP_REG) 6562 (plus:SI (reg:SI SP_REG) 6563 (match_operand 1 "immediate_operand" ""))) 6564 (set (reg:SI 13) 6565 (mem:SI 6566 (plus:SI 6567 (reg:SI SP_REG) 6568 (match_operand 2 "immediate_operand" ""))))])] 6569 "TARGET_CODE_DENSITY" 6570 { 6571 int len = XVECLEN (operands[0], 0); 6572 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6573 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) 6574 { 6575 operands[3] = XEXP (tmp, 0); 6576 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); 6577 return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1"; 6578 } 6579 else 6580 { 6581 tmp = XVECEXP (operands[0], 0, len - 2); 6582 operands[3] = XEXP (tmp, 0); 6583 return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1"; 6584 } 6585 } 6586 [(set_attr "type" "call_no_delay_slot") 6587 (set_attr "length" "2")]) 6588 6589(define_insn "*pop_multi_fp_blink_ret" 6590 [(match_parallel 0 "pop_multi_operand" 6591 [(return) 6592 (set (reg:SI SP_REG) 6593 (plus:SI (reg:SI SP_REG) 6594 (match_operand 1 "immediate_operand" ""))) 6595 (set (reg:SI RETURN_ADDR_REGNUM) 6596 (mem:SI 6597 (plus:SI 6598 (reg:SI SP_REG) 6599 (match_operand 2 "immediate_operand" ""))))])] 6600 "TARGET_CODE_DENSITY" 6601 { 6602 int len = XVECLEN (operands[0], 0); 6603 rtx tmp = XVECEXP (operands[0], 0, len - 1); 6604 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) 6605 { 6606 operands[3] = XEXP (tmp, 0); 6607 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); 6608 return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1"; 6609 } 6610 else 6611 { 6612 tmp = XVECEXP (operands[0], 0, len - 2); 6613 operands[3] = XEXP (tmp, 0); 6614 return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1"; 6615 } 6616 } 6617 [(set_attr "type" "call_no_delay_slot") 6618 (set_attr "length" "2")]) 6619 6620;; Patterns for exception handling 6621(define_insn_and_split "eh_return" 6622 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 6623 VUNSPEC_ARC_EH_RETURN)] 6624 "" 6625 "#" 6626 "reload_completed" 6627 [(const_int 0)] 6628 " 6629 { 6630 arc_eh_return_address_location (operands[0]); 6631 DONE; 6632 }" 6633) 6634;; include the arc-FPX instructions 6635(include "fpx.md") 6636 6637;; include the arc-FPU instructions 6638(include "fpu.md") 6639 6640(include "simdext.md") 6641 6642;; include atomic extensions 6643(include "atomic.md") 6644