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