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