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