1 ;; Machine description for GNU compiler, 2 ;; for ATMEL AVR micro controllers. 3 ;; Copyright (C) 1998-2024 Free Software Foundation, Inc. 4 ;; Contributed by Denis Chertykov (chertykov (a] gmail.com) 5 6 ;; This file is part of GCC. 7 8 ;; GCC is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation; either version 3, or (at your option) 11 ;; any later version. 12 13 ;; GCC is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with GCC; see the file COPYING3. If not see 20 ;; <http://www.gnu.org/licenses/>. 21 22 ;; Special characters after '%': 23 ;; A No effect (add 0). 24 ;; B Add 1 to REG number, MEM address or CONST_INT. 25 ;; C Add 2. 26 ;; D Add 3. 27 ;; E reg number in XEXP(x, 0). 28 ;; F Add 1 to reg number. 29 ;; I reg number in XEXP(XEXP(x, 0), 0). 30 ;; J Add 1 to reg number. 31 ;; j Branch condition. 32 ;; k Reverse branch condition. 33 ;;..m..Constant Direct Data memory address. 34 ;; i Print the SFR address equivalent of a CONST_INT or a CONST_INT 35 ;; RAM address. The resulting address is suitable to be used in IN/OUT. 36 ;; o Displacement for (mem (plus (reg) (const_int))) operands. 37 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z) 38 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30) 39 ;; r Print a REG without the register prefix 'r'. 40 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and 41 ;; bit number. This gets 2 operands: The first %T gets a REG_P and 42 ;; just cashes the operand for the next %T. The second %T gets 43 ;; a CONST_INT that represents a bit position. 44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13) 45 ;; "%T0%T1" it will print "r19,5". 46 ;; Notice that you must not write a comma between %T0 and %T1. 47 ;; T/t Similar to above, but don't print the comma and the bit number. 48 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13) 49 ;; "%T0%t1" it will print "r19". 50 ;;..x..Constant Direct Program memory address. 51 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL. 52 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL. 53 54 ;; Used in avr.cc to avoid magic numbers for register numbers. 55 (define_constants 56 [(REG_0 0) (REG_1 1) (REG_2 2) 57 (REG_8 8) (REG_9 9) (REG_10 10) (REG_11 11) 58 (REG_12 12) (REG_13 13) (REG_14 14) (REG_15 15) 59 (REG_16 16) (REG_17 17) (REG_18 18) (REG_19 19) 60 (REG_20 20) (REG_21 21) (REG_22 22) (REG_23 23) 61 (REG_24 24) (REG_25 25) (REG_26 26) (REG_27 27) 62 (REG_28 28) (REG_29 29) (REG_30 30) (REG_31 31) 63 (REG_32 32) (REG_36 36) 64 ]) 65 66 (define_constants 67 [(REG_X REG_26) 68 (REG_Y REG_28) 69 (REG_Z REG_30) 70 (REG_W REG_24) 71 (REG_SP REG_32) 72 (REG_CC REG_36) 73 (LPM_REGNO REG_0) ; implicit target register of LPM 74 (TMP_REGNO REG_0) ; temporary register r0 75 (ZERO_REGNO REG_1) ; zero register r1 76 ]) 77 78 (define_constants 79 [(TMP_REGNO_TINY REG_16) ; r16 is temp register for AVR_TINY 80 (ZERO_REGNO_TINY REG_17) ; r17 is zero register for AVR_TINY 81 ]) 82 83 (define_c_enum "unspec" 84 [UNSPEC_STRLEN 85 UNSPEC_CPYMEM 86 UNSPEC_INDEX_JMP 87 UNSPEC_FMUL 88 UNSPEC_FMULS 89 UNSPEC_FMULSU 90 UNSPEC_COPYSIGN 91 UNSPEC_INSERT_BITS 92 UNSPEC_ROUND 93 ]) 94 95 (define_c_enum "unspecv" 96 [UNSPECV_PROLOGUE_SAVES 97 UNSPECV_EPILOGUE_RESTORES 98 UNSPECV_WRITE_SP 99 UNSPECV_GASISR 100 UNSPECV_GOTO_RECEIVER 101 UNSPECV_ENABLE_IRQS 102 UNSPECV_MEMORY_BARRIER 103 UNSPECV_NOP 104 UNSPECV_SLEEP 105 UNSPECV_WDR 106 UNSPECV_DELAY_CYCLES 107 ]) 108 109 ;; Chunk numbers for __gcc_isr are hard-coded in GAS. 110 (define_constants 111 [(GASISR_Prologue 1) 112 (GASISR_Epilogue 2) 113 (GASISR_Done 0) 114 ]) 115 116 (include "predicates.md") 117 (include "constraints.md") 118 119 120 (define_attr "type" "branch,branch1,arith,xcall" 121 (const_string "arith")) 122 123 ;; The size of instructions in bytes. 124 ;; XXX may depend from "cc" 125 126 (define_attr "length" "" 127 (cond [(eq_attr "type" "branch") 128 (if_then_else (and (ge (minus (pc) (match_dup 0)) 129 (const_int -62)) 130 (le (minus (pc) (match_dup 0)) 131 (const_int 62))) 132 (const_int 1) 133 (if_then_else (and (ge (minus (pc) (match_dup 0)) 134 (const_int -2044)) 135 (le (minus (pc) (match_dup 0)) 136 (const_int 2045))) 137 (const_int 2) 138 (const_int 3))) 139 (eq_attr "type" "branch1") 140 (if_then_else (and (ge (minus (pc) (match_dup 0)) 141 (const_int -62)) 142 (le (minus (pc) (match_dup 0)) 143 (const_int 61))) 144 (const_int 2) 145 (if_then_else (and (ge (minus (pc) (match_dup 0)) 146 (const_int -2044)) 147 (le (minus (pc) (match_dup 0)) 148 (const_int 2043))) 149 (const_int 3) 150 (const_int 4))) 151 (eq_attr "type" "xcall") 152 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 153 (const_int 1) 154 (const_int 2))] 155 (const_int 2))) 156 157 ;; Lengths of several insns are adjusted in avr.cc:adjust_insn_length(). 158 ;; Following insn attribute tells if and how the adjustment has to be 159 ;; done: 160 ;; no No adjustment needed; attribute "length" is fine. 161 ;; Otherwise do special processing depending on the attribute. 162 163 (define_attr "adjust_len" 164 "out_bitop, plus, addto_sp, sext, extr, extr_not, 165 tsthi, tstpsi, tstsi, compare, compare64, call, 166 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32, 167 ufract, sfract, round, 168 xload, cpymem, 169 ashlqi, ashrqi, lshrqi, 170 ashlhi, ashrhi, lshrhi, 171 ashlsi, ashrsi, lshrsi, 172 ashlpsi, ashrpsi, lshrpsi, 173 insert_bits, insv_notbit, insv, 174 add_set_ZN, cmp_uext, cmp_sext, 175 no" 176 (const_string "no")) 177 178 ;; Flavours of instruction set architecture (ISA), used in enabled attribute 179 180 ;; mov : ISA has no MOVW movw : ISA has MOVW 181 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP 182 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP 183 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX 184 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX 185 ;; no_xmega: non-XMEGA core xmega : XMEGA core 186 ;; no_adiw: ISA has no ADIW, SBIW adiw : ISA has ADIW, SBIW 187 188 (define_attr "isa" 189 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, 190 no_adiw,adiw, 191 standard" 192 (const_string "standard")) 193 194 (define_attr "enabled" "" 195 (cond [(eq_attr "isa" "standard") 196 (const_int 1) 197 198 (and (eq_attr "isa" "mov") 199 (match_test "!AVR_HAVE_MOVW")) 200 (const_int 1) 201 202 (and (eq_attr "isa" "movw") 203 (match_test "AVR_HAVE_MOVW")) 204 (const_int 1) 205 206 (and (eq_attr "isa" "rjmp") 207 (match_test "!AVR_HAVE_JMP_CALL")) 208 (const_int 1) 209 210 (and (eq_attr "isa" "jmp") 211 (match_test "AVR_HAVE_JMP_CALL")) 212 (const_int 1) 213 214 (and (eq_attr "isa" "ijmp") 215 (match_test "!AVR_HAVE_EIJMP_EICALL")) 216 (const_int 1) 217 218 (and (eq_attr "isa" "eijmp") 219 (match_test "AVR_HAVE_EIJMP_EICALL")) 220 (const_int 1) 221 222 (and (eq_attr "isa" "lpm") 223 (match_test "!AVR_HAVE_LPMX")) 224 (const_int 1) 225 226 (and (eq_attr "isa" "lpmx") 227 (match_test "AVR_HAVE_LPMX")) 228 (const_int 1) 229 230 (and (eq_attr "isa" "elpm") 231 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX")) 232 (const_int 1) 233 234 (and (eq_attr "isa" "elpmx") 235 (match_test "AVR_HAVE_ELPMX")) 236 (const_int 1) 237 238 (and (eq_attr "isa" "xmega") 239 (match_test "AVR_XMEGA")) 240 (const_int 1) 241 242 (and (eq_attr "isa" "no_xmega") 243 (match_test "!AVR_XMEGA")) 244 (const_int 1) 245 246 (and (eq_attr "isa" "adiw") 247 (match_test "AVR_HAVE_ADIW")) 248 (const_int 1) 249 250 (and (eq_attr "isa" "no_adiw") 251 (match_test "!AVR_HAVE_ADIW")) 252 (const_int 1) 253 254 ] (const_int 0))) 255 256 257 ;; Define mode iterators 258 (define_mode_iterator QIHI [QI HI]) 259 (define_mode_iterator QIHI2 [QI HI]) 260 (define_mode_iterator QISI [QI HI PSI SI]) 261 (define_mode_iterator QIDI [QI HI PSI SI DI]) 262 (define_mode_iterator QIPSI [QI HI PSI]) 263 (define_mode_iterator HISI [HI PSI SI]) 264 265 ;; Ordered integral and fixed-point modes of specific sizes. 266 (define_mode_iterator ALL1 [QI QQ UQQ]) 267 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA]) 268 (define_mode_iterator ALL4 [SI SQ USQ SA USA]) 269 (define_mode_iterator ALL234 [HI SI PSI 270 HQ UHQ HA UHA 271 SQ USQ SA USA]) 272 273 ;; Ordered signed integral and signed fixed-point modes of specific sizes. 274 (define_mode_iterator ALLs1 [QI QQ]) 275 (define_mode_iterator ALLs2 [HI HQ HA]) 276 (define_mode_iterator ALLs4 [SI SQ SA]) 277 (define_mode_iterator ALLs234 [HI SI PSI 278 HQ HA SQ SA]) 279 280 ;; All supported move-modes 281 (define_mode_iterator MOVMODE [QI QQ UQQ 282 HI HQ UHQ HA UHA 283 SI SQ USQ SA USA 284 SF PSI]) 285 286 ;; Supported ordered modes that are 2, 3, 4 bytes wide 287 (define_mode_iterator ORDERED234 [HI SI PSI 288 HQ UHQ HA UHA 289 SQ USQ SA USA]) 290 291 ;; Post-reload split of 3, 4 bytes wide moves. 292 (define_mode_iterator SPLIT34 [SI SF PSI 293 SQ USQ SA USA]) 294 295 (define_mode_iterator SFDF [SF DF]) 296 297 ;; Where the most significant bit is located. 298 (define_mode_attr MSB [(QI "7") (QQ "7") (UQQ "7") 299 (HI "15") (HQ "15") (UHQ "15") (HA "15") (UHA "15") 300 (PSI "23") 301 (SI "31") (SQ "31") (USQ "31") (SA "31") (USA "31") (SF "31")]) 302 303 ;; Size in bytes of the mode. 304 (define_mode_attr SIZE [(QI "1") (QQ "1") (UQQ "1") 305 (HI "2") (HQ "2") (UHQ "2") (HA "2") (UHA "2") 306 (PSI "3") 307 (SI "4") (SQ "4") (USQ "4") (SA "4") (USA "4") (SF "4")]) 308 309 ;; Define code iterators 310 ;; Define two incarnations so that we can build the cartesian product. 311 (define_code_iterator any_extend [sign_extend zero_extend]) 312 (define_code_iterator any_extend2 [sign_extend zero_extend]) 313 (define_code_iterator any_extract [sign_extract zero_extract]) 314 (define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 315 (define_code_iterator any_shift [lshiftrt ashiftrt ashift]) 316 317 (define_code_iterator piaop [plus ior and]) 318 (define_code_iterator bitop [xor ior and]) 319 (define_code_iterator xior [xor ior]) 320 (define_code_iterator eqne [eq ne]) 321 (define_code_iterator gelt [ge lt]) 322 323 (define_code_iterator ss_addsub [ss_plus ss_minus]) 324 (define_code_iterator us_addsub [us_plus us_minus]) 325 (define_code_iterator ss_abs_neg [ss_abs ss_neg]) 326 327 ;; Define code attributes 328 (define_code_attr extend_su 329 [(sign_extend "s") 330 (zero_extend "u")]) 331 332 (define_code_attr extend_u 333 [(sign_extend "") 334 (zero_extend "u")]) 335 336 (define_code_attr extend_s 337 [(sign_extend "s") 338 (zero_extend "")]) 339 340 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS. 341 (define_code_attr mul_r_d 342 [(zero_extend "r") 343 (sign_extend "d")]) 344 345 (define_code_attr abelian 346 [(ss_minus "") (us_minus "") 347 (ss_plus "%") (us_plus "%")]) 348 349 (define_code_attr gelt_eqne 350 [(ge "eq") 351 (lt "ne")]) 352 353 ;; Map RTX code to its standard insn name 354 (define_code_attr code_stdname 355 [(ashift "ashl") 356 (ashiftrt "ashr") 357 (lshiftrt "lshr") 358 (ior "ior") 359 (xor "xor") 360 (rotate "rotl") 361 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs") 362 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg") 363 ]) 364 365 ;;======================================================================== 366 ;; The following is used by nonlocal_goto and setjmp. 367 ;; The receiver pattern will create no instructions since internally 368 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28 369 ;; This avoids creating add/sub offsets in frame_pointer save/resore. 370 ;; The 'null' receiver also avoids problems with optimisation 371 ;; not recognising incoming jmp and removing code that resets frame_pointer. 372 ;; The code derived from builtins.cc. 373 374 (define_expand "nonlocal_goto_receiver" 375 [(set (reg:HI REG_Y) 376 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))] 377 "" 378 { 379 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode); 380 emit_move_insn (virtual_stack_vars_rtx, 381 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset)); 382 // This might change the hard frame pointer in ways that aren't 383 // apparent to early optimization passes, so force a clobber. 384 emit_clobber (hard_frame_pointer_rtx); 385 DONE; 386 }) 387 388 389 ;; Defining nonlocal_goto_receiver means we must also define this 390 ;; even though its function is identical to that in builtins.cc 391 392 (define_expand "nonlocal_goto" 393 [(use (match_operand 0 "general_operand")) 394 (use (match_operand 1 "general_operand")) 395 (use (match_operand 2 "general_operand")) 396 (use (match_operand 3 "general_operand"))] 397 "" 398 { 399 rtx r_label = copy_to_reg (operands[1]); 400 rtx r_fp = operands[3]; 401 rtx r_sp = operands[2]; 402 403 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 404 405 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 406 407 // PR64242: When r_sp is located in the frame, we must not 408 // change FP prior to reading r_sp. Hence copy r_fp to a 409 // local register (and hope that reload won't spill it). 410 rtx r_fp_reg = copy_to_reg (r_fp); 411 emit_stack_restore (SAVE_NONLOCAL, r_sp); 412 413 emit_move_insn (hard_frame_pointer_rtx, r_fp_reg); 414 415 emit_use (hard_frame_pointer_rtx); 416 emit_use (stack_pointer_rtx); 417 418 emit_indirect_jump (r_label); 419 420 DONE; 421 }) 422 423 ;; "pushqi1" 424 ;; "pushqq1" "pushuqq1" 425 (define_insn "push<mode>1" 426 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP))) 427 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))] 428 "" 429 "@ 430 push %0 431 push __zero_reg__" 432 [(set_attr "length" "1,1")]) 433 434 (define_insn "pushhi1_insn" 435 [(set (mem:HI (post_dec:HI (reg:HI REG_SP))) 436 (match_operand:HI 0 "register_operand" "r"))] 437 "" 438 "push %B0\;push %A0" 439 [(set_attr "length" "2")]) 440 441 ;; All modes for a multi-byte push. We must include complex modes here too, 442 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself. 443 (define_mode_iterator MPUSH 444 [CQI 445 HI CHI HA UHA HQ UHQ 446 SI CSI SA USA SQ USQ 447 DI CDI DA UDA DQ UDQ 448 TA UTA 449 SF DF SC DC 450 PSI]) 451 452 (define_expand "push<mode>1" 453 [(match_operand:MPUSH 0 "" "")] 454 "" 455 { 456 if (MEM_P (operands[0]) 457 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0]))) 458 { 459 // Avoid (subreg (mem)) for non-generic address spaces. Because 460 // of the poor addressing capabilities of these spaces it's better to 461 // load them in one chunk. And it avoids PR61443. 462 463 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]); 464 } 465 else if (REG_P (operands[0]) 466 && VIRTUAL_REGISTER_P (operands[0])) 467 { 468 // Byte-wise pushing of virtual regs might result in something like 469 // 470 // (set (mem:QI (post_dec:HI (reg:HI 32 SP))) 471 // (subreg:QI (plus:HI (reg:HI 28) 472 // (const_int 17)) 0)) 473 // 474 // after elimination. This cannot be handled by reload, cf. PR64452. 475 // Reload virtuals in one chunk. That way it's possible to reload 476 // above situation and finally 477 // 478 // (set (reg:HI **) 479 // (const_int 17)) 480 // (set (reg:HI **) 481 // (plus:HI (reg:HI **) 482 // (reg:HI 28))) 483 // (set (mem:HI (post_dec:HI (reg:HI 32 SP)) 484 // (reg:HI **))) 485 486 emit_insn (gen_pushhi1_insn (operands[0])); 487 DONE; 488 } 489 490 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i) 491 { 492 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); 493 if (part != const0_rtx) 494 part = force_reg (QImode, part); 495 emit_insn (gen_pushqi1 (part)); 496 } 497 DONE; 498 }) 499 500 ;; Notice a special-case when adding N to SP where N results in a 501 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP. 502 (define_split 503 [(set (reg:HI REG_SP) 504 (match_operand:HI 0 "register_operand" ""))] 505 "reload_completed 506 && frame_pointer_needed 507 && !cfun->calls_alloca 508 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx) 509 && REGNO (operands[0]) != REG_Y" 510 [(set (reg:HI REG_SP) 511 (reg:HI REG_Y))]) 512 513 ;;======================================================================== 514 ;; Move stuff around 515 516 ;; "loadqi_libgcc" 517 ;; "loadhi_libgcc" 518 ;; "loadpsi_libgcc" 519 ;; "loadsi_libgcc" 520 ;; "loadsf_libgcc" 521 (define_expand "load<mode>_libgcc" 522 [(set (match_dup 3) 523 (match_dup 2)) 524 (set (reg:MOVMODE 22) 525 (match_operand:MOVMODE 1 "memory_operand" "")) 526 (set (match_operand:MOVMODE 0 "register_operand" "") 527 (reg:MOVMODE 22))] 528 "avr_load_libgcc_p (operands[1])" 529 { 530 operands[3] = gen_rtx_REG (HImode, REG_Z); 531 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX); 532 operands[1] = replace_equiv_address (operands[1], operands[3]); 533 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH); 534 }) 535 536 ;; "load_qi_libgcc" 537 ;; "load_hi_libgcc" 538 ;; "load_psi_libgcc" 539 ;; "load_si_libgcc" 540 ;; "load_sf_libgcc" 541 (define_insn_and_split "load_<mode>_libgcc" 542 [(set (reg:MOVMODE 22) 543 (match_operand:MOVMODE 0 "memory_operand" "m,m"))] 544 "avr_load_libgcc_p (operands[0]) 545 && REG_P (XEXP (operands[0], 0)) 546 && REG_Z == REGNO (XEXP (operands[0], 0))" 547 "#" 548 "&& reload_completed" 549 [(parallel [(set (reg:MOVMODE 22) 550 (match_dup 0)) 551 (clobber (reg:CC REG_CC))])] 552 "" 553 [(set_attr "isa" "rjmp,jmp")]) 554 555 (define_insn "*load_<mode>_libgcc" 556 [(set (reg:MOVMODE 22) 557 (match_operand:MOVMODE 0 "memory_operand" "m,m")) 558 (clobber (reg:CC REG_CC))] 559 "avr_load_libgcc_p (operands[0]) 560 && REG_P (XEXP (operands[0], 0)) 561 && REG_Z == REGNO (XEXP (operands[0], 0)) 562 && reload_completed" 563 { 564 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode)); 565 return "%~call __load_%0"; 566 } 567 [(set_attr "length" "1,2") 568 (set_attr "isa" "rjmp,jmp")]) 569 570 571 ;; "xload8qi_A" 572 ;; "xload8qq_A" "xload8uqq_A" 573 (define_insn_and_split "xload8<mode>_A" 574 [(set (match_operand:ALL1 0 "register_operand" "=r") 575 (match_operand:ALL1 1 "memory_operand" "m")) 576 (clobber (reg:HI REG_Z))] 577 "can_create_pseudo_p() 578 && !avr_xload_libgcc_p (<MODE>mode) 579 && avr_mem_memx_p (operands[1]) 580 && REG_P (XEXP (operands[1], 0))" 581 { gcc_unreachable(); } 582 "&& 1" 583 [(clobber (const_int 0))] 584 { 585 // Split away the high part of the address. GCC's register allocator 586 // is not able to allocate segment registers and reload the resulting 587 // expressions. Notice that no address register can hold a PSImode. 588 589 rtx addr = XEXP (operands[1], 0); 590 rtx hi8 = gen_reg_rtx (QImode); 591 rtx reg_z = gen_rtx_REG (HImode, REG_Z); 592 593 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); 594 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2)); 595 596 rtx_insn *insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8)); 597 set_mem_addr_space (SET_SRC (single_set (insn)), 598 MEM_ADDR_SPACE (operands[1])); 599 DONE; 600 }) 601 602 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A" 603 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A" 604 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A" 605 ;; "xloadpsi_A" 606 ;; "xloadsf_A" 607 (define_insn_and_split "xload<mode>_A" 608 [(set (match_operand:MOVMODE 0 "register_operand" "=r") 609 (match_operand:MOVMODE 1 "memory_operand" "m")) 610 (clobber (reg:MOVMODE 22)) 611 (clobber (reg:QI 21)) 612 (clobber (reg:HI REG_Z))] 613 "can_create_pseudo_p() 614 && avr_mem_memx_p (operands[1]) 615 && REG_P (XEXP (operands[1], 0))" 616 { gcc_unreachable(); } 617 "&& 1" 618 [(clobber (const_int 0))] 619 { 620 rtx addr = XEXP (operands[1], 0); 621 rtx reg_z = gen_rtx_REG (HImode, REG_Z); 622 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2); 623 addr_space_t as = MEM_ADDR_SPACE (operands[1]); 624 625 // Split the address to R21:Z 626 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); 627 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8); 628 629 // Load with code from libgcc. 630 rtx_insn *insn = emit_insn (gen_xload_<mode>_libgcc ()); 631 set_mem_addr_space (SET_SRC (single_set (insn)), as); 632 633 // Move to destination. 634 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22)); 635 636 DONE; 637 }) 638 639 ;; Move value from address space memx to a register 640 ;; These insns must be prior to respective generic move insn. 641 642 ;; "xloadqi_8" 643 ;; "xloadqq_8" "xloaduqq_8" 644 (define_insn "xload<mode>_8" 645 [(set (match_operand:ALL1 0 "register_operand" "=&r,r") 646 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r") 647 (reg:HI REG_Z))))] 648 "!avr_xload_libgcc_p (<MODE>mode)" 649 { 650 return avr_out_xload (insn, operands, NULL); 651 } 652 [(set_attr "length" "4,4") 653 (set_attr "adjust_len" "*,xload") 654 (set_attr "isa" "lpmx,lpm")]) 655 656 ;; R21:Z : 24-bit source address 657 ;; R22 : 1-4 byte output 658 659 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc" 660 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc" 661 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc" 662 ;; "xload_sf_libgcc" 663 ;; "xload_psi_libgcc" 664 665 (define_insn_and_split "xload_<mode>_libgcc" 666 [(set (reg:MOVMODE 22) 667 (mem:MOVMODE (lo_sum:PSI (reg:QI 21) 668 (reg:HI REG_Z)))) 669 (clobber (reg:QI 21)) 670 (clobber (reg:HI REG_Z))] 671 "avr_xload_libgcc_p (<MODE>mode)" 672 "#" 673 "&& reload_completed" 674 [(parallel [(set (reg:MOVMODE 22) 675 (mem:MOVMODE (lo_sum:PSI (reg:QI 21) 676 (reg:HI REG_Z)))) 677 (clobber (reg:QI 21)) 678 (clobber (reg:HI REG_Z)) 679 (clobber (reg:CC REG_CC))])]) 680 681 (define_insn "*xload_<mode>_libgcc" 682 [(set (reg:MOVMODE 22) 683 (mem:MOVMODE (lo_sum:PSI (reg:QI 21) 684 (reg:HI REG_Z)))) 685 (clobber (reg:QI 21)) 686 (clobber (reg:HI REG_Z)) 687 (clobber (reg:CC REG_CC))] 688 "avr_xload_libgcc_p (<MODE>mode) 689 && reload_completed" 690 { 691 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode)); 692 693 output_asm_insn ("%~call __xload_%0", &x_bytes); 694 return ""; 695 } 696 [(set_attr "type" "xcall")]) 697 698 699 ;; General move expanders 700 701 ;; "movqi" "movqq" "movuqq" 702 ;; "movhi" "movhq" "movuhq" "movha" "movuha" 703 ;; "movsi" "movsq" "movusq" "movsa" "movusa" 704 ;; "movsf" 705 ;; "movpsi" 706 (define_expand "mov<mode>" 707 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") 708 (match_operand:MOVMODE 1 "general_operand" ""))] 709 "" 710 { 711 rtx dest = operands[0]; 712 rtx src = avr_eval_addr_attrib (operands[1]); 713 714 if (avr_mem_flash_p (dest)) 715 DONE; 716 717 if (QImode == <MODE>mode 718 && SUBREG_P (src) 719 && CONSTANT_ADDRESS_P (SUBREG_REG (src)) 720 && can_create_pseudo_p()) 721 { 722 // store_bitfield may want to store a SYMBOL_REF or CONST in a 723 // structure that's represented as PSImode. As the upper 16 bits 724 // of PSImode cannot be expressed as an HImode subreg, the rhs is 725 // decomposed into QImode (word_mode) subregs of SYMBOL_REF, 726 // CONST or LABEL_REF; cf. PR71103. 727 728 rtx const_addr = SUBREG_REG (src); 729 operands[1] = src = copy_rtx (src); 730 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr); 731 } 732 733 // One of the operands has to be in a register. 734 if (!register_operand (dest, <MODE>mode) 735 && !reg_or_0_operand (src, <MODE>mode)) 736 { 737 operands[1] = src = copy_to_mode_reg (<MODE>mode, src); 738 } 739 740 if (avr_mem_memx_p (src)) 741 { 742 rtx addr = XEXP (src, 0); 743 744 if (!REG_P (addr)) 745 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr)); 746 747 rtx dest2 = reg_overlap_mentioned_p (dest, lpm_addr_reg_rtx) 748 ? gen_reg_rtx (<MODE>mode) 749 : dest; 750 751 if (!avr_xload_libgcc_p (<MODE>mode)) 752 // No <mode> here because gen_xload8<mode>_A only iterates over ALL1. 753 // insn-emit does not depend on the mode, it's all about operands. 754 emit_insn (gen_xload8qi_A (dest2, src)); 755 else 756 { 757 rtx reg_22 = gen_rtx_REG (<MODE>mode, REG_22); 758 if (reg_overlap_mentioned_p (dest2, reg_22) 759 || reg_overlap_mentioned_p (dest2, all_regs_rtx[REG_21])) 760 dest2 = gen_reg_rtx (<MODE>mode); 761 762 emit_insn (gen_xload<mode>_A (dest2, src)); 763 } 764 765 if (dest2 != dest) 766 emit_move_insn (dest, dest2); 767 768 DONE; 769 } 770 771 if (avr_load_libgcc_p (src)) 772 { 773 // For the small devices, do loads per libgcc call. 774 emit_insn (gen_load<mode>_libgcc (dest, src)); 775 DONE; 776 } 777 }) 778 779 ;;======================================================================== 780 ;; move byte 781 ;; The last alternative (any immediate constant to any register) is 782 ;; very expensive. It should be optimized by peephole2 if a scratch 783 ;; register is available, but then that register could just as well be 784 ;; allocated for the variable we are loading. But, most of NO_LD_REGS 785 ;; are call-saved registers, and most of LD_REGS are call-used registers, 786 ;; so this may still be a win for registers live across function calls. 787 788 (define_insn_and_split "mov<mode>_insn_split" 789 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") 790 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] 791 "register_operand (operands[0], <MODE>mode) 792 || reg_or_0_operand (operands[1], <MODE>mode)" 793 "#" 794 "&& reload_completed" 795 [(parallel [(set (match_dup 0) 796 (match_dup 1)) 797 (clobber (reg:CC REG_CC))])]) 798 799 ;; "movqi_insn" 800 ;; "movqq_insn" "movuqq_insn" 801 (define_insn "mov<mode>_insn" 802 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") 803 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i")) 804 (clobber (reg:CC REG_CC))] 805 "(register_operand (operands[0], <MODE>mode) 806 || reg_or_0_operand (operands[1], <MODE>mode)) 807 && reload_completed" 808 { 809 return output_movqi (insn, operands, NULL); 810 } 811 [(set_attr "length" "1,1,5,5,1,1,4") 812 (set_attr "adjust_len" "mov8")]) 813 814 ;; This is used in peephole2 to optimize loading immediate constants 815 ;; if a scratch register from LD_REGS happens to be available. 816 817 ;; "*reload_inqi" 818 ;; "*reload_inqq" "*reload_inuqq" 819 (define_insn "*reload_in<mode>" 820 [(set (match_operand:ALL1 0 "register_operand" "=l") 821 (match_operand:ALL1 1 "const_operand" "i")) 822 (clobber (match_operand:QI 2 "register_operand" "=&d")) 823 (clobber (reg:CC REG_CC))] 824 "reload_completed" 825 "ldi %2,lo8(%1) 826 mov %0,%2" 827 [(set_attr "length" "2")]) 828 829 (define_peephole2 830 [(match_scratch:QI 2 "d") 831 (parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 832 (match_operand:ALL1 1 "const_operand" "")) 833 (clobber (reg:CC REG_CC))])] 834 ; No need for a clobber reg for 0x0, 0x01 or 0xff 835 "!satisfies_constraint_Y00 (operands[1]) 836 && !satisfies_constraint_Y01 (operands[1]) 837 && !satisfies_constraint_Ym1 (operands[1])" 838 [(parallel [(set (match_dup 0) 839 (match_dup 1)) 840 (clobber (match_dup 2)) 841 (clobber (reg:CC REG_CC))])]) 842 843 ;;============================================================================ 844 ;; move word (16 bit) 845 846 ;; Move register $1 to the Stack Pointer register SP. 847 ;; This insn is emit during function prologue/epilogue generation. 848 ;; $2 = 0: We know that IRQs are off 849 ;; $2 = 1: We know that IRQs are on 850 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter 851 ;; $2 = -1: We don't know anything about IRQ on/off 852 ;; Always write SP via unspec, see PR50063 853 854 (define_insn "movhi_sp_r" 855 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q") 856 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r") 857 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")] 858 UNSPECV_WRITE_SP))] 859 "" 860 "@ 861 out %B0,%B1\;out %A0,%A1 862 cli\;out %B0,%B1\;sei\;out %A0,%A1 863 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1 864 out %A0,%A1 865 out %A0,%A1\;out %B0,%B1" 866 [(set_attr "length" "2,4,5,1,2") 867 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")]) 868 869 (define_peephole2 870 [(match_scratch:QI 2 "d") 871 (parallel [(set (match_operand:ALL2 0 "l_register_operand" "") 872 (match_operand:ALL2 1 "const_or_immediate_operand" "")) 873 (clobber (reg:CC REG_CC))])] 874 "operands[1] != CONST0_RTX (<MODE>mode)" 875 [(parallel [(set (match_dup 0) 876 (match_dup 1)) 877 (clobber (match_dup 2)) 878 (clobber (reg:CC REG_CC))])]) 879 880 ;; '*' because it is not used in rtl generation, only in above peephole 881 ;; "*reload_inhi" 882 ;; "*reload_inhq" "*reload_inuhq" 883 ;; "*reload_inha" "*reload_inuha" 884 (define_insn "*reload_in<mode>" 885 [(set (match_operand:ALL2 0 "l_register_operand" "=l") 886 (match_operand:ALL2 1 "immediate_operand" "i")) 887 (clobber (match_operand:QI 2 "register_operand" "=&d")) 888 (clobber (reg:CC REG_CC))] 889 "reload_completed" 890 { 891 return output_reload_inhi (operands, operands[2], NULL); 892 } 893 [(set_attr "length" "4") 894 (set_attr "adjust_len" "reload_in16")]) 895 896 ;; "*movhi" 897 ;; "*movhq" "*movuhq" 898 ;; "*movha" "*movuha" 899 (define_insn_and_split "*mov<mode>_split" 900 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r") 901 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))] 902 "register_operand (operands[0], <MODE>mode) 903 || reg_or_0_operand (operands[1], <MODE>mode)" 904 "#" 905 "&& reload_completed" 906 [(parallel [(set (match_dup 0) 907 (match_dup 1)) 908 (clobber (reg:CC REG_CC))])]) 909 910 (define_insn "*mov<mode>" 911 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r") 912 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q")) 913 (clobber (reg:CC REG_CC))] 914 "(register_operand (operands[0], <MODE>mode) 915 || reg_or_0_operand (operands[1], <MODE>mode)) 916 && reload_completed" 917 { 918 return output_movhi (insn, operands, NULL); 919 } 920 [(set_attr "length" "2,2,6,7,2,6,5,2") 921 (set_attr "adjust_len" "mov16")]) 922 923 (define_peephole2 ; movw 924 [(parallel [(set (match_operand:ALL1 0 "even_register_operand" "") 925 (match_operand:ALL1 1 "even_register_operand" "")) 926 (clobber (reg:CC REG_CC))]) 927 (parallel [(set (match_operand:ALL1 2 "odd_register_operand" "") 928 (match_operand:ALL1 3 "odd_register_operand" "")) 929 (clobber (reg:CC REG_CC))])] 930 "AVR_HAVE_MOVW 931 && REGNO (operands[0]) == REGNO (operands[2]) - 1 932 && REGNO (operands[1]) == REGNO (operands[3]) - 1" 933 [(parallel [(set (match_dup 4) 934 (match_dup 5)) 935 (clobber (reg:CC REG_CC))])] 936 { 937 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0])); 938 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1])); 939 }) 940 941 (define_peephole2 ; movw_r 942 [(parallel [(set (match_operand:ALL1 0 "odd_register_operand" "") 943 (match_operand:ALL1 1 "odd_register_operand" "")) 944 (clobber (reg:CC REG_CC))]) 945 (parallel [(set (match_operand:ALL1 2 "even_register_operand" "") 946 (match_operand:ALL1 3 "even_register_operand" "")) 947 (clobber (reg:CC REG_CC))])] 948 "AVR_HAVE_MOVW 949 && REGNO (operands[2]) == REGNO (operands[0]) - 1 950 && REGNO (operands[3]) == REGNO (operands[1]) - 1" 951 [(parallel [(set (match_dup 4) 952 (match_dup 5)) 953 (clobber (reg:CC REG_CC))])] 954 { 955 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2])); 956 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3])); 957 }) 958 959 960 ;; Register alloc may expand a 3-operand arithmetic X = Y o CST as 961 ;; X = CST 962 ;; X o= Y 963 ;; where it may be better to instead: 964 ;; X = Y 965 ;; X o= CST 966 ;; because 1) the first insn may use MOVW for "X = Y", and 2) the 967 ;; operation may be more efficient when performed with a constant, 968 ;; for example when ADIW or SBIW can be used, or some bytes of 969 ;; the constant are 0x00 or 0xff. 970 (define_peephole2 971 [(parallel [(set (match_operand:HISI 0 "d_register_operand") 972 (match_operand:HISI 1 "const_int_operand")) 973 (clobber (reg:CC REG_CC))]) 974 (parallel [(set (match_dup 0) 975 (piaop:HISI (match_dup 0) 976 (match_operand:HISI 2 "register_operand"))) 977 (clobber (scratch:QI)) 978 (clobber (reg:CC REG_CC))])] 979 "! reg_overlap_mentioned_p (operands[0], operands[2])" 980 [(parallel [(set (match_dup 0) 981 (match_dup 2)) 982 (clobber (reg:CC REG_CC))]) 983 (parallel [(set (match_dup 0) 984 (piaop:HISI (match_dup 0) 985 (match_dup 1))) 986 (clobber (scratch:QI)) 987 (clobber (reg:CC REG_CC))])]) 988 989 ;; Same, but just for plus:HI without a scratch:QI. 990 (define_peephole2 991 [(parallel [(set (match_operand:HI 0 "d_register_operand") 992 (match_operand:HI 1 "const_int_operand")) 993 (clobber (reg:CC REG_CC))]) 994 (parallel [(set (match_dup 0) 995 (plus:HI (match_dup 0) 996 (match_operand:HI 2 "register_operand"))) 997 (clobber (reg:CC REG_CC))])] 998 "! reg_overlap_mentioned_p (operands[0], operands[2])" 999 [(parallel [(set (match_dup 0) 1000 (match_dup 2)) 1001 (clobber (reg:CC REG_CC))]) 1002 (parallel [(set (match_dup 0) 1003 (plus:HI (match_dup 0) 1004 (match_dup 1))) 1005 (clobber (reg:CC REG_CC))])]) 1006 1007 1008 ;; For LPM loads from AS1 we split 1009 ;; R = *Z 1010 ;; to 1011 ;; R = *Z++ 1012 ;; Z = Z - sizeof (R) 1013 ;; 1014 ;; so that the second instruction can be optimized out. 1015 1016 (define_split ; "split-lpmx" 1017 [(set (match_operand:HISI 0 "register_operand" "") 1018 (match_operand:HISI 1 "memory_operand" ""))] 1019 "reload_completed 1020 && AVR_HAVE_LPMX 1021 && avr_mem_flash_p (operands[1]) 1022 && REG_P (XEXP (operands[1], 0)) 1023 && !reg_overlap_mentioned_p (XEXP (operands[1], 0), operands[0])" 1024 [(set (match_dup 0) 1025 (match_dup 2)) 1026 (set (match_dup 3) 1027 (plus:HI (match_dup 3) 1028 (match_dup 4)))] 1029 { 1030 rtx addr = XEXP (operands[1], 0); 1031 1032 operands[2] = replace_equiv_address (operands[1], 1033 gen_rtx_POST_INC (Pmode, addr)); 1034 operands[3] = addr; 1035 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode); 1036 }) 1037 1038 1039 ;; Legitimate address and stuff allows way more addressing modes than 1040 ;; Reduced Tiny actually supports. Split them now so that we get 1041 ;; closer to real instructions which may result in some optimization 1042 ;; opportunities. 1043 (define_split 1044 [(parallel [(set (match_operand:MOVMODE 0 "nonimmediate_operand") 1045 (match_operand:MOVMODE 1 "general_operand")) 1046 (clobber (reg:CC REG_CC))])] 1047 "AVR_TINY 1048 && reload_completed 1049 && avr_fuse_add > 0 1050 // Only split this for .split2 when we are before 1051 // pass .avr-fuse-add (which runs after proep). 1052 && ! epilogue_completed 1053 && (MEM_P (operands[0]) || MEM_P (operands[1]))" 1054 [(scratch)] 1055 { 1056 if (avr_split_tiny_move (curr_insn, operands)) 1057 DONE; 1058 FAIL; 1059 }) 1060 1061 1062 ;;========================================================================== 1063 ;; xpointer move (24 bit) 1064 1065 (define_peephole2 ; *reload_inpsi 1066 [(match_scratch:QI 2 "d") 1067 (parallel [(set (match_operand:PSI 0 "l_register_operand" "") 1068 (match_operand:PSI 1 "immediate_operand" "")) 1069 (clobber (reg:CC REG_CC))]) 1070 (match_dup 2)] 1071 "operands[1] != const0_rtx 1072 && operands[1] != constm1_rtx" 1073 [(parallel [(set (match_dup 0) 1074 (match_dup 1)) 1075 (clobber (match_dup 2)) 1076 (clobber (reg:CC REG_CC))])]) 1077 1078 ;; '*' because it is not used in rtl generation. 1079 (define_insn "*reload_inpsi" 1080 [(set (match_operand:PSI 0 "register_operand" "=r") 1081 (match_operand:PSI 1 "immediate_operand" "i")) 1082 (clobber (match_operand:QI 2 "register_operand" "=&d")) 1083 (clobber (reg:CC REG_CC))] 1084 "reload_completed" 1085 { 1086 return avr_out_reload_inpsi (operands, operands[2], NULL); 1087 } 1088 [(set_attr "length" "6") 1089 (set_attr "adjust_len" "reload_in24")]) 1090 1091 (define_insn_and_split "*movpsi_split" 1092 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 1093 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))] 1094 "register_operand (operands[0], PSImode) 1095 || register_operand (operands[1], PSImode) 1096 || const0_rtx == operands[1]" 1097 "#" 1098 "&& reload_completed" 1099 [(parallel [(set (match_dup 0) 1100 (match_dup 1)) 1101 (clobber (reg:CC REG_CC))])]) 1102 1103 (define_insn "*movpsi" 1104 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 1105 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i")) 1106 (clobber (reg:CC REG_CC))] 1107 "(register_operand (operands[0], PSImode) 1108 || register_operand (operands[1], PSImode) 1109 || const0_rtx == operands[1]) 1110 && reload_completed" 1111 { 1112 return avr_out_movpsi (insn, operands, NULL); 1113 } 1114 [(set_attr "length" "3,3,8,9,4,10") 1115 (set_attr "adjust_len" "mov24")]) 1116 1117 ;;========================================================================== 1118 ;; move double word (32 bit) 1119 1120 (define_peephole2 ; *reload_insi 1121 [(match_scratch:QI 2 "d") 1122 (parallel [(set (match_operand:ALL4 0 "l_register_operand" "") 1123 (match_operand:ALL4 1 "immediate_operand" "")) 1124 (clobber (reg:CC REG_CC))]) 1125 (match_dup 2)] 1126 "operands[1] != CONST0_RTX (<MODE>mode)" 1127 [(parallel [(set (match_dup 0) 1128 (match_dup 1)) 1129 (clobber (match_dup 2)) 1130 (clobber (reg:CC REG_CC))])]) 1131 1132 ;; '*' because it is not used in rtl generation. 1133 ;; "*reload_insi" 1134 ;; "*reload_insq" "*reload_inusq" 1135 ;; "*reload_insa" "*reload_inusa" 1136 (define_insn "*reload_insi" 1137 [(set (match_operand:ALL4 0 "register_operand" "=r") 1138 (match_operand:ALL4 1 "immediate_operand" "n Ynn")) 1139 (clobber (match_operand:QI 2 "register_operand" "=&d")) 1140 (clobber (reg:CC REG_CC))] 1141 "reload_completed" 1142 { 1143 return output_reload_insisf (operands, operands[2], NULL); 1144 } 1145 [(set_attr "length" "8") 1146 (set_attr "adjust_len" "reload_in32")]) 1147 1148 1149 ;; "*movsi" 1150 ;; "*movsq" "*movusq" 1151 ;; "*movsa" "*movusa" 1152 (define_insn_and_split "*mov<mode>_split" 1153 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r") 1154 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))] 1155 "register_operand (operands[0], <MODE>mode) 1156 || reg_or_0_operand (operands[1], <MODE>mode)" 1157 "#" 1158 "&& reload_completed" 1159 [(parallel [(set (match_dup 0) 1160 (match_dup 1)) 1161 (clobber (reg:CC REG_CC))])]) 1162 1163 (define_insn "*mov<mode>" 1164 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r") 1165 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i")) 1166 (clobber (reg:CC REG_CC))] 1167 "(register_operand (operands[0], <MODE>mode) 1168 || reg_or_0_operand (operands[1], <MODE>mode)) 1169 && reload_completed" 1170 { 1171 return output_movsisf (insn, operands, NULL); 1172 } 1173 [(set_attr "length" "4,4,8,9,4,10") 1174 (set_attr "adjust_len" "mov32")]) 1175 1176 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1177 ;; move floating point numbers (32 bit) 1178 1179 (define_insn_and_split "*movsf_split" 1180 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 1181 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))] 1182 "register_operand (operands[0], SFmode) 1183 || reg_or_0_operand (operands[1], SFmode)" 1184 "#" 1185 "&& reload_completed" 1186 [(parallel [(set (match_dup 0) 1187 (match_dup 1)) 1188 (clobber (reg:CC REG_CC))])]) 1189 1190 (define_insn "*movsf" 1191 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 1192 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F")) 1193 (clobber (reg:CC REG_CC))] 1194 "(register_operand (operands[0], SFmode) 1195 || reg_or_0_operand (operands[1], SFmode)) 1196 && reload_completed" 1197 { 1198 return output_movsisf (insn, operands, NULL); 1199 } 1200 [(set_attr "length" "4,4,8,9,4,10") 1201 (set_attr "adjust_len" "mov32")]) 1202 1203 (define_peephole2 ; *reload_insf 1204 [(match_scratch:QI 2 "d") 1205 (parallel [(set (match_operand:SF 0 "l_register_operand" "") 1206 (match_operand:SF 1 "const_double_operand" "")) 1207 (clobber (reg:CC REG_CC))]) 1208 (match_dup 2)] 1209 "operands[1] != CONST0_RTX (SFmode)" 1210 [(parallel [(set (match_dup 0) 1211 (match_dup 1)) 1212 (clobber (match_dup 2)) 1213 (clobber (reg:CC REG_CC))])]) 1214 1215 ;; '*' because it is not used in rtl generation. 1216 (define_insn "*reload_insf" 1217 [(set (match_operand:SF 0 "register_operand" "=r") 1218 (match_operand:SF 1 "const_double_operand" "F")) 1219 (clobber (match_operand:QI 2 "register_operand" "=&d")) 1220 (clobber (reg:CC REG_CC))] 1221 "reload_completed" 1222 { 1223 return output_reload_insisf (operands, operands[2], NULL); 1224 } 1225 [(set_attr "length" "8") 1226 (set_attr "adjust_len" "reload_in32")]) 1227 1228 ;;========================================================================= 1229 ;; move string (like memcpy) 1230 1231 (define_expand "cpymemhi" 1232 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 1233 (match_operand:BLK 1 "memory_operand" "")) 1234 (use (match_operand:HI 2 "const_int_operand" "")) 1235 (use (match_operand:HI 3 "const_int_operand" ""))])] 1236 "" 1237 { 1238 if (avr_emit_cpymemhi (operands)) 1239 DONE; 1240 1241 FAIL; 1242 }) 1243 1244 (define_mode_attr CPYMEM_r_d [(QI "r") 1245 (HI "wd")]) 1246 1247 ;; $0 : Address Space 1248 ;; $1, $2 : Loop register 1249 ;; R30 : source address 1250 ;; R26 : destination address 1251 1252 ;; "cpymem_qi" 1253 ;; "cpymem_hi" 1254 (define_insn_and_split "cpymem_<mode>" 1255 [(set (mem:BLK (reg:HI REG_X)) 1256 (mem:BLK (reg:HI REG_Z))) 1257 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1258 UNSPEC_CPYMEM) 1259 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>")) 1260 (clobber (reg:HI REG_X)) 1261 (clobber (reg:HI REG_Z)) 1262 (clobber (reg:QI LPM_REGNO)) 1263 (clobber (match_operand:QIHI 2 "register_operand" "=1"))] 1264 "" 1265 "#" 1266 "&& reload_completed" 1267 [(parallel [(set (mem:BLK (reg:HI REG_X)) 1268 (mem:BLK (reg:HI REG_Z))) 1269 (unspec [(match_dup 0)] 1270 UNSPEC_CPYMEM) 1271 (use (match_dup 1)) 1272 (clobber (reg:HI REG_X)) 1273 (clobber (reg:HI REG_Z)) 1274 (clobber (reg:QI LPM_REGNO)) 1275 (clobber (match_dup 2)) 1276 (clobber (reg:CC REG_CC))])]) 1277 1278 (define_insn "*cpymem_<mode>" 1279 [(set (mem:BLK (reg:HI REG_X)) 1280 (mem:BLK (reg:HI REG_Z))) 1281 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1282 UNSPEC_CPYMEM) 1283 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>")) 1284 (clobber (reg:HI REG_X)) 1285 (clobber (reg:HI REG_Z)) 1286 (clobber (reg:QI LPM_REGNO)) 1287 (clobber (match_operand:QIHI 2 "register_operand" "=1")) 1288 (clobber (reg:CC REG_CC))] 1289 "reload_completed" 1290 { 1291 return avr_out_cpymem (insn, operands, NULL); 1292 } 1293 [(set_attr "adjust_len" "cpymem")]) 1294 1295 1296 ;; $0 : Address Space 1297 ;; $1 : RAMPZ RAM address 1298 ;; R24 : #bytes and loop register 1299 ;; R23:Z : 24-bit source address 1300 ;; R26 : 16-bit destination address 1301 1302 ;; "cpymemx_qi" 1303 ;; "cpymemx_hi" 1304 1305 (define_insn_and_split "cpymemx_<mode>" 1306 [(set (mem:BLK (reg:HI REG_X)) 1307 (mem:BLK (lo_sum:PSI (reg:QI 23) 1308 (reg:HI REG_Z)))) 1309 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1310 UNSPEC_CPYMEM) 1311 (use (reg:QIHI 24)) 1312 (clobber (reg:HI REG_X)) 1313 (clobber (reg:HI REG_Z)) 1314 (clobber (reg:QI LPM_REGNO)) 1315 (clobber (reg:HI 24)) 1316 (clobber (reg:QI 23)) 1317 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))] 1318 "" 1319 "#" 1320 "&& reload_completed" 1321 [(parallel [(set (mem:BLK (reg:HI REG_X)) 1322 (mem:BLK (lo_sum:PSI (reg:QI 23) 1323 (reg:HI REG_Z)))) 1324 (unspec [(match_dup 0)] 1325 UNSPEC_CPYMEM) 1326 (use (reg:QIHI 24)) 1327 (clobber (reg:HI REG_X)) 1328 (clobber (reg:HI REG_Z)) 1329 (clobber (reg:QI LPM_REGNO)) 1330 (clobber (reg:HI 24)) 1331 (clobber (reg:QI 23)) 1332 (clobber (mem:QI (match_dup 1))) 1333 (clobber (reg:CC REG_CC))])]) 1334 1335 (define_insn "*cpymemx_<mode>" 1336 [(set (mem:BLK (reg:HI REG_X)) 1337 (mem:BLK (lo_sum:PSI (reg:QI 23) 1338 (reg:HI REG_Z)))) 1339 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1340 UNSPEC_CPYMEM) 1341 (use (reg:QIHI 24)) 1342 (clobber (reg:HI REG_X)) 1343 (clobber (reg:HI REG_Z)) 1344 (clobber (reg:QI LPM_REGNO)) 1345 (clobber (reg:HI 24)) 1346 (clobber (reg:QI 23)) 1347 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n"))) 1348 (clobber (reg:CC REG_CC))] 1349 "reload_completed" 1350 "%~call __movmemx_<mode>" 1351 [(set_attr "type" "xcall")]) 1352 1353 1354 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 1355 ;; memset (%0, %2, %1) 1356 1357 (define_expand "setmemhi" 1358 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 1359 (match_operand 2 "const_int_operand" "")) 1360 (use (match_operand:HI 1 "const_int_operand" "")) 1361 (use (match_operand:HI 3 "const_int_operand" "")) 1362 (clobber (match_scratch:HI 5 "")) 1363 (clobber (match_dup 4))])] 1364 "" 1365 { 1366 // If value to set is not zero, use the library routine. 1367 if (operands[2] != const0_rtx) 1368 FAIL; 1369 1370 if (!CONST_INT_P (operands[1])) 1371 FAIL; 1372 1373 machine_mode mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode; 1374 operands[4] = gen_rtx_SCRATCH (mode); 1375 operands[1] = copy_to_mode_reg (mode, 1376 gen_int_mode (INTVAL (operands[1]), mode)); 1377 rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 1378 operands[0] = gen_rtx_MEM (BLKmode, addr0); 1379 }) 1380 1381 1382 (define_insn_and_split "*clrmemqi_split" 1383 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) 1384 (const_int 0)) 1385 (use (match_operand:QI 1 "register_operand" "r")) 1386 (use (match_operand:HI 2 "const_int_operand" "n")) 1387 (clobber (match_scratch:HI 3 "=0")) 1388 (clobber (match_scratch:QI 4 "=&1"))] 1389 "" 1390 "#" 1391 "&& reload_completed" 1392 [(parallel [(set (mem:BLK (match_dup 0)) 1393 (const_int 0)) 1394 (use (match_dup 1)) 1395 (use (match_dup 2)) 1396 (clobber (match_dup 3)) 1397 (clobber (match_dup 4)) 1398 (clobber (reg:CC REG_CC))])]) 1399 1400 (define_insn "*clrmemqi" 1401 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) 1402 (const_int 0)) 1403 (use (match_operand:QI 1 "register_operand" "r")) 1404 (use (match_operand:HI 2 "const_int_operand" "n")) 1405 (clobber (match_scratch:HI 3 "=0")) 1406 (clobber (match_scratch:QI 4 "=&1")) 1407 (clobber (reg:CC REG_CC))] 1408 "reload_completed" 1409 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b" 1410 [(set_attr "length" "3")]) 1411 1412 1413 (define_insn_and_split "*clrmemhi_split" 1414 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e")) 1415 (const_int 0)) 1416 (use (match_operand:HI 1 "register_operand" "!w,d")) 1417 (use (match_operand:HI 2 "const_int_operand" "n,n")) 1418 (clobber (match_scratch:HI 3 "=0,0")) 1419 (clobber (match_scratch:HI 4 "=&1,&1"))] 1420 "" 1421 "#" 1422 "&& reload_completed" 1423 [(parallel [(set (mem:BLK (match_dup 0)) 1424 (const_int 0)) 1425 (use (match_dup 1)) 1426 (use (match_dup 2)) 1427 (clobber (match_dup 3)) 1428 (clobber (match_dup 4)) 1429 (clobber (reg:CC REG_CC))])] 1430 "" 1431 [(set_attr "isa" "adiw,*")]) 1432 1433 1434 (define_insn "*clrmemhi" 1435 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e")) 1436 (const_int 0)) 1437 (use (match_operand:HI 1 "register_operand" "!w,d")) 1438 (use (match_operand:HI 2 "const_int_operand" "n,n")) 1439 (clobber (match_scratch:HI 3 "=0,0")) 1440 (clobber (match_scratch:HI 4 "=&1,&1")) 1441 (clobber (reg:CC REG_CC))] 1442 "reload_completed" 1443 "@ 1444 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b 1445 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b" 1446 [(set_attr "length" "3,4") 1447 (set_attr "isa" "adiw,*")]) 1448 1449 (define_expand "strlenhi" 1450 [(set (match_dup 4) 1451 (unspec:HI [(match_operand:BLK 1 "memory_operand" "") 1452 (match_operand:QI 2 "const_int_operand" "") 1453 (match_operand:HI 3 "immediate_operand" "")] 1454 UNSPEC_STRLEN)) 1455 (set (match_dup 4) 1456 (plus:HI (match_dup 4) 1457 (const_int -1))) 1458 (parallel [(set (match_operand:HI 0 "register_operand" "") 1459 (minus:HI (match_dup 4) 1460 (match_dup 5))) 1461 (clobber (scratch:QI))])] 1462 "" 1463 { 1464 if (operands[2] != const0_rtx) 1465 FAIL; 1466 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 1467 operands[1] = gen_rtx_MEM (BLKmode, addr); 1468 operands[5] = addr; 1469 operands[4] = gen_reg_rtx (HImode); 1470 }) 1471 1472 (define_insn_and_split "*strlenhi_split" 1473 [(set (match_operand:HI 0 "register_operand" "=e") 1474 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0")) 1475 (const_int 0) 1476 (match_operand:HI 2 "immediate_operand" "i")] 1477 UNSPEC_STRLEN))] 1478 "" 1479 "#" 1480 "&& reload_completed" 1481 [(parallel 1482 [(set (match_dup 0) 1483 (unspec:HI [(mem:BLK (match_dup 1)) 1484 (const_int 0) 1485 (match_dup 2)] 1486 UNSPEC_STRLEN)) 1487 (clobber (reg:CC REG_CC))])]) 1488 1489 (define_insn "*strlenhi" 1490 [(set (match_operand:HI 0 "register_operand" "=e") 1491 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0")) 1492 (const_int 0) 1493 (match_operand:HI 2 "immediate_operand" "i")] 1494 UNSPEC_STRLEN)) 1495 (clobber (reg:CC REG_CC))] 1496 "reload_completed" 1497 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b" 1498 [(set_attr "length" "3")]) 1499 1500 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1501 ; add bytes 1502 1503 ;; "addqi3" 1504 ;; "addqq3" "adduqq3" 1505 (define_insn_and_split "add<mode>3" 1506 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r") 1507 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0") 1508 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))] 1509 "" 1510 "#" 1511 "&& reload_completed" 1512 [(parallel [(set (match_dup 0) 1513 (plus:ALL1 (match_dup 1) 1514 (match_dup 2))) 1515 (clobber (reg:CC REG_CC))])]) 1516 1517 (define_insn "*add<mode>3" 1518 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r") 1519 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0") 1520 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2"))) 1521 (clobber (reg:CC REG_CC))] 1522 "reload_completed" 1523 "@ 1524 add %0,%2 1525 subi %0,lo8(-(%2)) 1526 inc %0 1527 dec %0 1528 inc %0\;inc %0 1529 dec %0\;dec %0" 1530 [(set_attr "length" "1,1,1,1,2,2")]) 1531 1532 ;; "addhi3" 1533 ;; "addhq3" "adduhq3" 1534 ;; "addha3" "adduha3" 1535 (define_expand "add<mode>3" 1536 [(set (match_operand:ALL2 0 "register_operand" "") 1537 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "") 1538 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))] 1539 "" 1540 { 1541 if (CONST_INT_P (operands[2])) 1542 { 1543 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode); 1544 1545 if (can_create_pseudo_p() 1546 && !stack_register_operand (operands[0], HImode) 1547 && !stack_register_operand (operands[1], HImode) 1548 && !d_register_operand (operands[0], HImode) 1549 && !d_register_operand (operands[1], HImode)) 1550 { 1551 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2])); 1552 DONE; 1553 } 1554 } 1555 1556 if (CONST_FIXED_P (operands[2])) 1557 { 1558 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2])); 1559 DONE; 1560 } 1561 }) 1562 1563 1564 (define_insn_and_split "*addhi3_zero_extend_split" 1565 [(set (match_operand:HI 0 "register_operand" "=r,*?r") 1566 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0")) 1567 (match_operand:HI 2 "register_operand" "0 ,r")))] 1568 "" 1569 "#" 1570 "&& reload_completed" 1571 [(parallel [(set (match_dup 0) 1572 (plus:HI (zero_extend:HI (match_dup 1)) 1573 (match_dup 2))) 1574 (clobber (reg:CC REG_CC))])]) 1575 1576 (define_insn "*addhi3_zero_extend" 1577 [(set (match_operand:HI 0 "register_operand" "=r,*?r") 1578 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0")) 1579 (match_operand:HI 2 "register_operand" "0 ,r"))) 1580 (clobber (reg:CC REG_CC))] 1581 "reload_completed" 1582 "@ 1583 add %A0,%1\;adc %B0,__zero_reg__ 1584 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__" 1585 [(set_attr "length" "2,3")]) 1586 1587 (define_insn_and_split "*addhi3_zero_extend1_split" 1588 [(set (match_operand:HI 0 "register_operand" "=r") 1589 (plus:HI (match_operand:HI 1 "register_operand" "0") 1590 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1591 "" 1592 "#" 1593 "&& reload_completed" 1594 [(parallel [(set (match_dup 0) 1595 (plus:HI (match_dup 1) 1596 (zero_extend:HI (match_dup 2)))) 1597 (clobber (reg:CC REG_CC))])]) 1598 1599 (define_insn "*addhi3_zero_extend1" 1600 [(set (match_operand:HI 0 "register_operand" "=r") 1601 (plus:HI (match_operand:HI 1 "register_operand" "0") 1602 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))) 1603 (clobber (reg:CC REG_CC))] 1604 "reload_completed" 1605 "add %A0,%2\;adc %B0,__zero_reg__" 1606 [(set_attr "length" "2")]) 1607 1608 (define_insn_and_split "*addhi3.sign_extend1_split" 1609 [(set (match_operand:HI 0 "register_operand" "=r") 1610 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r")) 1611 (match_operand:HI 2 "register_operand" "0")))] 1612 "" 1613 "#" 1614 "&& reload_completed" 1615 [(parallel [(set (match_dup 0) 1616 (plus:HI (sign_extend:HI (match_dup 1)) 1617 (match_dup 2))) 1618 (clobber (reg:CC REG_CC))])]) 1619 1620 1621 (define_insn "*addhi3.sign_extend1" 1622 [(set (match_operand:HI 0 "register_operand" "=r") 1623 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r")) 1624 (match_operand:HI 2 "register_operand" "0"))) 1625 (clobber (reg:CC REG_CC))] 1626 "reload_completed" 1627 { 1628 return reg_overlap_mentioned_p (operands[0], operands[1]) 1629 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0" 1630 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0"; 1631 } 1632 [(set (attr "length") 1633 (symbol_ref ("4 + reg_overlap_mentioned_p (operands[0], operands[1])")))]) 1634 1635 (define_insn_and_split "*addhi3_zero_extend.const_split" 1636 [(set (match_operand:HI 0 "register_operand" "=d") 1637 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1638 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))] 1639 "" 1640 "#" 1641 "&& reload_completed" 1642 [(parallel [(set (match_dup 0) 1643 (plus:HI (zero_extend:HI (match_dup 1)) 1644 (match_dup 2))) 1645 (clobber (reg:CC REG_CC))])]) 1646 1647 (define_insn "*addhi3_zero_extend.const" 1648 [(set (match_operand:HI 0 "register_operand" "=d") 1649 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1650 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8"))) 1651 (clobber (reg:CC REG_CC))] 1652 "reload_completed" 1653 "subi %A0,%n2\;sbc %B0,%B0" 1654 [(set_attr "length" "2")]) 1655 1656 1657 ;; Occurs when computing offsets into 16-bit arrays. 1658 ;; Saves up to 2 instructions. 1659 (define_insn_and_split "*addhi3_zero_extend.ashift1.split" 1660 [(set (match_operand:HI 0 "register_operand" "=r") 1661 (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 1662 (const_int 1)) 1663 (match_operand:HI 2 "register_operand" "0")))] 1664 "" 1665 "#" 1666 "&& reload_completed" 1667 [(parallel [(set (match_dup 0) 1668 (plus:HI (ashift:HI (zero_extend:HI (match_dup 1)) 1669 (const_int 1)) 1670 (match_dup 2))) 1671 (clobber (reg:CC REG_CC))])]) 1672 1673 (define_insn "*addhi3_zero_extend.ashift1" 1674 [(set (match_operand:HI 0 "register_operand" "=r") 1675 (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 1676 (const_int 1)) 1677 (match_operand:HI 2 "register_operand" "0"))) 1678 (clobber (reg:CC REG_CC))] 1679 "reload_completed" 1680 { 1681 return reg_overlap_mentioned_p (operands[1], operands[0]) 1682 ? "mov __tmp_reg__,%1\;add %A0,__tmp_reg__\;adc %B0,__zero_reg__\;add %A0,__tmp_reg__\;adc %B0,__zero_reg__" 1683 : "add %A0,%1\;adc %B0,__zero_reg__\;add %A0,%1\;adc %B0,__zero_reg__"; 1684 } 1685 [(set (attr "length") 1686 (symbol_ref ("4 + reg_overlap_mentioned_p (operands[1], operands[0])")))]) 1687 1688 1689 (define_insn_and_split "*usum_widenqihi3_split" 1690 [(set (match_operand:HI 0 "register_operand" "=r") 1691 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 1692 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1693 "" 1694 "#" 1695 "&& reload_completed" 1696 [(parallel [(set (match_dup 0) 1697 (plus:HI (zero_extend:HI (match_dup 1)) 1698 (zero_extend:HI (match_dup 2)))) 1699 (clobber (reg:CC REG_CC))])]) 1700 1701 1702 (define_insn "*usum_widenqihi3" 1703 [(set (match_operand:HI 0 "register_operand" "=r") 1704 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 1705 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))) 1706 (clobber (reg:CC REG_CC))] 1707 "reload_completed" 1708 "add %A0,%2\;clr %B0\;rol %B0" 1709 [(set_attr "length" "3")]) 1710 1711 (define_insn_and_split "*udiff_widenqihi3_split" 1712 [(set (match_operand:HI 0 "register_operand" "=r") 1713 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1714 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1715 "" 1716 "#" 1717 "&& reload_completed" 1718 [(parallel [(set (match_dup 0) 1719 (minus:HI (zero_extend:HI (match_dup 1)) 1720 (zero_extend:HI (match_dup 2)))) 1721 (clobber (reg:CC REG_CC))])]) 1722 1723 (define_insn "*udiff_widenqihi3" 1724 [(set (match_operand:HI 0 "register_operand" "=r") 1725 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1726 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))) 1727 (clobber (reg:CC REG_CC))] 1728 "reload_completed" 1729 "sub %A0,%2\;sbc %B0,%B0" 1730 [(set_attr "length" "2")]) 1731 1732 (define_insn_and_split "*addhi3_sp" 1733 [(set (match_operand:HI 1 "stack_register_operand" "=q") 1734 (plus:HI (match_operand:HI 2 "stack_register_operand" "q") 1735 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))] 1736 "" 1737 { 1738 return avr_out_addto_sp (operands, NULL); 1739 } 1740 "" 1741 [(const_int 0)] 1742 { 1743 // Do not attempt to split this pattern. This FAIL is necessary 1744 // to prevent the splitter from matching *add<ALL2>3_split, splitting 1745 // it, and then failing later because constraints don't match, as split 1746 // does not look at constraints. 1747 FAIL; 1748 } 1749 [(set_attr "length" "6") 1750 (set_attr "adjust_len" "addto_sp")]) 1751 1752 ;; "*addhi3_split" 1753 ;; "*addhq3_split" "*adduhq3_split" 1754 ;; "*addha3_split" "*adduha3_split" 1755 (define_insn_and_split "*add<mode>3_split" 1756 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d") 1757 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0") 1758 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))] 1759 "" 1760 "#" 1761 "&& reload_completed" 1762 [(parallel [(set (match_dup 0) 1763 (plus:ALL2 (match_dup 1) 1764 (match_dup 2))) 1765 (clobber (reg:CC REG_CC))])] 1766 "" 1767 [(set_attr "isa" "*,*,adiw,*")]) 1768 1769 ;; "*addhi3" 1770 ;; "*addhq3" "*adduhq3" 1771 ;; "*addha3" "*adduha3" 1772 (define_insn "*add<mode>3" 1773 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d") 1774 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0") 1775 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn"))) 1776 (clobber (reg:CC REG_CC))] 1777 "reload_completed" 1778 { 1779 return avr_out_plus (insn, operands); 1780 } 1781 [(set_attr "length" "2") 1782 (set_attr "isa" "*,*,adiw,*") 1783 (set_attr "adjust_len" "plus")]) 1784 1785 ;; Adding a constant to NO_LD_REGS might have lead to a reload of 1786 ;; that constant to LD_REGS. We don't add a scratch to *addhi3 1787 ;; itself because that insn is special to reload. 1788 1789 (define_peephole2 ; addhi3_clobber 1790 [(parallel [(set (match_operand:ALL2 0 "d_register_operand" "") 1791 (match_operand:ALL2 1 "const_operand" "")) 1792 (clobber (reg:CC REG_CC))]) 1793 (parallel [(set (match_operand:ALL2 2 "l_register_operand" "") 1794 (plus:ALL2 (match_dup 2) 1795 (match_dup 0))) 1796 (clobber (reg:CC REG_CC))])] 1797 "peep2_reg_dead_p (2, operands[0])" 1798 [(parallel [(set (match_dup 2) 1799 (plus:ALL2 (match_dup 2) 1800 (match_dup 1))) 1801 (clobber (match_dup 3)) 1802 (clobber (reg:CC REG_CC))])] 1803 { 1804 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0); 1805 }) 1806 1807 ;; Same, but with reload to NO_LD_REGS 1808 ;; Combine *reload_inhi with *addhi3 1809 1810 (define_peephole2 ; addhi3_clobber 1811 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "") 1812 (match_operand:ALL2 1 "const_operand" "")) 1813 (clobber (match_operand:QI 2 "d_register_operand" "")) 1814 (clobber (reg:CC REG_CC))]) 1815 (parallel [(set (match_operand:ALL2 3 "l_register_operand" "") 1816 (plus:ALL2 (match_dup 3) 1817 (match_dup 0))) 1818 (clobber (reg:CC REG_CC))])] 1819 "peep2_reg_dead_p (2, operands[0])" 1820 [(parallel [(set (match_dup 3) 1821 (plus:ALL2 (match_dup 3) 1822 (match_dup 1))) 1823 (clobber (match_dup 2)) 1824 (clobber (reg:CC REG_CC))])]) 1825 1826 ;; "addhi3_clobber" 1827 ;; "addhq3_clobber" "adduhq3_clobber" 1828 ;; "addha3_clobber" "adduha3_clobber" 1829 (define_insn_and_split "add<mode>3_clobber" 1830 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r") 1831 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0") 1832 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn"))) 1833 (clobber (match_scratch:QI 3 "=X ,X ,&d"))] 1834 "" 1835 "#" 1836 "&& reload_completed" 1837 [(parallel [(set (match_dup 0) 1838 (plus:ALL2 (match_dup 1) 1839 (match_dup 2))) 1840 (clobber (match_dup 3)) 1841 (clobber (reg:CC REG_CC))])]) 1842 1843 ;; "*addhi3_clobber" 1844 ;; "*addhq3_clobber" "*adduhq3_clobber" 1845 ;; "*addha3_clobber" "*adduha3_clobber" 1846 (define_insn "*add<mode>3_clobber" 1847 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r") 1848 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0") 1849 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn"))) 1850 (clobber (match_scratch:QI 3 "=X ,X ,&d")) 1851 (clobber (reg:CC REG_CC))] 1852 "reload_completed" 1853 { 1854 return avr_out_plus (insn, operands); 1855 } 1856 [(set_attr "length" "4") 1857 (set_attr "adjust_len" "plus")]) 1858 1859 1860 ;; "addsi3" 1861 ;; "addsq3" "addusq3" 1862 ;; "addsa3" "addusa3" 1863 (define_insn_and_split "add<mode>3" 1864 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 1865 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0") 1866 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn"))) 1867 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 1868 "" 1869 "#" 1870 "&& reload_completed" 1871 [(parallel [(set (match_dup 0) 1872 (plus:ALL4 (match_dup 1) 1873 (match_dup 2))) 1874 (clobber (match_dup 3)) 1875 (clobber (reg:CC REG_CC))])]) 1876 1877 (define_insn "*add<mode>3" 1878 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 1879 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0") 1880 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn"))) 1881 (clobber (match_scratch:QI 3 "=X,X ,&d")) 1882 (clobber (reg:CC REG_CC))] 1883 "reload_completed" 1884 { 1885 return avr_out_plus (insn, operands); 1886 } 1887 [(set_attr "length" "4") 1888 (set_attr "adjust_len" "plus")]) 1889 1890 (define_insn_and_split "*addpsi3_zero_extend.qi_split" 1891 [(set (match_operand:PSI 0 "register_operand" "=r") 1892 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 1893 (match_operand:PSI 2 "register_operand" "0")))] 1894 "" 1895 "#" 1896 "&& reload_completed" 1897 [(parallel [(set (match_dup 0) 1898 (plus:PSI (zero_extend:PSI (match_dup 1)) 1899 (match_dup 2))) 1900 (clobber (reg:CC REG_CC))])]) 1901 1902 (define_insn "*addpsi3_zero_extend.qi" 1903 [(set (match_operand:PSI 0 "register_operand" "=r") 1904 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 1905 (match_operand:PSI 2 "register_operand" "0"))) 1906 (clobber (reg:CC REG_CC))] 1907 "reload_completed" 1908 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__" 1909 [(set_attr "length" "3")]) 1910 1911 (define_insn_and_split "*addpsi3_zero_extend.hi_split" 1912 [(set (match_operand:PSI 0 "register_operand" "=r") 1913 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1914 (match_operand:PSI 2 "register_operand" "0")))] 1915 "" 1916 "#" 1917 "&& reload_completed" 1918 [(parallel [(set (match_dup 0) 1919 (plus:PSI (zero_extend:PSI (match_dup 1)) 1920 (match_dup 2))) 1921 (clobber (reg:CC REG_CC))])]) 1922 1923 (define_insn "*addpsi3_zero_extend.hi" 1924 [(set (match_operand:PSI 0 "register_operand" "=r") 1925 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1926 (match_operand:PSI 2 "register_operand" "0"))) 1927 (clobber (reg:CC REG_CC))] 1928 "reload_completed" 1929 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__" 1930 [(set_attr "length" "3")]) 1931 1932 (define_insn_and_split "*addpsi3_sign_extend.hi_split" 1933 [(set (match_operand:PSI 0 "register_operand" "=r") 1934 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1935 (match_operand:PSI 2 "register_operand" "0")))] 1936 "" 1937 "#" 1938 "&& reload_completed" 1939 [(parallel [(set (match_dup 0) 1940 (plus:PSI (sign_extend:PSI (match_dup 1)) 1941 (match_dup 2))) 1942 (clobber (reg:CC REG_CC))])]) 1943 1944 (define_insn "*addpsi3_sign_extend.hi" 1945 [(set (match_operand:PSI 0 "register_operand" "=r") 1946 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1947 (match_operand:PSI 2 "register_operand" "0"))) 1948 (clobber (reg:CC REG_CC))] 1949 "reload_completed" 1950 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0" 1951 [(set_attr "length" "5")]) 1952 1953 (define_insn_and_split "*addsi3_zero_extend_split" 1954 [(set (match_operand:SI 0 "register_operand" "=r") 1955 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 1956 (match_operand:SI 2 "register_operand" "0")))] 1957 "" 1958 "#" 1959 "&& reload_completed" 1960 [(parallel [(set (match_dup 0) 1961 (plus:SI (zero_extend:SI (match_dup 1)) 1962 (match_dup 2))) 1963 (clobber (reg:CC REG_CC))])]) 1964 1965 (define_insn "*addsi3_zero_extend" 1966 [(set (match_operand:SI 0 "register_operand" "=r") 1967 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 1968 (match_operand:SI 2 "register_operand" "0"))) 1969 (clobber (reg:CC REG_CC))] 1970 "reload_completed" 1971 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 1972 [(set_attr "length" "4")]) 1973 1974 (define_insn_and_split "*addsi3_zero_extend.hi_split" 1975 [(set (match_operand:SI 0 "register_operand" "=r") 1976 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) 1977 (match_operand:SI 2 "register_operand" "0")))] 1978 "" 1979 "#" 1980 "&& reload_completed" 1981 [(parallel [(set (match_dup 0) 1982 (plus:SI (zero_extend:SI (match_dup 1)) 1983 (match_dup 2))) 1984 (clobber (reg:CC REG_CC))])]) 1985 1986 (define_insn "*addsi3_zero_extend.hi" 1987 [(set (match_operand:SI 0 "register_operand" "=r") 1988 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) 1989 (match_operand:SI 2 "register_operand" "0"))) 1990 (clobber (reg:CC REG_CC))] 1991 "reload_completed" 1992 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 1993 [(set_attr "length" "4")]) 1994 1995 (define_insn_and_split "addpsi3" 1996 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r") 1997 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0") 1998 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n"))) 1999 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))] 2000 "" 2001 "#" 2002 "&& reload_completed" 2003 [(parallel [(set (match_dup 0) 2004 (plus:PSI (match_dup 1) 2005 (match_dup 2))) 2006 (clobber (match_dup 3 )) 2007 (clobber (reg:CC REG_CC))])]) 2008 2009 (define_insn "*addpsi3" 2010 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r") 2011 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0") 2012 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n"))) 2013 (clobber (match_scratch:QI 3 "=X,X ,X,&d")) 2014 (clobber (reg:CC REG_CC))] 2015 "reload_completed" 2016 { 2017 return avr_out_plus (insn, operands); 2018 } 2019 [(set_attr "length" "3") 2020 (set_attr "adjust_len" "plus")]) 2021 2022 (define_insn_and_split "subpsi3" 2023 [(set (match_operand:PSI 0 "register_operand" "=r") 2024 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2025 (match_operand:PSI 2 "register_operand" "r")))] 2026 "" 2027 "#" 2028 "&& reload_completed" 2029 [(parallel [(set (match_dup 0) 2030 (minus:PSI (match_dup 1) 2031 (match_dup 2))) 2032 (clobber (reg:CC REG_CC))])]) 2033 2034 (define_insn "*subpsi3" 2035 [(set (match_operand:PSI 0 "register_operand" "=r") 2036 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2037 (match_operand:PSI 2 "register_operand" "r"))) 2038 (clobber (reg:CC REG_CC))] 2039 "reload_completed" 2040 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2" 2041 [(set_attr "length" "3")]) 2042 2043 (define_insn_and_split "*subpsi3_zero_extend.qi_split" 2044 [(set (match_operand:PSI 0 "register_operand" "=r") 2045 (minus:PSI (match_operand:SI 1 "register_operand" "0") 2046 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))] 2047 "" 2048 "#" 2049 "&& reload_completed" 2050 [(parallel [(set (match_dup 0) 2051 (minus:PSI (match_dup 1) 2052 (zero_extend:PSI (match_dup 2)))) 2053 (clobber (reg:CC REG_CC))])]) 2054 2055 (define_insn "*subpsi3_zero_extend.qi" 2056 [(set (match_operand:PSI 0 "register_operand" "=r") 2057 (minus:PSI (match_operand:SI 1 "register_operand" "0") 2058 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r")))) 2059 (clobber (reg:CC REG_CC))] 2060 "reload_completed" 2061 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__" 2062 [(set_attr "length" "3")]) 2063 2064 (define_insn_and_split "*subpsi3_zero_extend.hi_split" 2065 [(set (match_operand:PSI 0 "register_operand" "=r") 2066 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2067 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 2068 "" 2069 "#" 2070 "&& reload_completed" 2071 [(parallel [(set (match_dup 0) 2072 (minus:PSI (match_dup 1) 2073 (zero_extend:PSI (match_dup 2)))) 2074 (clobber (reg:CC REG_CC))])]) 2075 2076 (define_insn "*subpsi3_zero_extend.hi" 2077 [(set (match_operand:PSI 0 "register_operand" "=r") 2078 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2079 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")))) 2080 (clobber (reg:CC REG_CC))] 2081 "reload_completed" 2082 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__" 2083 [(set_attr "length" "3")]) 2084 2085 (define_insn_and_split "*subpsi3_sign_extend.hi_split" 2086 [(set (match_operand:PSI 0 "register_operand" "=r") 2087 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2088 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 2089 "" 2090 "#" 2091 "&& reload_completed" 2092 [(parallel [(set (match_dup 0) 2093 (minus:PSI (match_dup 1) 2094 (sign_extend:PSI (match_dup 2)))) 2095 (clobber (reg:CC REG_CC))])]) 2096 2097 (define_insn "*subpsi3_sign_extend.hi" 2098 [(set (match_operand:PSI 0 "register_operand" "=r") 2099 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 2100 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r")))) 2101 (clobber (reg:CC REG_CC))] 2102 "reload_completed" 2103 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0" 2104 [(set_attr "length" "5")]) 2105 2106 ;----------------------------------------------------------------------------- 2107 ; sub bytes 2108 2109 ;; "subqi3" 2110 ;; "subqq3" "subuqq3" 2111 (define_insn_and_split "sub<mode>3" 2112 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r") 2113 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0") 2114 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))] 2115 "" 2116 "#" 2117 "&& reload_completed" 2118 [(parallel [(set (match_dup 0) 2119 (minus:ALL1 (match_dup 1) 2120 (match_dup 2))) 2121 (clobber (reg:CC REG_CC))])]) 2122 2123 (define_insn "*sub<mode>3" 2124 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r") 2125 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0") 2126 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2"))) 2127 (clobber (reg:CC REG_CC))] 2128 "reload_completed" 2129 "@ 2130 sub %0,%2 2131 subi %0,lo8(%2) 2132 dec %0 2133 inc %0 2134 dec %0\;dec %0 2135 inc %0\;inc %0" 2136 [(set_attr "length" "1,1,1,1,2,2")]) 2137 2138 ;; "subhi3" 2139 ;; "subhq3" "subuhq3" 2140 ;; "subha3" "subuha3" 2141 (define_insn_and_split "sub<mode>3" 2142 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r") 2143 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0") 2144 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn"))) 2145 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 2146 "" 2147 "#" 2148 "&& reload_completed" 2149 [(parallel [(set (match_dup 0) 2150 (minus:ALL2 (match_dup 1) 2151 (match_dup 2))) 2152 (clobber (match_dup 3)) 2153 (clobber (reg:CC REG_CC))])]) 2154 2155 (define_insn "*sub<mode>3" 2156 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r") 2157 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0") 2158 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn"))) 2159 (clobber (match_scratch:QI 3 "=X,X ,&d")) 2160 (clobber (reg:CC REG_CC))] 2161 "reload_completed" 2162 { 2163 return avr_out_plus (insn, operands); 2164 } 2165 [(set_attr "adjust_len" "plus")]) 2166 2167 (define_insn_and_split "*subhi3_zero_extend1_split" 2168 [(set (match_operand:HI 0 "register_operand" "=r") 2169 (minus:HI (match_operand:HI 1 "register_operand" "0") 2170 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 2171 "" 2172 "#" 2173 "&& reload_completed" 2174 [(parallel [(set (match_dup 0) 2175 (minus:HI (match_dup 1) 2176 (zero_extend:HI (match_dup 2)))) 2177 (clobber (reg:CC REG_CC))])]) 2178 2179 (define_insn "*subhi3_zero_extend1" 2180 [(set (match_operand:HI 0 "register_operand" "=r") 2181 (minus:HI (match_operand:HI 1 "register_operand" "0") 2182 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))) 2183 (clobber (reg:CC REG_CC))] 2184 "reload_completed" 2185 "sub %A0,%2\;sbc %B0,__zero_reg__" 2186 [(set_attr "length" "2")]) 2187 2188 (define_insn_and_split "*subhi3.sign_extend2_split" 2189 [(set (match_operand:HI 0 "register_operand" "=r") 2190 (minus:HI (match_operand:HI 1 "register_operand" "0") 2191 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 2192 "" 2193 "#" 2194 "&& reload_completed" 2195 [(parallel [(set (match_dup 0) 2196 (minus:HI (match_dup 1) 2197 (sign_extend:HI (match_dup 2)))) 2198 (clobber (reg:CC REG_CC))])]) 2199 2200 2201 (define_insn "*subhi3.sign_extend2" 2202 [(set (match_operand:HI 0 "register_operand" "=r") 2203 (minus:HI (match_operand:HI 1 "register_operand" "0") 2204 (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))) 2205 (clobber (reg:CC REG_CC))] 2206 "reload_completed" 2207 { 2208 return reg_overlap_mentioned_p (operands[0], operands[2]) 2209 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0" 2210 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0"; 2211 } 2212 [(set (attr "length") 2213 (symbol_ref ("4 + reg_overlap_mentioned_p (operands[0], operands[2])")))]) 2214 2215 ;; "subsi3" 2216 ;; "subsq3" "subusq3" 2217 ;; "subsa3" "subusa3" 2218 (define_insn_and_split "sub<mode>3" 2219 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 2220 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0") 2221 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn"))) 2222 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 2223 "" 2224 "#" 2225 "&& reload_completed" 2226 [(parallel [(set (match_dup 0) 2227 (minus:ALL4 (match_dup 1) 2228 (match_dup 2))) 2229 (clobber (match_dup 3)) 2230 (clobber (reg:CC REG_CC))])]) 2231 2232 (define_insn "*sub<mode>3" 2233 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 2234 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0") 2235 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn"))) 2236 (clobber (match_scratch:QI 3 "=X,X ,&d")) 2237 (clobber (reg:CC REG_CC))] 2238 "reload_completed" 2239 { 2240 return avr_out_plus (insn, operands); 2241 } 2242 [(set_attr "adjust_len" "plus")]) 2243 2244 (define_insn_and_split "*subsi3_zero_extend_split" 2245 [(set (match_operand:SI 0 "register_operand" "=r") 2246 (minus:SI (match_operand:SI 1 "register_operand" "0") 2247 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))] 2248 "" 2249 "#" 2250 "&& reload_completed" 2251 [(parallel [(set (match_dup 0) 2252 (minus:SI (match_dup 1) 2253 (zero_extend:SI (match_dup 2)))) 2254 (clobber (reg:CC REG_CC))])]) 2255 2256 (define_insn "*subsi3_zero_extend" 2257 [(set (match_operand:SI 0 "register_operand" "=r") 2258 (minus:SI (match_operand:SI 1 "register_operand" "0") 2259 (zero_extend:SI (match_operand:QI 2 "register_operand" "r")))) 2260 (clobber (reg:CC REG_CC))] 2261 "reload_completed" 2262 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__" 2263 [(set_attr "length" "4") 2264 ]) 2265 2266 (define_insn_and_split "*subsi3_zero_extend.hi_split" 2267 [(set (match_operand:SI 0 "register_operand" "=r") 2268 (minus:SI (match_operand:SI 1 "register_operand" "0") 2269 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 2270 "" 2271 "#" 2272 "&& reload_completed" 2273 [(parallel [(set (match_dup 0) 2274 (minus:SI (match_dup 1) 2275 (zero_extend:SI (match_dup 2)))) 2276 (clobber (reg:CC REG_CC))])]) 2277 2278 (define_insn "*subsi3_zero_extend.hi" 2279 [(set (match_operand:SI 0 "register_operand" "=r") 2280 (minus:SI (match_operand:SI 1 "register_operand" "0") 2281 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))) 2282 (clobber (reg:CC REG_CC))] 2283 "reload_completed" 2284 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__" 2285 [(set_attr "length" "4")]) 2286 2287 ;****************************************************************************** 2288 ; mul 2289 2290 (define_expand "mulqi3" 2291 [(set (match_operand:QI 0 "register_operand" "") 2292 (mult:QI (match_operand:QI 1 "register_operand" "") 2293 (match_operand:QI 2 "register_operand" "")))] 2294 "" 2295 { 2296 if (!AVR_HAVE_MUL) 2297 { 2298 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2])); 2299 DONE; 2300 } 2301 }) 2302 2303 (define_insn_and_split "*mulqi3_enh_split" 2304 [(set (match_operand:QI 0 "register_operand" "=r") 2305 (mult:QI (match_operand:QI 1 "register_operand" "r") 2306 (match_operand:QI 2 "register_operand" "r")))] 2307 "AVR_HAVE_MUL" 2308 "#" 2309 "&& reload_completed" 2310 [(parallel [(set (match_dup 0) 2311 (mult:QI (match_dup 1) 2312 (match_dup 2))) 2313 (clobber (reg:CC REG_CC))])]) 2314 2315 (define_insn "*mulqi3_enh" 2316 [(set (match_operand:QI 0 "register_operand" "=r") 2317 (mult:QI (match_operand:QI 1 "register_operand" "r") 2318 (match_operand:QI 2 "register_operand" "r"))) 2319 (clobber (reg:CC REG_CC))] 2320 "AVR_HAVE_MUL && reload_completed" 2321 "mul %1,%2 2322 mov %0,r0 2323 clr r1" 2324 [(set_attr "length" "3")]) 2325 2326 (define_expand "mulqi3_call" 2327 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" "")) 2328 (set (reg:QI 22) (match_operand:QI 2 "register_operand" "")) 2329 (parallel [(set (reg:QI 24) 2330 (mult:QI (reg:QI 24) (reg:QI 22))) 2331 (clobber (reg:QI 22))]) 2332 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))] 2333 "" 2334 { 2335 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 2336 }) 2337 2338 (define_insn_and_split "*mulqi3_call_split" 2339 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22))) 2340 (clobber (reg:QI 22))] 2341 "!AVR_HAVE_MUL" 2342 "#" 2343 "&& reload_completed" 2344 [(parallel [(set (reg:QI 24) 2345 (mult:QI (reg:QI 24) (reg:QI 22))) 2346 (clobber (reg:QI 22)) 2347 (clobber (reg:CC REG_CC))])]) 2348 2349 (define_insn "*mulqi3_call" 2350 [(set (reg:QI 24) 2351 (mult:QI (reg:QI 24) (reg:QI 22))) 2352 (clobber (reg:QI 22)) 2353 (clobber (reg:CC REG_CC))] 2354 "!AVR_HAVE_MUL && reload_completed" 2355 "%~call __mulqi3" 2356 [(set_attr "type" "xcall")]) 2357 2358 ;; "umulqi3_highpart" 2359 ;; "smulqi3_highpart" 2360 2361 (define_insn_and_split "<extend_su>mulqi3_highpart" 2362 [(set (match_operand:QI 0 "register_operand" "=r") 2363 (truncate:QI 2364 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2365 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 2366 (const_int 8))))] 2367 "AVR_HAVE_MUL" 2368 "#" 2369 "&& reload_completed" 2370 [(parallel [(set (match_dup 0) 2371 (truncate:QI 2372 (lshiftrt:HI (mult:HI (any_extend:HI (match_dup 1)) 2373 (any_extend:HI (match_dup 2))) 2374 (const_int 8)))) 2375 (clobber (reg:CC REG_CC))])]) 2376 2377 (define_insn "*<extend_su>mulqi3_highpart" 2378 [(set (match_operand:QI 0 "register_operand" "=r") 2379 (truncate:QI 2380 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2381 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 2382 (const_int 8)))) 2383 (clobber (reg:CC REG_CC))] 2384 "AVR_HAVE_MUL && reload_completed" 2385 "mul<extend_s> %1,%2 2386 mov %0,r1 2387 clr __zero_reg__" 2388 [(set_attr "length" "3")]) 2389 2390 2391 ;; Used when expanding div or mod inline for some special values 2392 (define_insn_and_split "*subqi3.ashiftrt7_split" 2393 [(set (match_operand:QI 0 "register_operand" "=r") 2394 (minus:QI (match_operand:QI 1 "register_operand" "0") 2395 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r") 2396 (const_int 7))))] 2397 "" 2398 "#" 2399 "&& reload_completed" 2400 [(parallel [(set (match_dup 0) 2401 (minus:QI (match_dup 1) 2402 (ashiftrt:QI (match_dup 2) 2403 (const_int 7)))) 2404 (clobber (reg:CC REG_CC))])]) 2405 2406 (define_insn "*subqi3.ashiftrt7" 2407 [(set (match_operand:QI 0 "register_operand" "=r") 2408 (minus:QI (match_operand:QI 1 "register_operand" "0") 2409 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r") 2410 (const_int 7)))) 2411 (clobber (reg:CC REG_CC))] 2412 "reload_completed" 2413 "sbrc %2,7\;inc %0" 2414 [(set_attr "length" "2")]) 2415 2416 (define_insn_and_split "*addqi3.lt0_split" 2417 [(set (match_operand:QI 0 "register_operand" "=r") 2418 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r") 2419 (const_int 0)) 2420 (match_operand:QI 2 "register_operand" "0")))] 2421 "" 2422 "#" 2423 "&& reload_completed" 2424 [(parallel [(set (match_dup 0) 2425 (plus:QI (lt:QI (match_dup 1) 2426 (const_int 0)) 2427 (match_dup 2))) 2428 (clobber (reg:CC REG_CC))])]) 2429 2430 (define_insn "*addqi3.lt0" 2431 [(set (match_operand:QI 0 "register_operand" "=r") 2432 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r") 2433 (const_int 0)) 2434 (match_operand:QI 2 "register_operand" "0"))) 2435 (clobber (reg:CC REG_CC))] 2436 "reload_completed" 2437 "sbrc %1,7\;inc %0" 2438 [(set_attr "length" "2")]) 2439 2440 (define_insn_and_split "*addhi3.lt0_split" 2441 [(set (match_operand:HI 0 "register_operand" "=w,r") 2442 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r") 2443 (const_int 0)) 2444 (match_operand:HI 2 "register_operand" "0,0"))) 2445 (clobber (match_scratch:QI 3 "=X,&1"))] 2446 "" 2447 "#" 2448 "&& reload_completed" 2449 [(parallel [(set (match_dup 0) 2450 (plus:HI (lt:HI (match_dup 1) 2451 (const_int 0)) 2452 (match_dup 2))) 2453 (clobber (match_dup 3)) 2454 (clobber (reg:CC REG_CC))])] 2455 "" 2456 [(set_attr "isa" "adiw,*")]) 2457 2458 (define_insn "*addhi3.lt0" 2459 [(set (match_operand:HI 0 "register_operand" "=w,r") 2460 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r") 2461 (const_int 0)) 2462 (match_operand:HI 2 "register_operand" "0,0"))) 2463 (clobber (match_scratch:QI 3 "=X,&1")) 2464 (clobber (reg:CC REG_CC))] 2465 "reload_completed" 2466 "@ 2467 sbrc %1,7\;adiw %0,1 2468 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__" 2469 [(set_attr "length" "2,3") 2470 (set_attr "isa" "adiw,*")]) 2471 2472 (define_insn_and_split "*addpsi3.lt0_split" 2473 [(set (match_operand:PSI 0 "register_operand" "=r") 2474 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r") 2475 (const_int 23)) 2476 (match_operand:PSI 2 "register_operand" "0")))] 2477 "" 2478 "#" 2479 "&& reload_completed" 2480 [(parallel [(set (match_dup 0) 2481 (plus:PSI (lshiftrt:PSI (match_dup 1) 2482 (const_int 23)) 2483 (match_dup 2))) 2484 (clobber (reg:CC REG_CC))])]) 2485 2486 (define_insn "*addpsi3.lt0" 2487 [(set (match_operand:PSI 0 "register_operand" "=r") 2488 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r") 2489 (const_int 23)) 2490 (match_operand:PSI 2 "register_operand" "0"))) 2491 (clobber (reg:CC REG_CC))] 2492 "reload_completed" 2493 "mov __tmp_reg__,%C1\;lsl __tmp_reg__ 2494 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__" 2495 [(set_attr "length" "5")]) 2496 2497 (define_insn_and_split "*addsi3.lt0_split" 2498 [(set (match_operand:SI 0 "register_operand" "=r") 2499 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 2500 (const_int 31)) 2501 (match_operand:SI 2 "register_operand" "0")))] 2502 "" 2503 "#" 2504 "&& reload_completed" 2505 [(parallel [(set (match_dup 0) 2506 (plus:SI (lshiftrt:SI (match_dup 1) 2507 (const_int 31)) 2508 (match_dup 2))) 2509 (clobber (reg:CC REG_CC))])]) 2510 2511 (define_insn "*addsi3.lt0" 2512 [(set (match_operand:SI 0 "register_operand" "=r") 2513 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 2514 (const_int 31)) 2515 (match_operand:SI 2 "register_operand" "0"))) 2516 (clobber (reg:CC REG_CC))] 2517 "reload_completed" 2518 "mov __tmp_reg__,%D1\;lsl __tmp_reg__ 2519 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 2520 [(set_attr "length" "6")]) 2521 2522 (define_insn_and_split "*umulqihi3.call_split" 2523 [(set (reg:HI 24) 2524 (mult:HI (zero_extend:HI (reg:QI 22)) 2525 (zero_extend:HI (reg:QI 24)))) 2526 (clobber (reg:QI 21)) 2527 (clobber (reg:HI 22))] 2528 "!AVR_HAVE_MUL" 2529 "#" 2530 "&& reload_completed" 2531 [(parallel [(set (reg:HI 24) 2532 (mult:HI (zero_extend:HI (reg:QI 22)) 2533 (zero_extend:HI (reg:QI 24)))) 2534 (clobber (reg:QI 21)) 2535 (clobber (reg:HI 22)) 2536 (clobber (reg:CC REG_CC))])]) 2537 2538 (define_insn "*umulqihi3.call" 2539 [(set (reg:HI 24) 2540 (mult:HI (zero_extend:HI (reg:QI 22)) 2541 (zero_extend:HI (reg:QI 24)))) 2542 (clobber (reg:QI 21)) 2543 (clobber (reg:HI 22)) 2544 (clobber (reg:CC REG_CC))] 2545 "!AVR_HAVE_MUL && reload_completed" 2546 "%~call __umulqihi3" 2547 [(set_attr "type" "xcall")]) 2548 2549 ;; "umulqihi3" 2550 ;; "mulqihi3" 2551 2552 (define_insn_and_split "<extend_u>mulqihi3_split" 2553 [(set (match_operand:HI 0 "register_operand" "=r") 2554 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2555 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))] 2556 "AVR_HAVE_MUL" 2557 "#" 2558 "&& reload_completed" 2559 [(parallel [(set (match_dup 0) 2560 (mult:HI (any_extend:HI (match_dup 1)) 2561 (any_extend:HI (match_dup 2)))) 2562 (clobber (reg:CC REG_CC))])]) 2563 2564 (define_insn "<extend_u>mulqihi3" 2565 [(set (match_operand:HI 0 "register_operand" "=r") 2566 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2567 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))) 2568 (clobber (reg:CC REG_CC))] 2569 "AVR_HAVE_MUL && reload_completed" 2570 "mul<extend_s> %1,%2 2571 movw %0,r0 2572 clr __zero_reg__" 2573 [(set_attr "length" "3")]) 2574 2575 (define_insn_and_split "usmulqihi3" 2576 [(set (match_operand:HI 0 "register_operand" "=r") 2577 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a")) 2578 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 2579 "AVR_HAVE_MUL" 2580 "#" 2581 "&& reload_completed" 2582 [(parallel [(set (match_dup 0) 2583 (mult:HI (zero_extend:HI (match_dup 1)) 2584 (sign_extend:HI (match_dup 2)))) 2585 (clobber (reg:CC REG_CC))])]) 2586 2587 (define_insn "*usmulqihi3" 2588 [(set (match_operand:HI 0 "register_operand" "=r") 2589 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a")) 2590 (sign_extend:HI (match_operand:QI 2 "register_operand" "a")))) 2591 (clobber (reg:CC REG_CC))] 2592 "AVR_HAVE_MUL && reload_completed" 2593 "mulsu %2,%1 2594 movw %0,r0 2595 clr __zero_reg__" 2596 [(set_attr "length" "3")]) 2597 2598 ;; Above insn is not canonicalized by insn combine, so here is a version with 2599 ;; operands swapped. 2600 (define_insn_and_split "*sumulqihi3_split" 2601 [(set (match_operand:HI 0 "register_operand" "=r") 2602 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2603 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 2604 "AVR_HAVE_MUL" 2605 "#" 2606 "&& reload_completed" 2607 [(parallel [(set (match_dup 0) 2608 (mult:HI (sign_extend:HI (match_dup 1)) 2609 (zero_extend:HI (match_dup 2)))) 2610 (clobber (reg:CC REG_CC))])]) 2611 2612 (define_insn "*sumulqihi3" 2613 [(set (match_operand:HI 0 "register_operand" "=r") 2614 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2615 (zero_extend:HI (match_operand:QI 2 "register_operand" "a")))) 2616 (clobber (reg:CC REG_CC))] 2617 "AVR_HAVE_MUL && reload_completed" 2618 "mulsu %1,%2 2619 movw %0,r0 2620 clr __zero_reg__" 2621 [(set_attr "length" "3")]) 2622 2623 ;; One-extend operand 1 2624 2625 (define_insn_and_split "*osmulqihi3_split" 2626 [(set (match_operand:HI 0 "register_operand" "=&r") 2627 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a")))) 2628 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 2629 "AVR_HAVE_MUL" 2630 "#" 2631 "&& reload_completed" 2632 [(parallel [(set (match_dup 0) 2633 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) 2634 (sign_extend:HI (match_dup 2)))) 2635 (clobber (reg:CC REG_CC))])]) 2636 2637 (define_insn "*osmulqihi3" 2638 [(set (match_operand:HI 0 "register_operand" "=&r") 2639 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a")))) 2640 (sign_extend:HI (match_operand:QI 2 "register_operand" "a")))) 2641 (clobber (reg:CC REG_CC))] 2642 "AVR_HAVE_MUL && reload_completed" 2643 "mulsu %2,%1 2644 movw %0,r0 2645 sub %B0,%2 2646 clr __zero_reg__" 2647 [(set_attr "length" "4")]) 2648 2649 (define_insn_and_split "*oumulqihi3_split" 2650 [(set (match_operand:HI 0 "register_operand" "=&r") 2651 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 2652 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 2653 "AVR_HAVE_MUL" 2654 "#" 2655 "&& reload_completed" 2656 [(parallel [(set (match_dup 0) 2657 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) 2658 (zero_extend:HI (match_dup 2)))) 2659 (clobber (reg:CC REG_CC))])]) 2660 2661 (define_insn "*oumulqihi3" 2662 [(set (match_operand:HI 0 "register_operand" "=&r") 2663 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 2664 (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))) 2665 (clobber (reg:CC REG_CC))] 2666 "AVR_HAVE_MUL && reload_completed" 2667 "mul %2,%1 2668 movw %0,r0 2669 sub %B0,%2 2670 clr __zero_reg__" 2671 [(set_attr "length" "4")]) 2672 2673 ;****************************************************************************** 2674 ; multiply-add/sub QI: $0 = $3 +/- $1*$2 2675 ;****************************************************************************** 2676 2677 (define_insn_and_split "*maddqi4_split" 2678 [(set (match_operand:QI 0 "register_operand" "=r") 2679 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r") 2680 (match_operand:QI 2 "register_operand" "r")) 2681 (match_operand:QI 3 "register_operand" "0")))] 2682 2683 "AVR_HAVE_MUL" 2684 "#" 2685 "&& reload_completed" 2686 [(parallel [(set (match_dup 0) 2687 (plus:QI (mult:QI (match_dup 1) 2688 (match_dup 2)) 2689 (match_dup 3))) 2690 (clobber (reg:CC REG_CC))])]) 2691 2692 (define_insn "*maddqi4" 2693 [(set (match_operand:QI 0 "register_operand" "=r") 2694 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r") 2695 (match_operand:QI 2 "register_operand" "r")) 2696 (match_operand:QI 3 "register_operand" "0"))) 2697 (clobber (reg:CC REG_CC))] 2698 "AVR_HAVE_MUL && reload_completed" 2699 "mul %1,%2 2700 add %A0,r0 2701 clr __zero_reg__" 2702 [(set_attr "length" "4")]) 2703 2704 (define_insn_and_split "*msubqi4_split" 2705 [(set (match_operand:QI 0 "register_operand" "=r") 2706 (minus:QI (match_operand:QI 3 "register_operand" "0") 2707 (mult:QI (match_operand:QI 1 "register_operand" "r") 2708 (match_operand:QI 2 "register_operand" "r"))))] 2709 "AVR_HAVE_MUL" 2710 "#" 2711 "&& reload_completed" 2712 [(parallel [(set (match_dup 0) 2713 (minus:QI (match_dup 3) 2714 (mult:QI (match_dup 1) 2715 (match_dup 2)))) 2716 (clobber (reg:CC REG_CC))])]) 2717 2718 (define_insn "*msubqi4" 2719 [(set (match_operand:QI 0 "register_operand" "=r") 2720 (minus:QI (match_operand:QI 3 "register_operand" "0") 2721 (mult:QI (match_operand:QI 1 "register_operand" "r") 2722 (match_operand:QI 2 "register_operand" "r")))) 2723 (clobber (reg:CC REG_CC))] 2724 "AVR_HAVE_MUL && reload_completed" 2725 "mul %1,%2 2726 sub %A0,r0 2727 clr __zero_reg__" 2728 [(set_attr "length" "4")]) 2729 2730 (define_insn_and_split "*maddqi4.const" 2731 [(set (match_operand:QI 0 "register_operand" "=r") 2732 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r") 2733 (match_operand:QI 2 "const_int_operand" "n")) 2734 (match_operand:QI 3 "register_operand" "0"))) 2735 (clobber (match_scratch:QI 4 "=&d"))] 2736 "AVR_HAVE_MUL" 2737 "#" 2738 "&& reload_completed" 2739 [(set (match_dup 4) 2740 (match_dup 2)) 2741 ; *maddqi4 2742 (set (match_dup 0) 2743 (plus:QI (mult:QI (match_dup 1) 2744 (match_dup 4)) 2745 (match_dup 3)))]) 2746 2747 (define_insn_and_split "*msubqi4.const" 2748 [(set (match_operand:QI 0 "register_operand" "=r") 2749 (minus:QI (match_operand:QI 3 "register_operand" "0") 2750 (mult:QI (match_operand:QI 1 "register_operand" "r") 2751 (match_operand:QI 2 "const_int_operand" "n")))) 2752 (clobber (match_scratch:QI 4 "=&d"))] 2753 "AVR_HAVE_MUL" 2754 "#" 2755 "&& reload_completed" 2756 [(set (match_dup 4) 2757 (match_dup 2)) 2758 ; *msubqi4 2759 (set (match_dup 0) 2760 (minus:QI (match_dup 3) 2761 (mult:QI (match_dup 1) 2762 (match_dup 4))))]) 2763 2764 2765 ;****************************************************************************** 2766 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2 2767 ;****************************************************************************** 2768 2769 ;; We don't use standard insns/expanders as they lead to cumbersome code for, 2770 ;; e.g, 2771 ;; 2772 ;; int foo (unsigned char z) 2773 ;; { 2774 ;; extern int aInt[]; 2775 ;; return aInt[3*z+2]; 2776 ;; } 2777 ;; 2778 ;; because the constant +4 then is added explicitely instead of consuming it 2779 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs 2780 ;; into account more accurately and doesn't do burte-force multiply-add/sub. 2781 ;; The implementational effort is the same so we are fine with that approach. 2782 2783 2784 ;; "*maddqihi4" 2785 ;; "*umaddqihi4" 2786 (define_insn_and_split "*<extend_u>maddqihi4_split" 2787 [(set (match_operand:HI 0 "register_operand" "=r") 2788 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2789 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 2790 (match_operand:HI 3 "register_operand" "0")))] 2791 2792 "AVR_HAVE_MUL" 2793 "#" 2794 "&& reload_completed" 2795 [(parallel [(set (match_dup 0) 2796 (plus:HI (mult:HI (any_extend:HI (match_dup 1)) 2797 (any_extend:HI (match_dup 2))) 2798 (match_dup 3))) 2799 (clobber (reg:CC REG_CC))])]) 2800 2801 (define_insn "*<extend_u>maddqihi4" 2802 [(set (match_operand:HI 0 "register_operand" "=r") 2803 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2804 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 2805 (match_operand:HI 3 "register_operand" "0"))) 2806 (clobber (reg:CC REG_CC))] 2807 "AVR_HAVE_MUL && reload_completed" 2808 "mul<extend_s> %1,%2 2809 add %A0,r0 2810 adc %B0,r1 2811 clr __zero_reg__" 2812 [(set_attr "length" "4")]) 2813 2814 ;; "*msubqihi4" 2815 ;; "*umsubqihi4" 2816 (define_insn_and_split "*<extend_u>msubqihi4_split" 2817 [(set (match_operand:HI 0 "register_operand" "=r") 2818 (minus:HI (match_operand:HI 3 "register_operand" "0") 2819 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2820 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))] 2821 "AVR_HAVE_MUL" 2822 "#" 2823 "&& reload_completed" 2824 [(parallel [(set (match_dup 0) 2825 (minus:HI (match_dup 3) 2826 (mult:HI (any_extend:HI (match_dup 1)) 2827 (any_extend:HI (match_dup 2))))) 2828 (clobber (reg:CC REG_CC))])]) 2829 2830 (define_insn "*<extend_u>msubqihi4" 2831 [(set (match_operand:HI 0 "register_operand" "=r") 2832 (minus:HI (match_operand:HI 3 "register_operand" "0") 2833 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2834 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))) 2835 (clobber (reg:CC REG_CC))] 2836 "AVR_HAVE_MUL && reload_completed" 2837 "mul<extend_s> %1,%2 2838 sub %A0,r0 2839 sbc %B0,r1 2840 clr __zero_reg__" 2841 [(set_attr "length" "4")]) 2842 2843 ;; "*usmaddqihi4" 2844 ;; "*sumaddqihi4" 2845 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split" 2846 [(set (match_operand:HI 0 "register_operand" "=r") 2847 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 2848 (any_extend2:HI (match_operand:QI 2 "register_operand" "a"))) 2849 (match_operand:HI 3 "register_operand" "0")))] 2850 "AVR_HAVE_MUL 2851 && reload_completed 2852 && <any_extend:CODE> != <any_extend2:CODE>" 2853 "#" 2854 "&& reload_completed" 2855 [(parallel [(set (match_dup 0) 2856 (plus:HI (mult:HI (any_extend:HI (match_dup 1)) 2857 (any_extend2:HI (match_dup 2))) 2858 (match_dup 3))) 2859 (clobber (reg:CC REG_CC))])]) 2860 2861 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" 2862 [(set (match_operand:HI 0 "register_operand" "=r") 2863 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 2864 (any_extend2:HI (match_operand:QI 2 "register_operand" "a"))) 2865 (match_operand:HI 3 "register_operand" "0"))) 2866 (clobber (reg:CC REG_CC))] 2867 "AVR_HAVE_MUL 2868 && reload_completed 2869 && <any_extend:CODE> != <any_extend2:CODE>" 2870 { 2871 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND 2872 ? "mulsu %1,%2" : "mulsu %2,%1", operands); 2873 2874 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__"; 2875 } 2876 [(set_attr "length" "4")]) 2877 2878 ;; "*usmsubqihi4" 2879 ;; "*sumsubqihi4" 2880 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split" 2881 [(set (match_operand:HI 0 "register_operand" "=r") 2882 (minus:HI (match_operand:HI 3 "register_operand" "0") 2883 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 2884 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))] 2885 "AVR_HAVE_MUL 2886 && reload_completed 2887 && <any_extend:CODE> != <any_extend2:CODE>" 2888 "#" 2889 "&& reload_completed" 2890 [(parallel [(set (match_dup 0) 2891 (minus:HI (match_dup 3) 2892 (mult:HI (any_extend:HI (match_dup 1)) 2893 (any_extend2:HI (match_dup 2))))) 2894 (clobber (reg:CC REG_CC))])]) 2895 2896 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" 2897 [(set (match_operand:HI 0 "register_operand" "=r") 2898 (minus:HI (match_operand:HI 3 "register_operand" "0") 2899 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 2900 (any_extend2:HI (match_operand:QI 2 "register_operand" "a"))))) 2901 (clobber (reg:CC REG_CC))] 2902 "AVR_HAVE_MUL 2903 && reload_completed 2904 && <any_extend:CODE> != <any_extend2:CODE>" 2905 { 2906 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND 2907 ? "mulsu %1,%2" : "mulsu %2,%1", operands); 2908 2909 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__"; 2910 } 2911 [(set_attr "length" "4")]) 2912 2913 ;; Handle small constants 2914 2915 ;; Special case of a += 2*b as frequently seen with accesses to int arrays. 2916 ;; This is shorter, faster than MUL and has lower register pressure. 2917 ;; See also "*addhi3_zero_extend.ashift1". 2918 (define_insn_and_split "*umaddqihi4.2" 2919 [(set (match_operand:HI 0 "register_operand" "=r") 2920 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 2921 (const_int 2)) 2922 (match_operand:HI 2 "register_operand" "r")))] 2923 "!reload_completed 2924 && !reg_overlap_mentioned_p (operands[0], operands[1])" 2925 { gcc_unreachable(); } 2926 "&& 1" 2927 [(set (match_dup 0) 2928 (match_dup 2)) 2929 ; *addhi3_zero_extend 2930 (set (match_dup 0) 2931 (plus:HI (zero_extend:HI (match_dup 1)) 2932 (match_dup 0))) 2933 ; *addhi3_zero_extend 2934 (set (match_dup 0) 2935 (plus:HI (zero_extend:HI (match_dup 1)) 2936 (match_dup 0)))]) 2937 2938 ;; "umaddqihi4.uconst" 2939 ;; "maddqihi4.sconst" 2940 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const" 2941 [(set (match_operand:HI 0 "register_operand" "=r") 2942 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2943 (match_operand:HI 2 "<extend_su>8_operand" "n")) 2944 (match_operand:HI 3 "register_operand" "0"))) 2945 (clobber (match_scratch:QI 4 "=&d"))] 2946 "AVR_HAVE_MUL" 2947 "#" 2948 "&& reload_completed" 2949 [(set (match_dup 4) 2950 (match_dup 2)) 2951 ; *umaddqihi4 resp. *maddqihi4 2952 (set (match_dup 0) 2953 (plus:HI (mult:HI (any_extend:HI (match_dup 1)) 2954 (any_extend:HI (match_dup 4))) 2955 (match_dup 3)))] 2956 { 2957 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2958 }) 2959 2960 ;; "*umsubqihi4.uconst" 2961 ;; "*msubqihi4.sconst" 2962 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const" 2963 [(set (match_operand:HI 0 "register_operand" "=r") 2964 (minus:HI (match_operand:HI 3 "register_operand" "0") 2965 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2966 (match_operand:HI 2 "<extend_su>8_operand" "n")))) 2967 (clobber (match_scratch:QI 4 "=&d"))] 2968 "AVR_HAVE_MUL" 2969 "#" 2970 "&& reload_completed" 2971 [(set (match_dup 4) 2972 (match_dup 2)) 2973 ; *umsubqihi4 resp. *msubqihi4 2974 (set (match_dup 0) 2975 (minus:HI (match_dup 3) 2976 (mult:HI (any_extend:HI (match_dup 1)) 2977 (any_extend:HI (match_dup 4)))))] 2978 { 2979 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2980 }) 2981 2982 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT 2983 ;; for MULT with power of 2 and skips trying MULT insn above. 2984 2985 (define_insn_and_split "*umsubqihi4.uconst.ashift" 2986 [(set (match_operand:HI 0 "register_operand" "=r") 2987 (minus:HI (match_operand:HI 3 "register_operand" "0") 2988 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 2989 (match_operand:HI 2 "const_2_to_7_operand" "n")))) 2990 (clobber (match_scratch:QI 4 "=&d"))] 2991 "AVR_HAVE_MUL" 2992 "#" 2993 "&& reload_completed" 2994 [(set (match_dup 4) 2995 (match_dup 2)) 2996 ; *umsubqihi4 2997 (set (match_dup 0) 2998 (minus:HI (match_dup 3) 2999 (mult:HI (zero_extend:HI (match_dup 1)) 3000 (zero_extend:HI (match_dup 4)))))] 3001 { 3002 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 3003 }) 3004 3005 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT 3006 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128 3007 ;; because this would require an extra pattern for just one value. 3008 3009 (define_insn_and_split "*msubqihi4.sconst.ashift" 3010 [(set (match_operand:HI 0 "register_operand" "=r") 3011 (minus:HI (match_operand:HI 3 "register_operand" "0") 3012 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d")) 3013 (match_operand:HI 2 "const_1_to_6_operand" "M")))) 3014 (clobber (match_scratch:QI 4 "=&d"))] 3015 "AVR_HAVE_MUL" 3016 "#" 3017 "&& reload_completed" 3018 [(set (match_dup 4) 3019 (match_dup 2)) 3020 ; *smsubqihi4 3021 (set (match_dup 0) 3022 (minus:HI (match_dup 3) 3023 (mult:HI (sign_extend:HI (match_dup 1)) 3024 (sign_extend:HI (match_dup 4)))))] 3025 { 3026 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 3027 }) 3028 3029 ;; For signed/unsigned combinations that require narrow constraint "a" 3030 ;; just provide a pattern if signed/unsigned combination is actually needed. 3031 3032 (define_insn_and_split "*sumaddqihi4.uconst" 3033 [(set (match_operand:HI 0 "register_operand" "=r") 3034 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3035 (match_operand:HI 2 "u8_operand" "M")) 3036 (match_operand:HI 3 "register_operand" "0"))) 3037 (clobber (match_scratch:QI 4 "=&a"))] 3038 "AVR_HAVE_MUL 3039 && !s8_operand (operands[2], VOIDmode)" 3040 "#" 3041 "&& reload_completed" 3042 [(set (match_dup 4) 3043 (match_dup 2)) 3044 ; *sumaddqihi4 3045 (set (match_dup 0) 3046 (plus:HI (mult:HI (sign_extend:HI (match_dup 1)) 3047 (zero_extend:HI (match_dup 4))) 3048 (match_dup 3)))] 3049 { 3050 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3051 }) 3052 3053 (define_insn_and_split "*sumsubqihi4.uconst" 3054 [(set (match_operand:HI 0 "register_operand" "=r") 3055 (minus:HI (match_operand:HI 3 "register_operand" "0") 3056 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3057 (match_operand:HI 2 "u8_operand" "M")))) 3058 (clobber (match_scratch:QI 4 "=&a"))] 3059 "AVR_HAVE_MUL 3060 && !s8_operand (operands[2], VOIDmode)" 3061 "#" 3062 "&& reload_completed" 3063 [(set (match_dup 4) 3064 (match_dup 2)) 3065 ; *sumsubqihi4 3066 (set (match_dup 0) 3067 (minus:HI (match_dup 3) 3068 (mult:HI (sign_extend:HI (match_dup 1)) 3069 (zero_extend:HI (match_dup 4)))))] 3070 { 3071 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3072 }) 3073 3074 ;****************************************************************************** 3075 ; mul HI: $1 = sign/zero-extend, $2 = small constant 3076 ;****************************************************************************** 3077 3078 ;; "*muluqihi3.uconst" 3079 ;; "*mulsqihi3.sconst" 3080 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const" 3081 [(set (match_operand:HI 0 "register_operand" "=r") 3082 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 3083 (match_operand:HI 2 "<extend_su>8_operand" "n"))) 3084 (clobber (match_scratch:QI 3 "=&d"))] 3085 "AVR_HAVE_MUL" 3086 "#" 3087 "&& reload_completed" 3088 [(set (match_dup 3) 3089 (match_dup 2)) 3090 ; umulqihi3 resp. mulqihi3 3091 (set (match_dup 0) 3092 (mult:HI (any_extend:HI (match_dup 1)) 3093 (any_extend:HI (match_dup 3))))] 3094 { 3095 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3096 }) 3097 3098 (define_insn_and_split "*muluqihi3.sconst" 3099 [(set (match_operand:HI 0 "register_operand" "=r") 3100 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a")) 3101 (match_operand:HI 2 "s8_operand" "n"))) 3102 (clobber (match_scratch:QI 3 "=&a"))] 3103 "AVR_HAVE_MUL" 3104 "#" 3105 "&& reload_completed" 3106 [(set (match_dup 3) 3107 (match_dup 2)) 3108 ; usmulqihi3 3109 (set (match_dup 0) 3110 (mult:HI (zero_extend:HI (match_dup 1)) 3111 (sign_extend:HI (match_dup 3))))] 3112 { 3113 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3114 }) 3115 3116 (define_insn_and_split "*mulsqihi3.uconst" 3117 [(set (match_operand:HI 0 "register_operand" "=r") 3118 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3119 (match_operand:HI 2 "u8_operand" "M"))) 3120 (clobber (match_scratch:QI 3 "=&a"))] 3121 "AVR_HAVE_MUL" 3122 "#" 3123 "&& reload_completed" 3124 [(set (match_dup 3) 3125 (match_dup 2)) 3126 ; usmulqihi3 3127 (set (match_dup 0) 3128 (mult:HI (zero_extend:HI (match_dup 3)) 3129 (sign_extend:HI (match_dup 1))))] 3130 { 3131 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3132 }) 3133 3134 (define_insn_and_split "*mulsqihi3.oconst" 3135 [(set (match_operand:HI 0 "register_operand" "=&r") 3136 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3137 (match_operand:HI 2 "o8_operand" "n"))) 3138 (clobber (match_scratch:QI 3 "=&a"))] 3139 "AVR_HAVE_MUL" 3140 "#" 3141 "&& reload_completed" 3142 [(set (match_dup 3) 3143 (match_dup 2)) 3144 ; *osmulqihi3 3145 (set (match_dup 0) 3146 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3)))) 3147 (sign_extend:HI (match_dup 1))))] 3148 { 3149 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 3150 }) 3151 3152 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that 3153 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper 3154 ;; at that time. Fix that. 3155 (define_insn_and_split "*ashiftqihi2.signx.1_split" 3156 [(set (match_operand:HI 0 "register_operand" "=r,*r") 3157 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r")) 3158 (const_int 1)))] 3159 "" 3160 "#" 3161 "&& reload_completed" 3162 [(parallel [(set (match_dup 0) 3163 (ashift:HI (sign_extend:HI (match_dup 1)) 3164 (const_int 1))) 3165 (clobber (reg:CC REG_CC))])]) 3166 3167 (define_insn "*ashiftqihi2.signx.1" 3168 [(set (match_operand:HI 0 "register_operand" "=r,*r") 3169 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r")) 3170 (const_int 1))) 3171 (clobber (reg:CC REG_CC)) ] 3172 "reload_completed" 3173 "@ 3174 lsl %A0\;sbc %B0,%B0 3175 mov %A0,%1\;lsl %A0\;sbc %B0,%B0" 3176 [(set_attr "length" "2,3")]) 3177 3178 (define_insn_and_split "*ashifthi3.signx.const" 3179 [(set (match_operand:HI 0 "register_operand" "=r") 3180 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d")) 3181 (match_operand:HI 2 "const_2_to_6_operand" "I"))) 3182 (clobber (match_scratch:QI 3 "=&d"))] 3183 "AVR_HAVE_MUL" 3184 "#" 3185 "&& reload_completed" 3186 [(set (match_dup 3) 3187 (match_dup 2)) 3188 ; mulqihi3 3189 (set (match_dup 0) 3190 (mult:HI (sign_extend:HI (match_dup 1)) 3191 (sign_extend:HI (match_dup 3))))] 3192 { 3193 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 3194 }) 3195 3196 (define_insn_and_split "*ashifthi3.signx.const7" 3197 [(set (match_operand:HI 0 "register_operand" "=r") 3198 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3199 (const_int 7))) 3200 (clobber (match_scratch:QI 2 "=&a"))] 3201 "AVR_HAVE_MUL" 3202 "#" 3203 "&& reload_completed" 3204 [(set (match_dup 2) 3205 (match_dup 3)) 3206 ; usmulqihi3 3207 (set (match_dup 0) 3208 (mult:HI (zero_extend:HI (match_dup 2)) 3209 (sign_extend:HI (match_dup 1))))] 3210 { 3211 operands[3] = gen_int_mode (1 << 7, QImode); 3212 }) 3213 3214 (define_insn_and_split "*ashifthi3.zerox.const" 3215 [(set (match_operand:HI 0 "register_operand" "=r") 3216 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 3217 (match_operand:HI 2 "const_2_to_7_operand" "I"))) 3218 (clobber (match_scratch:QI 3 "=&d"))] 3219 "AVR_HAVE_MUL" 3220 "#" 3221 "&& reload_completed" 3222 [(set (match_dup 3) 3223 (match_dup 2)) 3224 ; umulqihi3 3225 (set (match_dup 0) 3226 (mult:HI (zero_extend:HI (match_dup 1)) 3227 (zero_extend:HI (match_dup 3))))] 3228 { 3229 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 3230 }) 3231 3232 ;****************************************************************************** 3233 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg 3234 ;****************************************************************************** 3235 3236 (define_insn_and_split "mulsqihi3" 3237 [(set (match_operand:HI 0 "register_operand" "=&r") 3238 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3239 (match_operand:HI 2 "register_operand" "a")))] 3240 "AVR_HAVE_MUL" 3241 "#" 3242 "&& reload_completed" 3243 [(parallel [(set (match_dup 0) 3244 (mult:HI (sign_extend:HI (match_dup 1)) 3245 (match_dup 2))) 3246 (clobber (reg:CC REG_CC))])]) 3247 3248 (define_insn "*mulsqihi3" 3249 [(set (match_operand:HI 0 "register_operand" "=&r") 3250 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 3251 (match_operand:HI 2 "register_operand" "a"))) 3252 (clobber (reg:CC REG_CC))] 3253 "AVR_HAVE_MUL && reload_completed" 3254 "mulsu %1,%A2 3255 movw %0,r0 3256 mul %1,%B2 3257 add %B0,r0 3258 clr __zero_reg__" 3259 [(set_attr "length" "5")]) 3260 3261 (define_insn_and_split "muluqihi3" 3262 [(set (match_operand:HI 0 "register_operand" "=&r") 3263 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 3264 (match_operand:HI 2 "register_operand" "r")))] 3265 "AVR_HAVE_MUL" 3266 "#" 3267 "&& reload_completed" 3268 [(parallel [(set (match_dup 0) 3269 (mult:HI (zero_extend:HI (match_dup 1)) 3270 (match_dup 2))) 3271 (clobber (reg:CC REG_CC))])]) 3272 3273 (define_insn "*muluqihi3" 3274 [(set (match_operand:HI 0 "register_operand" "=&r") 3275 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 3276 (match_operand:HI 2 "register_operand" "r"))) 3277 (clobber (reg:CC REG_CC))] 3278 "AVR_HAVE_MUL && reload_completed" 3279 "mul %1,%A2 3280 movw %0,r0 3281 mul %1,%B2 3282 add %B0,r0 3283 clr __zero_reg__" 3284 [(set_attr "length" "5")]) 3285 3286 ;; one-extend operand 1 3287 3288 (define_insn_and_split "muloqihi3" 3289 [(set (match_operand:HI 0 "register_operand" "=&r") 3290 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 3291 (match_operand:HI 2 "register_operand" "r")))] 3292 "AVR_HAVE_MUL" 3293 "#" 3294 "&& reload_completed" 3295 [(parallel [(set (match_dup 0) 3296 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1)))) 3297 (match_dup 2))) 3298 (clobber (reg:CC REG_CC))])]) 3299 3300 (define_insn "*muloqihi3" 3301 [(set (match_operand:HI 0 "register_operand" "=&r") 3302 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 3303 (match_operand:HI 2 "register_operand" "r"))) 3304 (clobber (reg:CC REG_CC))] 3305 "AVR_HAVE_MUL && reload_completed" 3306 "mul %1,%A2 3307 movw %0,r0 3308 mul %1,%B2 3309 add %B0,r0 3310 sub %B0,%A2 3311 clr __zero_reg__" 3312 [(set_attr "length" "6")]) 3313 3314 ;****************************************************************************** 3315 3316 (define_expand "mulhi3" 3317 [(set (match_operand:HI 0 "register_operand" "") 3318 (mult:HI (match_operand:HI 1 "register_operand" "") 3319 (match_operand:HI 2 "register_or_s9_operand" "")))] 3320 "" 3321 { 3322 if (!AVR_HAVE_MUL) 3323 { 3324 if (!register_operand (operands[2], HImode)) 3325 operands[2] = force_reg (HImode, operands[2]); 3326 3327 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2])); 3328 DONE; 3329 } 3330 3331 // For small constants we can do better by extending them on the fly. 3332 // The constant can be loaded in one instruction and the widening 3333 // multiplication is shorter. First try the unsigned variant because it 3334 // allows constraint "d" instead of "a" for the signed version. */ 3335 3336 if (s9_operand (operands[2], HImode)) 3337 { 3338 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 3339 3340 if (u8_operand (operands[2], HImode)) 3341 { 3342 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1])); 3343 } 3344 else if (s8_operand (operands[2], HImode)) 3345 { 3346 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1])); 3347 } 3348 else 3349 { 3350 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1])); 3351 } 3352 3353 DONE; 3354 } 3355 3356 if (!register_operand (operands[2], HImode)) 3357 operands[2] = force_reg (HImode, operands[2]); 3358 }) 3359 3360 (define_insn_and_split "*mulhi3_enh_split" 3361 [(set (match_operand:HI 0 "register_operand" "=&r") 3362 (mult:HI (match_operand:HI 1 "register_operand" "r") 3363 (match_operand:HI 2 "register_operand" "r")))] 3364 "AVR_HAVE_MUL" 3365 "#" 3366 "&& reload_completed" 3367 [(parallel [(set (match_dup 0) 3368 (mult:HI (match_dup 1) 3369 (match_dup 2))) 3370 (clobber (reg:CC REG_CC))])]) 3371 3372 (define_insn "*mulhi3_enh" 3373 [(set (match_operand:HI 0 "register_operand" "=&r") 3374 (mult:HI (match_operand:HI 1 "register_operand" "r") 3375 (match_operand:HI 2 "register_operand" "r"))) 3376 (clobber (reg:CC REG_CC))] 3377 "AVR_HAVE_MUL && reload_completed" 3378 { 3379 return REGNO (operands[1]) == REGNO (operands[2]) 3380 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1" 3381 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1"; 3382 } 3383 [(set (attr "length") 3384 (symbol_ref ("7 - (REGNO (operands[1]) == REGNO (operands[2]))")))]) 3385 3386 (define_expand "mulhi3_call" 3387 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" "")) 3388 (set (reg:HI 22) (match_operand:HI 2 "register_operand" "")) 3389 (parallel [(set (reg:HI 24) 3390 (mult:HI (reg:HI 24) (reg:HI 22))) 3391 (clobber (reg:HI 22)) 3392 (clobber (reg:QI 21))]) 3393 (set (match_operand:HI 0 "register_operand" "") 3394 (reg:HI 24))] 3395 "" 3396 { 3397 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24)); 3398 }) 3399 3400 3401 (define_insn_and_split "*mulhi3_call_split" 3402 [(set (reg:HI 24) 3403 (mult:HI (reg:HI 24) (reg:HI 22))) 3404 (clobber (reg:HI 22)) 3405 (clobber (reg:QI 21))] 3406 "!AVR_HAVE_MUL" 3407 "#" 3408 "&& reload_completed" 3409 [(parallel [(set (reg:HI 24) 3410 (mult:HI (reg:HI 24) (reg:HI 22))) 3411 (clobber (reg:HI 22)) 3412 (clobber (reg:QI 21)) 3413 (clobber (reg:CC REG_CC))])]) 3414 3415 (define_insn "*mulhi3_call" 3416 [(set (reg:HI 24) 3417 (mult:HI (reg:HI 24) (reg:HI 22))) 3418 (clobber (reg:HI 22)) 3419 (clobber (reg:QI 21)) 3420 (clobber (reg:CC REG_CC))] 3421 "!AVR_HAVE_MUL && reload_completed" 3422 "%~call __mulhi3" 3423 [(set_attr "type" "xcall")]) 3424 3425 ;; To support widening multiplication with constant we postpone 3426 ;; expanding to the implicit library call until post combine and 3427 ;; prior to register allocation. Clobber all hard registers that 3428 ;; might be used by the (widening) multiply until it is split and 3429 ;; it's final register footprint is worked out. 3430 3431 (define_expand "mulsi3" 3432 [(parallel [(set (match_operand:SI 0 "register_operand" "") 3433 (mult:SI (match_operand:SI 1 "register_operand" "") 3434 (match_operand:SI 2 "nonmemory_operand" ""))) 3435 (clobber (reg:HI 26)) 3436 (clobber (reg:DI 18))])] 3437 "AVR_HAVE_MUL" 3438 { 3439 if (u16_operand (operands[2], SImode)) 3440 { 3441 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3442 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1])); 3443 DONE; 3444 } 3445 3446 if (o16_operand (operands[2], SImode)) 3447 { 3448 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3449 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1])); 3450 DONE; 3451 } 3452 3453 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0, 3454 regmask (DImode, 18) | regmask (HImode, 26))) 3455 DONE; 3456 }) 3457 3458 (define_insn_and_split "*mulsi3" 3459 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 3460 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r") 3461 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 3462 (clobber (reg:HI 26)) 3463 (clobber (reg:DI 18))] 3464 "AVR_HAVE_MUL && !reload_completed" 3465 { gcc_unreachable(); } 3466 "&& 1" 3467 [(set (reg:SI 18) 3468 (match_dup 1)) 3469 (set (reg:SI 22) 3470 (match_dup 2)) 3471 (parallel [(set (reg:SI 22) 3472 (mult:SI (reg:SI 22) 3473 (reg:SI 18))) 3474 (clobber (reg:HI 26))]) 3475 (set (match_dup 0) 3476 (reg:SI 22))] 3477 { 3478 if (u16_operand (operands[2], SImode)) 3479 { 3480 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3481 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1])); 3482 DONE; 3483 } 3484 3485 if (o16_operand (operands[2], SImode)) 3486 { 3487 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3488 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1])); 3489 DONE; 3490 } 3491 }) 3492 3493 ;; "muluqisi3" 3494 ;; "muluhisi3" 3495 (define_expand "mulu<mode>si3" 3496 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 3497 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "")) 3498 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 3499 (clobber (reg:HI 26)) 3500 (clobber (reg:DI 18))])] 3501 "AVR_HAVE_MUL" 3502 { 3503 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 3504 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0, 3505 regmask (DImode, 18) | regmask (HImode, 26))) 3506 DONE; 3507 }) 3508 3509 ;; "*muluqisi3" 3510 ;; "*muluhisi3" 3511 (define_insn_and_split "*mulu<mode>si3" 3512 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 3513 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 3514 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 3515 (clobber (reg:HI 26)) 3516 (clobber (reg:DI 18))] 3517 "AVR_HAVE_MUL && !reload_completed" 3518 { gcc_unreachable(); } 3519 "&& 1" 3520 [(set (reg:HI 26) 3521 (match_dup 1)) 3522 (set (reg:SI 18) 3523 (match_dup 2)) 3524 (set (reg:SI 22) 3525 (mult:SI (zero_extend:SI (reg:HI 26)) 3526 (reg:SI 18))) 3527 (set (match_dup 0) 3528 (reg:SI 22))] 3529 { 3530 // Do the QI -> HI extension explicitely before the multiplication. 3531 // Do the HI -> SI extension implicitely and after the multiplication. 3532 3533 if (QImode == <MODE>mode) 3534 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]); 3535 3536 if (u16_operand (operands[2], SImode)) 3537 { 3538 operands[1] = force_reg (HImode, operands[1]); 3539 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3540 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2])); 3541 DONE; 3542 } 3543 }) 3544 3545 ;; "mulsqisi3" 3546 ;; "mulshisi3" 3547 (define_expand "muls<mode>si3" 3548 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 3549 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "")) 3550 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 3551 (clobber (reg:HI 26)) 3552 (clobber (reg:DI 18))])] 3553 "AVR_HAVE_MUL" 3554 { 3555 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 3556 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0, 3557 regmask (DImode, 18) | regmask (HImode, 26))) 3558 DONE; 3559 }) 3560 3561 ;; "*mulsqisi3" 3562 ;; "*mulshisi3" 3563 (define_insn_and_split "*muls<mode>si3" 3564 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 3565 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 3566 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 3567 (clobber (reg:HI 26)) 3568 (clobber (reg:DI 18))] 3569 "AVR_HAVE_MUL && !reload_completed" 3570 { gcc_unreachable(); } 3571 "&& 1" 3572 [(set (reg:HI 26) 3573 (match_dup 1)) 3574 (set (reg:SI 18) 3575 (match_dup 2)) 3576 (set (reg:SI 22) 3577 (mult:SI (sign_extend:SI (reg:HI 26)) 3578 (reg:SI 18))) 3579 (set (match_dup 0) 3580 (reg:SI 22))] 3581 { 3582 // Do the QI -> HI extension explicitly before the multiplication. 3583 // Do the HI -> SI extension implicitly and after the multiplication. 3584 3585 if (QImode == <MODE>mode) 3586 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]); 3587 3588 if (u16_operand (operands[2], SImode) 3589 || s16_operand (operands[2], SImode)) 3590 { 3591 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 3592 3593 operands[1] = force_reg (HImode, operands[1]); 3594 3595 if (u16_operand (operands[2], SImode)) 3596 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1])); 3597 else 3598 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2)); 3599 3600 DONE; 3601 } 3602 }) 3603 3604 ;; One-extend operand 1 3605 3606 (define_expand "mulohisi3" 3607 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 3608 (mult:SI (not:SI (zero_extend:SI 3609 (not:HI (match_operand:HI 1 "pseudo_register_operand" "")))) 3610 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 3611 (clobber (reg:HI 26)) 3612 (clobber (reg:DI 18))])] 3613 "AVR_HAVE_MUL" 3614 { 3615 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 3616 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0, 3617 regmask (DImode, 18) | regmask (HImode, 26))) 3618 DONE; 3619 }) 3620 3621 (define_insn_and_split "*mulohisi3" 3622 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 3623 (mult:SI (not:SI (zero_extend:SI 3624 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r")))) 3625 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 3626 (clobber (reg:HI 26)) 3627 (clobber (reg:DI 18))] 3628 "AVR_HAVE_MUL && !reload_completed" 3629 { gcc_unreachable(); } 3630 "&& 1" 3631 [(set (reg:HI 26) 3632 (match_dup 1)) 3633 (set (reg:SI 18) 3634 (match_dup 2)) 3635 (set (reg:SI 22) 3636 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 3637 (reg:SI 18))) 3638 (set (match_dup 0) 3639 (reg:SI 22))]) 3640 3641 ;; "mulhisi3" 3642 ;; "umulhisi3" 3643 (define_expand "<extend_u>mulhisi3" 3644 [(parallel [(set (match_operand:SI 0 "register_operand" "") 3645 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" "")) 3646 (any_extend:SI (match_operand:HI 2 "register_operand" "")))) 3647 (clobber (reg:HI 26)) 3648 (clobber (reg:DI 18))])] 3649 "AVR_HAVE_MUL" 3650 { 3651 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0, 3652 regmask (DImode, 18) | regmask (HImode, 26))) 3653 DONE; 3654 }) 3655 3656 (define_expand "usmulhisi3" 3657 [(parallel [(set (match_operand:SI 0 "register_operand" "") 3658 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) 3659 (sign_extend:SI (match_operand:HI 2 "register_operand" "")))) 3660 (clobber (reg:HI 26)) 3661 (clobber (reg:DI 18))])] 3662 "AVR_HAVE_MUL" 3663 { 3664 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0, 3665 regmask (DImode, 18) | regmask (HImode, 26))) 3666 DONE; 3667 }) 3668 3669 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3" 3670 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3" 3671 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3" 3672 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3" 3673 (define_insn_and_split 3674 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3" 3675 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 3676 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 3677 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r")))) 3678 (clobber (reg:HI 26)) 3679 (clobber (reg:DI 18))] 3680 "AVR_HAVE_MUL && !reload_completed" 3681 { gcc_unreachable(); } 3682 "&& 1" 3683 [(set (reg:HI 18) 3684 (match_dup 1)) 3685 (set (reg:HI 26) 3686 (match_dup 2)) 3687 (set (reg:SI 22) 3688 (mult:SI (match_dup 3) 3689 (match_dup 4))) 3690 (set (match_dup 0) 3691 (reg:SI 22))] 3692 { 3693 rtx xop1 = operands[1]; 3694 rtx xop2 = operands[2]; 3695 3696 // Do the QI -> HI extension explicitly before the multiplication. 3697 // Do the HI -> SI extension implicitly and after the multiplication. 3698 3699 if (QImode == <QIHI:MODE>mode) 3700 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1); 3701 3702 if (QImode == <QIHI2:MODE>mode) 3703 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2); 3704 3705 if (<any_extend:CODE> == <any_extend2:CODE> 3706 || <any_extend:CODE> == ZERO_EXTEND) 3707 { 3708 operands[1] = xop1; 3709 operands[2] = xop2; 3710 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18)); 3711 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26)); 3712 } 3713 else 3714 { 3715 // <any_extend:CODE> = SIGN_EXTEND 3716 // <any_extend2:CODE> = ZERO_EXTEND 3717 3718 operands[1] = xop2; 3719 operands[2] = xop1; 3720 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18)); 3721 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26)); 3722 } 3723 }) 3724 3725 ;; "smulhi3_highpart" 3726 ;; "umulhi3_highpart" 3727 (define_expand "<extend_su>mulhi3_highpart" 3728 [(set (reg:HI 18) 3729 (match_operand:HI 1 "nonmemory_operand" "")) 3730 (set (reg:HI 26) 3731 (match_operand:HI 2 "nonmemory_operand" "")) 3732 (parallel [(set (reg:HI 24) 3733 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 3734 (any_extend:SI (reg:HI 26))) 3735 (const_int 16)))) 3736 (clobber (reg:HI 22))]) 3737 (set (match_operand:HI 0 "register_operand" "") 3738 (reg:HI 24))] 3739 "AVR_HAVE_MUL" 3740 { 3741 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18)); 3742 }) 3743 3744 (define_insn_and_split "*mulsi3_call_split" 3745 [(set (reg:SI 22) 3746 (mult:SI (reg:SI 22) 3747 (reg:SI 18))) 3748 (clobber (reg:HI 26))] 3749 "AVR_HAVE_MUL" 3750 "#" 3751 "&& reload_completed" 3752 [(parallel [(set (reg:SI 22) 3753 (mult:SI (reg:SI 22) 3754 (reg:SI 18))) 3755 (clobber (reg:HI 26)) 3756 (clobber (reg:CC REG_CC))])]) 3757 3758 (define_insn "*mulsi3_call" 3759 [(set (reg:SI 22) 3760 (mult:SI (reg:SI 22) 3761 (reg:SI 18))) 3762 (clobber (reg:HI 26)) 3763 (clobber (reg:CC REG_CC))] 3764 "AVR_HAVE_MUL && reload_completed" 3765 "%~call __mulsi3" 3766 [(set_attr "type" "xcall")]) 3767 3768 ;; "*mulhisi3_call" 3769 ;; "*umulhisi3_call" 3770 (define_insn_and_split "*<extend_u>mulhisi3_call_split" 3771 [(set (reg:SI 22) 3772 (mult:SI (any_extend:SI (reg:HI 18)) 3773 (any_extend:SI (reg:HI 26))))] 3774 "AVR_HAVE_MUL" 3775 "#" 3776 "&& reload_completed" 3777 [(parallel [(set (reg:SI 22) 3778 (mult:SI (any_extend:SI (reg:HI 18)) 3779 (any_extend:SI (reg:HI 26)))) 3780 (clobber (reg:CC REG_CC))])]) 3781 3782 (define_insn "*<extend_u>mulhisi3_call" 3783 [(set (reg:SI 22) 3784 (mult:SI (any_extend:SI (reg:HI 18)) 3785 (any_extend:SI (reg:HI 26)))) 3786 (clobber (reg:CC REG_CC))] 3787 "AVR_HAVE_MUL && reload_completed" 3788 "%~call __<extend_u>mulhisi3" 3789 [(set_attr "type" "xcall")]) 3790 3791 ;; "*umulhi3_highpart_call" 3792 ;; "*smulhi3_highpart_call" 3793 (define_insn_and_split "*<extend_su>mulhi3_highpart_call_split" 3794 [(set (reg:HI 24) 3795 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 3796 (any_extend:SI (reg:HI 26))) 3797 (const_int 16)))) 3798 (clobber (reg:HI 22))] 3799 "AVR_HAVE_MUL" 3800 "#" 3801 "&& reload_completed" 3802 [(parallel [(set (reg:HI 24) 3803 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 3804 (any_extend:SI (reg:HI 26))) 3805 (const_int 16)))) 3806 (clobber (reg:HI 22)) 3807 (clobber (reg:CC REG_CC))])]) 3808 3809 (define_insn "*<extend_su>mulhi3_highpart_call" 3810 [(set (reg:HI 24) 3811 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 3812 (any_extend:SI (reg:HI 26))) 3813 (const_int 16)))) 3814 (clobber (reg:HI 22)) 3815 (clobber (reg:CC REG_CC))] 3816 "AVR_HAVE_MUL && reload_completed" 3817 "%~call __<extend_u>mulhisi3" 3818 [(set_attr "type" "xcall")]) 3819 3820 (define_insn_and_split "*usmulhisi3_call_split" 3821 [(set (reg:SI 22) 3822 (mult:SI (zero_extend:SI (reg:HI 18)) 3823 (sign_extend:SI (reg:HI 26))))] 3824 "AVR_HAVE_MUL" 3825 "#" 3826 "&& reload_completed" 3827 [(parallel [(set (reg:SI 22) 3828 (mult:SI (zero_extend:SI (reg:HI 18)) 3829 (sign_extend:SI (reg:HI 26)))) 3830 (clobber (reg:CC REG_CC))])]) 3831 3832 (define_insn "*usmulhisi3_call" 3833 [(set (reg:SI 22) 3834 (mult:SI (zero_extend:SI (reg:HI 18)) 3835 (sign_extend:SI (reg:HI 26)))) 3836 (clobber (reg:CC REG_CC))] 3837 "AVR_HAVE_MUL && reload_completed" 3838 "%~call __usmulhisi3" 3839 [(set_attr "type" "xcall")]) 3840 3841 (define_insn_and_split "*mul<extend_su>hisi3_call_split" 3842 [(set (reg:SI 22) 3843 (mult:SI (any_extend:SI (reg:HI 26)) 3844 (reg:SI 18)))] 3845 "AVR_HAVE_MUL" 3846 "#" 3847 "&& reload_completed" 3848 [(parallel [(set (reg:SI 22) 3849 (mult:SI (any_extend:SI (reg:HI 26)) 3850 (reg:SI 18))) 3851 (clobber (reg:CC REG_CC))])]) 3852 3853 (define_insn "*mul<extend_su>hisi3_call" 3854 [(set (reg:SI 22) 3855 (mult:SI (any_extend:SI (reg:HI 26)) 3856 (reg:SI 18))) 3857 (clobber (reg:CC REG_CC))] 3858 "AVR_HAVE_MUL && reload_completed" 3859 "%~call __mul<extend_su>hisi3" 3860 [(set_attr "type" "xcall")]) 3861 3862 (define_insn_and_split "*mulohisi3_call_split" 3863 [(set (reg:SI 22) 3864 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 3865 (reg:SI 18)))] 3866 "AVR_HAVE_MUL" 3867 "#" 3868 "&& reload_completed" 3869 [(parallel [(set (reg:SI 22) 3870 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 3871 (reg:SI 18))) 3872 (clobber (reg:CC REG_CC))])]) 3873 3874 (define_insn "*mulohisi3_call" 3875 [(set (reg:SI 22) 3876 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 3877 (reg:SI 18))) 3878 (clobber (reg:CC REG_CC))] 3879 "AVR_HAVE_MUL && reload_completed" 3880 "%~call __mulohisi3" 3881 [(set_attr "type" "xcall")]) 3882 3883 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % 3884 ; divmod 3885 3886 ;; Generate lib1funcs.S calls ourselves, because: 3887 ;; - we know exactly which registers are clobbered (for QI and HI 3888 ;; modes, some of the call-used registers are preserved) 3889 ;; - we get both the quotient and the remainder at no extra cost 3890 ;; - we split the patterns only after the first CSE passes because 3891 ;; CSE has problems to operate on hard regs. 3892 ;; 3893 (define_insn_and_split "divmodqi4" 3894 [(set (match_operand:QI 0 "pseudo_register_operand") 3895 (div:QI (match_operand:QI 1 "pseudo_register_operand") 3896 (match_operand:QI 2 "pseudo_register_operand"))) 3897 (set (match_operand:QI 3 "pseudo_register_operand") 3898 (mod:QI (match_dup 1) (match_dup 2))) 3899 (clobber (reg:QI 22)) 3900 (clobber (reg:QI 23)) 3901 (clobber (reg:QI 24)) 3902 (clobber (reg:QI 25))] 3903 "" 3904 { gcc_unreachable(); } 3905 "" 3906 [(set (reg:QI 24) (match_dup 1)) 3907 (set (reg:QI 22) (match_dup 2)) 3908 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 3909 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 3910 (clobber (reg:QI 22)) 3911 (clobber (reg:QI 23))]) 3912 (set (match_dup 0) (reg:QI 24)) 3913 (set (match_dup 3) (reg:QI 25))]) 3914 3915 (define_insn_and_split "*divmodqi4_call_split" 3916 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 3917 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 3918 (clobber (reg:QI 22)) 3919 (clobber (reg:QI 23))] 3920 "" 3921 "#" 3922 "&& reload_completed" 3923 [(parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 3924 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 3925 (clobber (reg:QI 22)) 3926 (clobber (reg:QI 23)) 3927 (clobber (reg:CC REG_CC))])]) 3928 3929 (define_insn "*divmodqi4_call" 3930 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 3931 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 3932 (clobber (reg:QI 22)) 3933 (clobber (reg:QI 23)) 3934 (clobber (reg:CC REG_CC))] 3935 "reload_completed" 3936 "%~call __divmodqi4" 3937 [(set_attr "type" "xcall")]) 3938 3939 (define_insn_and_split "udivmodqi4" 3940 [(set (match_operand:QI 0 "pseudo_register_operand") 3941 (udiv:QI (match_operand:QI 1 "pseudo_register_operand") 3942 (match_operand:QI 2 "pseudo_register_operand"))) 3943 (set (match_operand:QI 3 "pseudo_register_operand") 3944 (umod:QI (match_dup 1) (match_dup 2))) 3945 (clobber (reg:QI 22)) 3946 (clobber (reg:QI 23)) 3947 (clobber (reg:QI 24)) 3948 (clobber (reg:QI 25))] 3949 "" 3950 { gcc_unreachable(); } 3951 "" 3952 [(set (reg:QI 24) (match_dup 1)) 3953 (set (reg:QI 22) (match_dup 2)) 3954 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 3955 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 3956 (clobber (reg:QI 23))]) 3957 (set (match_dup 0) (reg:QI 24)) 3958 (set (match_dup 3) (reg:QI 25))]) 3959 3960 (define_insn_and_split "*udivmodqi4_call_split" 3961 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 3962 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 3963 (clobber (reg:QI 23))] 3964 "" 3965 "#" 3966 "&& reload_completed" 3967 [(parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 3968 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 3969 (clobber (reg:QI 23)) 3970 (clobber (reg:CC REG_CC))])]) 3971 3972 (define_insn "*udivmodqi4_call" 3973 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 3974 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 3975 (clobber (reg:QI 23)) 3976 (clobber (reg:CC REG_CC))] 3977 "reload_completed" 3978 "%~call __udivmodqi4" 3979 [(set_attr "type" "xcall")]) 3980 3981 (define_insn_and_split "divmodhi4" 3982 [(set (match_operand:HI 0 "pseudo_register_operand") 3983 (div:HI (match_operand:HI 1 "pseudo_register_operand") 3984 (match_operand:HI 2 "pseudo_register_operand"))) 3985 (set (match_operand:HI 3 "pseudo_register_operand") 3986 (mod:HI (match_dup 1) (match_dup 2))) 3987 (clobber (reg:QI 21)) 3988 (clobber (reg:HI 22)) 3989 (clobber (reg:HI 24)) 3990 (clobber (reg:HI 26))] 3991 "" 3992 { gcc_unreachable(); } 3993 "" 3994 [(set (reg:HI 24) (match_dup 1)) 3995 (set (reg:HI 22) (match_dup 2)) 3996 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 3997 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 3998 (clobber (reg:HI 26)) 3999 (clobber (reg:QI 21))]) 4000 (set (match_dup 0) (reg:HI 22)) 4001 (set (match_dup 3) (reg:HI 24))]) 4002 4003 (define_insn_and_split "*divmodhi4_call_split" 4004 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 4005 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 4006 (clobber (reg:HI 26)) 4007 (clobber (reg:QI 21))] 4008 "" 4009 "#" 4010 "&& reload_completed" 4011 [(parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 4012 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 4013 (clobber (reg:HI 26)) 4014 (clobber (reg:QI 21)) 4015 (clobber (reg:CC REG_CC))])]) 4016 4017 (define_insn "*divmodhi4_call" 4018 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 4019 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 4020 (clobber (reg:HI 26)) 4021 (clobber (reg:QI 21)) 4022 (clobber (reg:CC REG_CC))] 4023 "reload_completed" 4024 "%~call __divmodhi4" 4025 [(set_attr "type" "xcall")]) 4026 4027 (define_insn_and_split "udivmodhi4" 4028 [(set (match_operand:HI 0 "pseudo_register_operand") 4029 (udiv:HI (match_operand:HI 1 "pseudo_register_operand") 4030 (match_operand:HI 2 "pseudo_register_operand"))) 4031 (set (match_operand:HI 3 "pseudo_register_operand") 4032 (umod:HI (match_dup 1) (match_dup 2))) 4033 (clobber (reg:QI 21)) 4034 (clobber (reg:HI 22)) 4035 (clobber (reg:HI 24)) 4036 (clobber (reg:HI 26))] 4037 "" 4038 { gcc_unreachable(); } 4039 "" 4040 [(set (reg:HI 24) (match_dup 1)) 4041 (set (reg:HI 22) (match_dup 2)) 4042 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 4043 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 4044 (clobber (reg:HI 26)) 4045 (clobber (reg:QI 21))]) 4046 (set (match_dup 0) (reg:HI 22)) 4047 (set (match_dup 3) (reg:HI 24))]) 4048 4049 (define_insn_and_split "*udivmodhi4_call_split" 4050 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 4051 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 4052 (clobber (reg:HI 26)) 4053 (clobber (reg:QI 21))] 4054 "" 4055 "#" 4056 "&& reload_completed" 4057 [(parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 4058 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 4059 (clobber (reg:HI 26)) 4060 (clobber (reg:QI 21)) 4061 (clobber (reg:CC REG_CC))])]) 4062 4063 (define_insn "*udivmodhi4_call" 4064 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 4065 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 4066 (clobber (reg:HI 26)) 4067 (clobber (reg:QI 21)) 4068 (clobber (reg:CC REG_CC)) 4069 ] 4070 "reload_completed" 4071 "%~call __udivmodhi4" 4072 [(set_attr "type" "xcall")]) 4073 4074 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4075 ;; 24-bit multiply 4076 4077 ;; To support widening multiplication with constant we postpone 4078 ;; expanding to the implicit library call until post combine and 4079 ;; prior to register allocation. Clobber all hard registers that 4080 ;; might be used by the (widening) multiply until it is split and 4081 ;; it's final register footprint is worked out. 4082 4083 (define_expand "mulpsi3" 4084 [(parallel [(set (match_operand:PSI 0 "register_operand" "") 4085 (mult:PSI (match_operand:PSI 1 "register_operand" "") 4086 (match_operand:PSI 2 "nonmemory_operand" ""))) 4087 (clobber (reg:HI 26)) 4088 (clobber (reg:DI 18))])] 4089 "AVR_HAVE_MUL" 4090 { 4091 if (s8_operand (operands[2], PSImode)) 4092 { 4093 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 4094 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1])); 4095 DONE; 4096 } 4097 4098 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0, 4099 regmask (DImode, 18) | regmask (HImode, 26))) 4100 DONE; 4101 }) 4102 4103 (define_insn_and_split "*umulqihipsi3_split" 4104 [(set (match_operand:PSI 0 "register_operand" "=&r") 4105 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 4106 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 4107 "AVR_HAVE_MUL" 4108 "#" 4109 "&& reload_completed" 4110 [(parallel [(set (match_dup 0) 4111 (mult:PSI (zero_extend:PSI (match_dup 1)) 4112 (zero_extend:PSI (match_dup 2)))) 4113 (clobber (reg:CC REG_CC))])]) 4114 4115 (define_insn "*umulqihipsi3" 4116 [(set (match_operand:PSI 0 "register_operand" "=&r") 4117 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 4118 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")))) 4119 (clobber (reg:CC REG_CC))] 4120 "AVR_HAVE_MUL && reload_completed" 4121 "mul %1,%A2 4122 movw %A0,r0 4123 mul %1,%B2 4124 clr %C0 4125 add %B0,r0 4126 adc %C0,r1 4127 clr __zero_reg__" 4128 [(set_attr "length" "7")]) 4129 4130 (define_insn_and_split "*umulhiqipsi3_split" 4131 [(set (match_operand:PSI 0 "register_operand" "=&r") 4132 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")) 4133 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))] 4134 "AVR_HAVE_MUL" 4135 "#" 4136 "&& reload_completed" 4137 [(parallel [(set (match_dup 0) 4138 (mult:PSI (zero_extend:PSI (match_dup 2)) 4139 (zero_extend:PSI (match_dup 1)))) 4140 (clobber (reg:CC REG_CC))])]) 4141 4142 (define_insn "*umulhiqipsi3" 4143 [(set (match_operand:PSI 0 "register_operand" "=&r") 4144 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")) 4145 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")))) 4146 (clobber (reg:CC REG_CC))] 4147 "AVR_HAVE_MUL && reload_completed" 4148 "mul %1,%A2 4149 movw %A0,r0 4150 mul %1,%B2 4151 add %B0,r0 4152 mov %C0,r1 4153 clr __zero_reg__ 4154 adc %C0,__zero_reg__" 4155 [(set_attr "length" "7")]) 4156 4157 (define_expand "mulsqipsi3" 4158 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "") 4159 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "")) 4160 (match_operand:PSI 2 "pseudo_register_or_const_int_operand"""))) 4161 (clobber (reg:HI 26)) 4162 (clobber (reg:DI 18))])] 4163 "AVR_HAVE_MUL" 4164 { 4165 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 4166 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0, 4167 regmask (DImode, 18) | regmask (HImode, 26))) 4168 DONE; 4169 }) 4170 4171 (define_insn_and_split "*mulsqipsi3" 4172 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r") 4173 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r")) 4174 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn"))) 4175 (clobber (reg:HI 26)) 4176 (clobber (reg:DI 18))] 4177 "AVR_HAVE_MUL && !reload_completed" 4178 { gcc_unreachable(); } 4179 "&& 1" 4180 [(set (reg:QI 25) 4181 (match_dup 1)) 4182 (set (reg:PSI 22) 4183 (match_dup 2)) 4184 (set (reg:PSI 18) 4185 (mult:PSI (sign_extend:PSI (reg:QI 25)) 4186 (reg:PSI 22))) 4187 (set (match_dup 0) 4188 (reg:PSI 18))]) 4189 4190 (define_insn_and_split "*mulpsi3" 4191 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r") 4192 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r") 4193 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn"))) 4194 (clobber (reg:HI 26)) 4195 (clobber (reg:DI 18))] 4196 "AVR_HAVE_MUL && !reload_completed" 4197 { gcc_unreachable(); } 4198 "&& 1" 4199 [(set (reg:PSI 18) 4200 (match_dup 1)) 4201 (set (reg:PSI 22) 4202 (match_dup 2)) 4203 (parallel [(set (reg:PSI 22) 4204 (mult:PSI (reg:PSI 22) 4205 (reg:PSI 18))) 4206 (clobber (reg:QI 21)) 4207 (clobber (reg:QI 25)) 4208 (clobber (reg:HI 26))]) 4209 (set (match_dup 0) 4210 (reg:PSI 22))] 4211 { 4212 if (s8_operand (operands[2], PSImode)) 4213 { 4214 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 4215 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1])); 4216 DONE; 4217 } 4218 }) 4219 4220 (define_insn_and_split "*mulsqipsi3.libgcc_split" 4221 [(set (reg:PSI 18) 4222 (mult:PSI (sign_extend:PSI (reg:QI 25)) 4223 (reg:PSI 22)))] 4224 "AVR_HAVE_MUL" 4225 "#" 4226 "&& reload_completed" 4227 [(parallel [(set (reg:PSI 18) 4228 (mult:PSI (sign_extend:PSI (reg:QI 25)) 4229 (reg:PSI 22))) 4230 (clobber (reg:CC REG_CC))])]) 4231 4232 (define_insn "*mulsqipsi3.libgcc" 4233 [(set (reg:PSI 18) 4234 (mult:PSI (sign_extend:PSI (reg:QI 25)) 4235 (reg:PSI 22))) 4236 (clobber (reg:CC REG_CC))] 4237 "AVR_HAVE_MUL && reload_completed" 4238 "%~call __mulsqipsi3" 4239 [(set_attr "type" "xcall")]) 4240 4241 (define_insn_and_split "*mulpsi3.libgcc_split" 4242 [(set (reg:PSI 22) 4243 (mult:PSI (reg:PSI 22) 4244 (reg:PSI 18))) 4245 (clobber (reg:QI 21)) 4246 (clobber (reg:QI 25)) 4247 (clobber (reg:HI 26))] 4248 "AVR_HAVE_MUL" 4249 "#" 4250 "&& reload_completed" 4251 [(parallel [(set (reg:PSI 22) 4252 (mult:PSI (reg:PSI 22) 4253 (reg:PSI 18))) 4254 (clobber (reg:QI 21)) 4255 (clobber (reg:QI 25)) 4256 (clobber (reg:HI 26)) 4257 (clobber (reg:CC REG_CC))])]) 4258 4259 (define_insn "*mulpsi3.libgcc" 4260 [(set (reg:PSI 22) 4261 (mult:PSI (reg:PSI 22) 4262 (reg:PSI 18))) 4263 (clobber (reg:QI 21)) 4264 (clobber (reg:QI 25)) 4265 (clobber (reg:HI 26)) 4266 (clobber (reg:CC REG_CC))] 4267 "AVR_HAVE_MUL && reload_completed" 4268 "%~call __mulpsi3" 4269 [(set_attr "type" "xcall")]) 4270 4271 4272 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4273 ;; 24-bit signed/unsigned division and modulo. 4274 ;; Notice that the libgcc implementation return the quotient in R22 4275 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4 4276 ;; implementation works the other way round. 4277 4278 (define_insn_and_split "divmodpsi4" 4279 [(set (match_operand:PSI 0 "pseudo_register_operand") 4280 (div:PSI (match_operand:PSI 1 "pseudo_register_operand") 4281 (match_operand:PSI 2 "pseudo_register_operand"))) 4282 (set (match_operand:PSI 3 "pseudo_register_operand") 4283 (mod:PSI (match_dup 1) 4284 (match_dup 2))) 4285 (clobber (reg:DI 18)) 4286 (clobber (reg:QI 26))] 4287 "" 4288 { gcc_unreachable(); } 4289 "" 4290 [(set (reg:PSI 22) (match_dup 1)) 4291 (set (reg:PSI 18) (match_dup 2)) 4292 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 4293 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 4294 (clobber (reg:QI 21)) 4295 (clobber (reg:QI 25)) 4296 (clobber (reg:QI 26))]) 4297 (set (match_dup 0) (reg:PSI 22)) 4298 (set (match_dup 3) (reg:PSI 18))]) 4299 4300 (define_insn_and_split "*divmodpsi4_call_split" 4301 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 4302 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 4303 (clobber (reg:QI 21)) 4304 (clobber (reg:QI 25)) 4305 (clobber (reg:QI 26))] 4306 "" 4307 "#" 4308 "&& reload_completed" 4309 [(parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 4310 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 4311 (clobber (reg:QI 21)) 4312 (clobber (reg:QI 25)) 4313 (clobber (reg:QI 26)) 4314 (clobber (reg:CC REG_CC))])]) 4315 4316 (define_insn "*divmodpsi4_call" 4317 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 4318 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 4319 (clobber (reg:QI 21)) 4320 (clobber (reg:QI 25)) 4321 (clobber (reg:QI 26)) 4322 (clobber (reg:CC REG_CC))] 4323 "reload_completed" 4324 "%~call __divmodpsi4" 4325 [(set_attr "type" "xcall")]) 4326 4327 (define_insn_and_split "udivmodpsi4" 4328 [(set (match_operand:PSI 0 "pseudo_register_operand") 4329 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand") 4330 (match_operand:PSI 2 "pseudo_register_operand"))) 4331 (set (match_operand:PSI 3 "pseudo_register_operand") 4332 (umod:PSI (match_dup 1) 4333 (match_dup 2))) 4334 (clobber (reg:DI 18)) 4335 (clobber (reg:QI 26))] 4336 "" 4337 { gcc_unreachable(); } 4338 "" 4339 [(set (reg:PSI 22) (match_dup 1)) 4340 (set (reg:PSI 18) (match_dup 2)) 4341 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 4342 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 4343 (clobber (reg:QI 21)) 4344 (clobber (reg:QI 25)) 4345 (clobber (reg:QI 26))]) 4346 (set (match_dup 0) (reg:PSI 22)) 4347 (set (match_dup 3) (reg:PSI 18))]) 4348 4349 (define_insn_and_split "*udivmodpsi4_call_split" 4350 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 4351 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 4352 (clobber (reg:QI 21)) 4353 (clobber (reg:QI 25)) 4354 (clobber (reg:QI 26))] 4355 "" 4356 "#" 4357 "&& reload_completed" 4358 [(parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 4359 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 4360 (clobber (reg:QI 21)) 4361 (clobber (reg:QI 25)) 4362 (clobber (reg:QI 26)) 4363 (clobber (reg:CC REG_CC))])]) 4364 4365 (define_insn "*udivmodpsi4_call" 4366 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 4367 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 4368 (clobber (reg:QI 21)) 4369 (clobber (reg:QI 25)) 4370 (clobber (reg:QI 26)) 4371 (clobber (reg:CC REG_CC))] 4372 "reload_completed" 4373 "%~call __udivmodpsi4" 4374 [(set_attr "type" "xcall")]) 4375 4376 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4377 4378 (define_insn_and_split "divmodsi4" 4379 [(set (match_operand:SI 0 "pseudo_register_operand") 4380 (div:SI (match_operand:SI 1 "pseudo_register_operand") 4381 (match_operand:SI 2 "pseudo_register_operand"))) 4382 (set (match_operand:SI 3 "pseudo_register_operand") 4383 (mod:SI (match_dup 1) 4384 (match_dup 2))) 4385 (clobber (reg:SI 18)) 4386 (clobber (reg:SI 22)) 4387 (clobber (reg:HI 26)) 4388 (clobber (reg:HI 30))] 4389 "" 4390 { gcc_unreachable(); } 4391 "" 4392 [(set (reg:SI 22) (match_dup 1)) 4393 (set (reg:SI 18) (match_dup 2)) 4394 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 4395 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 4396 (clobber (reg:HI 26)) 4397 (clobber (reg:HI 30))]) 4398 (set (match_dup 0) (reg:SI 18)) 4399 (set (match_dup 3) (reg:SI 22))]) 4400 4401 (define_insn_and_split "*divmodsi4_call_split" 4402 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 4403 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 4404 (clobber (reg:HI 26)) 4405 (clobber (reg:HI 30))] 4406 "" 4407 "#" 4408 "&& reload_completed" 4409 [(parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 4410 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 4411 (clobber (reg:HI 26)) 4412 (clobber (reg:HI 30)) 4413 (clobber (reg:CC REG_CC))])]) 4414 4415 (define_insn "*divmodsi4_call" 4416 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 4417 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 4418 (clobber (reg:HI 26)) 4419 (clobber (reg:HI 30)) 4420 (clobber (reg:CC REG_CC))] 4421 "reload_completed" 4422 "%~call __divmodsi4" 4423 [(set_attr "type" "xcall")]) 4424 4425 (define_insn_and_split "udivmodsi4" 4426 [(set (match_operand:SI 0 "pseudo_register_operand") 4427 (udiv:SI (match_operand:SI 1 "pseudo_register_operand") 4428 (match_operand:SI 2 "pseudo_register_operand"))) 4429 (set (match_operand:SI 3 "pseudo_register_operand") 4430 (umod:SI (match_dup 1) 4431 (match_dup 2))) 4432 (clobber (reg:SI 18)) 4433 (clobber (reg:SI 22)) 4434 (clobber (reg:HI 26)) 4435 (clobber (reg:HI 30))] 4436 "" 4437 { gcc_unreachable(); } 4438 "" 4439 [(set (reg:SI 22) (match_dup 1)) 4440 (set (reg:SI 18) (match_dup 2)) 4441 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 4442 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 4443 (clobber (reg:HI 26)) 4444 (clobber (reg:HI 30))]) 4445 (set (match_dup 0) (reg:SI 18)) 4446 (set (match_dup 3) (reg:SI 22))]) 4447 4448 (define_insn_and_split "*udivmodsi4_call_split" 4449 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 4450 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 4451 (clobber (reg:HI 26)) 4452 (clobber (reg:HI 30))] 4453 "" 4454 "#" 4455 "&& reload_completed" 4456 [(parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 4457 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 4458 (clobber (reg:HI 26)) 4459 (clobber (reg:HI 30)) 4460 (clobber (reg:CC REG_CC))])]) 4461 4462 (define_insn "*udivmodsi4_call" 4463 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 4464 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 4465 (clobber (reg:HI 26)) 4466 (clobber (reg:HI 30)) 4467 (clobber (reg:CC REG_CC))] 4468 "reload_completed" 4469 "%~call __udivmodsi4" 4470 [(set_attr "type" "xcall")]) 4471 4472 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 4473 ; and 4474 4475 (define_insn_and_split "andqi3" 4476 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 4477 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0") 4478 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))] 4479 "" 4480 "#" 4481 "&& reload_completed" 4482 [(parallel [(set (match_dup 0) 4483 (and:QI (match_dup 1) 4484 (match_dup 2))) 4485 (clobber (reg:CC REG_CC))])]) 4486 4487 (define_insn "*andqi3" 4488 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 4489 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0") 4490 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1"))) 4491 (clobber (reg:CC REG_CC))] 4492 "reload_completed" 4493 "@ 4494 and %0,%2 4495 andi %0,lo8(%2) 4496 * return avr_out_bitop (insn, operands, NULL);" 4497 [(set_attr "length" "1,1,2")]) 4498 4499 (define_insn_and_split "andhi3" 4500 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r ,r") 4501 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,r ,0") 4502 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,Cb2,n"))) 4503 (clobber (match_scratch:QI 3 "=X,X,X,X ,X ,&d"))] 4504 "" 4505 "#" 4506 "&& reload_completed" 4507 [(parallel [(set (match_dup 0) 4508 (and:HI (match_dup 1) 4509 (match_dup 2))) 4510 (clobber (match_dup 3)) 4511 (clobber (reg:CC REG_CC))])]) 4512 4513 (define_insn "*andhi3" 4514 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r ,r") 4515 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,r ,0") 4516 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,Cb2,n"))) 4517 (clobber (match_scratch:QI 3 "=X,X,X,X ,X ,&d")) 4518 (clobber (reg:CC REG_CC))] 4519 "reload_completed" 4520 { 4521 if (which_alternative == 0) 4522 return "and %A0,%A2\;and %B0,%B2"; 4523 else if (which_alternative == 1) 4524 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)"; 4525 else if (which_alternative == 4) 4526 return avr_out_insv (insn, operands, NULL); 4527 4528 return avr_out_bitop (insn, operands, NULL); 4529 } 4530 [(set_attr "length" "2,2,2,4,4,4") 4531 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,insv,out_bitop")]) 4532 4533 (define_insn_and_split "andpsi3" 4534 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r ,r") 4535 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,r ,0") 4536 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,Cb3,n"))) 4537 (clobber (match_scratch:QI 3 "=X,X,X ,X ,&d"))] 4538 "" 4539 "#" 4540 "&& reload_completed" 4541 [(parallel [(set (match_dup 0) 4542 (and:PSI (match_dup 1) 4543 (match_dup 2))) 4544 (clobber (match_dup 3)) 4545 (clobber (reg:CC REG_CC))])]) 4546 4547 (define_insn "*andpsi3" 4548 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r ,r") 4549 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,r ,0") 4550 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,Cb3,n"))) 4551 (clobber (match_scratch:QI 3 "=X,X,X ,X ,&d")) 4552 (clobber (reg:CC REG_CC))] 4553 "reload_completed" 4554 { 4555 if (which_alternative == 0) 4556 return "and %A0,%A2" CR_TAB 4557 "and %B0,%B2" CR_TAB 4558 "and %C0,%C2"; 4559 4560 if (which_alternative == 3) 4561 return avr_out_insv (insn, operands, NULL); 4562 4563 return avr_out_bitop (insn, operands, NULL); 4564 } 4565 [(set_attr "length" "3,3,6,5,6") 4566 (set_attr "adjust_len" "*,out_bitop,out_bitop,insv,out_bitop")]) 4567 4568 (define_insn_and_split "andsi3" 4569 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r ,r") 4570 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,r ,0") 4571 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,Cb4,n"))) 4572 (clobber (match_scratch:QI 3 "=X,X,X ,X ,&d"))] 4573 "" 4574 "#" 4575 "&& reload_completed" 4576 [(parallel [(set (match_dup 0) 4577 (and:SI (match_dup 1) 4578 (match_dup 2))) 4579 (clobber (match_dup 3)) 4580 (clobber (reg:CC REG_CC))])]) 4581 4582 (define_insn "*andsi3" 4583 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r ,r") 4584 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,r ,0") 4585 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,Cb4,n"))) 4586 (clobber (match_scratch:QI 3 "=X,X,X ,X ,&d")) 4587 (clobber (reg:CC REG_CC))] 4588 "reload_completed" 4589 { 4590 if (which_alternative == 0) 4591 return "and %0,%2" CR_TAB 4592 "and %B0,%B2" CR_TAB 4593 "and %C0,%C2" CR_TAB 4594 "and %D0,%D2"; 4595 4596 if (which_alternative == 3) 4597 return avr_out_insv (insn, operands, NULL); 4598 4599 return avr_out_bitop (insn, operands, NULL); 4600 } 4601 [(set_attr "length" "4,4,8,6,8") 4602 (set_attr "adjust_len" "*,out_bitop,out_bitop,insv,out_bitop")]) 4603 4604 (define_peephole2 ; andi 4605 [(parallel [(set (match_operand:QI 0 "d_register_operand" "") 4606 (and:QI (match_dup 0) 4607 (match_operand:QI 1 "const_int_operand" ""))) 4608 (clobber (reg:CC REG_CC))]) 4609 (parallel [(set (match_dup 0) 4610 (and:QI (match_dup 0) 4611 (match_operand:QI 2 "const_int_operand" ""))) 4612 (clobber (reg:CC REG_CC))])] 4613 "" 4614 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) 4615 (clobber (reg:CC REG_CC))])] 4616 { 4617 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2])); 4618 }) 4619 4620 ;;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 4621 ;; ior 4622 4623 (define_insn_and_split "iorqi3" 4624 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 4625 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0") 4626 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))] 4627 "" 4628 "#" 4629 "&& reload_completed" 4630 [(parallel [(set (match_dup 0) 4631 (ior:QI (match_dup 1) 4632 (match_dup 2))) 4633 (clobber (reg:CC REG_CC))])]) 4634 4635 (define_insn "*iorqi3" 4636 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 4637 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0") 4638 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1"))) 4639 (clobber (reg:CC REG_CC))] 4640 "reload_completed" 4641 "@ 4642 or %0,%2 4643 ori %0,lo8(%2) 4644 * return avr_out_bitop (insn, operands, NULL);" 4645 [(set_attr "length" "1,1,2")]) 4646 4647 (define_insn_and_split "iorhi3" 4648 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") 4649 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0") 4650 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n"))) 4651 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))] 4652 "" 4653 "#" 4654 "&& reload_completed" 4655 [(parallel [(set (match_dup 0) 4656 (ior:HI (match_dup 1) 4657 (match_dup 2))) 4658 (clobber (match_dup 3)) 4659 (clobber (reg:CC REG_CC))])]) 4660 4661 (define_insn "*iorhi3" 4662 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") 4663 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0") 4664 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n"))) 4665 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d")) 4666 (clobber (reg:CC REG_CC))] 4667 "reload_completed" 4668 { 4669 if (which_alternative == 0) 4670 return "or %A0,%A2\;or %B0,%B2"; 4671 else if (which_alternative == 1) 4672 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)"; 4673 4674 return avr_out_bitop (insn, operands, NULL); 4675 } 4676 [(set_attr "length" "2,2,2,4,4") 4677 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")]) 4678 4679 (define_insn_and_split "iorpsi3" 4680 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r") 4681 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0") 4682 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n"))) 4683 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 4684 "" 4685 "#" 4686 "&& reload_completed" 4687 [(parallel [(set (match_dup 0) 4688 (ior:PSI (match_dup 1) 4689 (match_dup 2))) 4690 (clobber (match_dup 3)) 4691 (clobber (reg:CC REG_CC))])]) 4692 4693 (define_insn "*iorpsi3" 4694 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r") 4695 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0") 4696 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n"))) 4697 (clobber (match_scratch:QI 3 "=X,X,X ,&d")) 4698 (clobber (reg:CC REG_CC))] 4699 "reload_completed" 4700 { 4701 if (which_alternative == 0) 4702 return "or %A0,%A2" CR_TAB 4703 "or %B0,%B2" CR_TAB 4704 "or %C0,%C2"; 4705 4706 return avr_out_bitop (insn, operands, NULL); 4707 } 4708 [(set_attr "length" "3,3,6,6") 4709 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")]) 4710 4711 (define_insn_and_split "iorsi3" 4712 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r") 4713 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0") 4714 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n"))) 4715 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 4716 "" 4717 "#" 4718 "&& reload_completed" 4719 [(parallel [(set (match_dup 0) 4720 (ior:SI (match_dup 1) 4721 (match_dup 2))) 4722 (clobber (match_dup 3)) 4723 (clobber (reg:CC REG_CC))])]) 4724 4725 (define_insn "*iorsi3" 4726 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r") 4727 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0") 4728 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n"))) 4729 (clobber (match_scratch:QI 3 "=X,X,X ,&d")) 4730 (clobber (reg:CC REG_CC))] 4731 "reload_completed" 4732 { 4733 if (which_alternative == 0) 4734 return "or %0,%2" CR_TAB 4735 "or %B0,%B2" CR_TAB 4736 "or %C0,%C2" CR_TAB 4737 "or %D0,%D2"; 4738 4739 return avr_out_bitop (insn, operands, NULL); 4740 } 4741 [(set_attr "length" "4,4,8,8") 4742 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")]) 4743 4744 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4745 ;; xor 4746 4747 (define_insn_and_split "xorqi3" 4748 [(set (match_operand:QI 0 "register_operand" "=r") 4749 (xor:QI (match_operand:QI 1 "register_operand" "%0") 4750 (match_operand:QI 2 "register_operand" "r")))] 4751 "" 4752 "#" 4753 "&& reload_completed" 4754 [(parallel [(set (match_dup 0) 4755 (xor:QI (match_dup 1) 4756 (match_dup 2))) 4757 (clobber (reg:CC REG_CC))])]) 4758 4759 (define_insn "*xorqi3" 4760 [(set (match_operand:QI 0 "register_operand" "=r") 4761 (xor:QI (match_operand:QI 1 "register_operand" "%0") 4762 (match_operand:QI 2 "register_operand" "r"))) 4763 (clobber (reg:CC REG_CC))] 4764 "reload_completed" 4765 "eor %0,%2" 4766 [(set_attr "length" "1")]) 4767 4768 (define_insn_and_split "xorhi3" 4769 [(set (match_operand:HI 0 "register_operand" "=??r,r ,d ,r") 4770 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0 ,0") 4771 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,CX2,n"))) 4772 (clobber (match_scratch:QI 3 "=X,X ,X ,&d"))] 4773 "" 4774 "#" 4775 "&& reload_completed" 4776 [(parallel [(set (match_dup 0) 4777 (xor:HI (match_dup 1) 4778 (match_dup 2))) 4779 (clobber (match_dup 3)) 4780 (clobber (reg:CC REG_CC))])]) 4781 4782 (define_insn "*xorhi3" 4783 [(set (match_operand:HI 0 "register_operand" "=??r,r ,d ,r") 4784 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0 ,0") 4785 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,CX2,n"))) 4786 (clobber (match_scratch:QI 3 "=X,X ,X ,&d")) 4787 (clobber (reg:CC REG_CC))] 4788 "reload_completed" 4789 { 4790 if (which_alternative == 0) 4791 return "eor %A0,%A2\;eor %B0,%B2"; 4792 4793 return avr_out_bitop (insn, operands, NULL); 4794 } 4795 [(set_attr "length" "2,2,4,4") 4796 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")]) 4797 4798 (define_insn_and_split "xorpsi3" 4799 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,d ,r") 4800 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0 ,0") 4801 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,CX3,n"))) 4802 (clobber (match_scratch:QI 3 "=X,X ,X ,&d"))] 4803 "" 4804 "#" 4805 "&& reload_completed" 4806 [(parallel [(set (match_dup 0) 4807 (xor:PSI (match_dup 1) 4808 (match_dup 2))) 4809 (clobber (match_dup 3)) 4810 (clobber (reg:CC REG_CC))])]) 4811 4812 (define_insn "*xorpsi3" 4813 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,d ,r") 4814 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0 ,0") 4815 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,CX3,n"))) 4816 (clobber (match_scratch:QI 3 "=X,X ,X ,&d")) 4817 (clobber (reg:CC REG_CC))] 4818 "reload_completed" 4819 { 4820 if (which_alternative == 0) 4821 return "eor %A0,%A2" CR_TAB 4822 "eor %B0,%B2" CR_TAB 4823 "eor %C0,%C2"; 4824 4825 return avr_out_bitop (insn, operands, NULL); 4826 } 4827 [(set_attr "length" "3,6,6,6") 4828 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")]) 4829 4830 (define_insn_and_split "xorsi3" 4831 [(set (match_operand:SI 0 "register_operand" "=??r,r ,d ,r") 4832 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0") 4833 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,CX4,n"))) 4834 (clobber (match_scratch:QI 3 "=X,X ,X ,&d"))] 4835 "" 4836 "#" 4837 "&& reload_completed" 4838 [(parallel [(set (match_dup 0) 4839 (xor:SI (match_dup 1) 4840 (match_dup 2))) 4841 (clobber (match_dup 3)) 4842 (clobber (reg:CC REG_CC))])]) 4843 4844 (define_insn "*xorsi3" 4845 [(set (match_operand:SI 0 "register_operand" "=??r,r ,d ,r") 4846 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0") 4847 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,CX4,n"))) 4848 (clobber (match_scratch:QI 3 "=X,X ,X ,&d")) 4849 (clobber (reg:CC REG_CC))] 4850 "reload_completed" 4851 { 4852 if (which_alternative == 0) 4853 return "eor %0,%2" CR_TAB 4854 "eor %B0,%B2" CR_TAB 4855 "eor %C0,%C2" CR_TAB 4856 "eor %D0,%D2"; 4857 4858 return avr_out_bitop (insn, operands, NULL); 4859 } 4860 [(set_attr "length" "4,8,8,8") 4861 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")]) 4862 4863 4864 (define_split 4865 [(set (match_operand:SPLIT34 0 "register_operand") 4866 (match_operand:SPLIT34 1 "register_operand"))] 4867 "optimize 4868 && reload_completed" 4869 [(set (match_dup 2) (match_dup 3)) 4870 (set (match_dup 4) (match_dup 5))] 4871 { 4872 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode; 4873 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]); 4874 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0); 4875 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0); 4876 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2); 4877 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2); 4878 4879 operands[2] = lo_first ? dst_lo : dst_hi; 4880 operands[3] = lo_first ? src_lo : src_hi; 4881 operands[4] = lo_first ? dst_hi : dst_lo; 4882 operands[5] = lo_first ? src_hi : src_lo; 4883 }) 4884 4885 (define_split 4886 [(set (match_operand:HI 0 "register_operand") 4887 (match_operand:HI 1 "reg_or_0_operand"))] 4888 "optimize 4889 && reload_completed 4890 && GENERAL_REG_P (operands[0]) 4891 && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1])) 4892 && (!AVR_HAVE_MOVW 4893 || const0_rtx == operands[1])" 4894 [(set (match_dup 2) (match_dup 3)) 4895 (set (match_dup 4) (match_dup 5))] 4896 { 4897 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 4898 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1); 4899 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 4900 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 4901 }) 4902 4903 ;; Split andhi3, andpsi3, andsi3. 4904 ;; Split iorhi3, iorpsi3, iorsi3. 4905 ;; Split xorhi3, xorpsi3, xorsi3. 4906 (define_split 4907 [(parallel [(set (match_operand:HISI 0 "register_operand") 4908 (bitop:HISI (match_dup 0) 4909 (match_operand:HISI 1 "register_operand"))) 4910 (clobber (scratch:QI)) 4911 (clobber (reg:CC REG_CC))])] 4912 "optimize 4913 && reload_completed" 4914 [(const_int 1)] 4915 { 4916 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++) 4917 { 4918 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); 4919 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i); 4920 emit_insn (gen_<code>qi3 (dst, dst, src)); 4921 } 4922 DONE; 4923 }) 4924 4925 ;; If $0 = $0 <op> const requires a QI scratch, and d-reg $1 dies after 4926 ;; the first insn, then we can replace 4927 ;; $0 = $1 4928 ;; $0 = $0 <op> const 4929 ;; by 4930 ;; $1 = $1 <op> const 4931 ;; $0 = $1 4932 ;; This transforms constraint alternative "r,0,n,&d" of the first operation 4933 ;; to alternative "d,0,n,X". 4934 ;; "*addhi3_clobber" "*addpsi3" "*addsi3" 4935 ;; "*addhq3" "*adduhq3" "*addha3" "*adduha3" 4936 ;; "*addsq3" "*addusq3" "*addsa3" "*addusa3" 4937 ;; "*iorhi3" "*iorpsi3" "*iorsi3" 4938 ;; "*andhi3" "*andpsi3" "*andsi3" 4939 (define_peephole2 4940 [(parallel [(set (match_operand:ORDERED234 0 "register_operand") 4941 (match_operand:ORDERED234 1 "d_register_operand")) 4942 (clobber (reg:CC REG_CC))]) 4943 (parallel [(set (match_dup 0) 4944 (piaop:ORDERED234 (match_dup 0) 4945 (match_operand:ORDERED234 2 "const_operand"))) 4946 ; A d-reg as scratch tells that this insn is expensive, and 4947 ; that $0 is not a d-register: l-reg or something like SI:14 etc. 4948 (clobber (match_operand:QI 3 "d_register_operand")) 4949 (clobber (reg:CC REG_CC))])] 4950 "peep2_reg_dead_p (1, operands[1])" 4951 [(parallel [(set (match_dup 1) 4952 (piaop:ORDERED234 (match_dup 1) 4953 (match_dup 2))) 4954 (clobber (scratch:QI)) 4955 (clobber (reg:CC REG_CC))]) 4956 ; Unfortunately, the following insn misses a REG_DEAD note for $1, 4957 ; so this peep2 works only once. 4958 (parallel [(set (match_dup 0) 4959 (match_dup 1)) 4960 (clobber (reg:CC REG_CC))])]) 4961 4962 4963 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap 4964 ;; swap 4965 4966 (define_expand "rotlqi3" 4967 [(set (match_operand:QI 0 "register_operand" "") 4968 (rotate:QI (match_operand:QI 1 "register_operand" "") 4969 (match_operand:QI 2 "const_0_to_7_operand" "")))] 4970 "" 4971 { 4972 if (!CONST_INT_P (operands[2])) 4973 FAIL; 4974 4975 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode); 4976 }) 4977 4978 ;; Expander used by __builtin_avr_swap 4979 (define_expand "rotlqi3_4" 4980 [(set (match_operand:QI 0 "register_operand" "") 4981 (rotate:QI (match_operand:QI 1 "register_operand" "") 4982 (const_int 4)))]) 4983 4984 (define_insn_and_split "*rotlqi3_split" 4985 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r") 4986 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0") 4987 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))] 4988 "" 4989 "#" 4990 "&& reload_completed" 4991 [(parallel [(set (match_dup 0) 4992 (rotate:QI (match_dup 1) 4993 (match_dup 2))) 4994 (clobber (reg:CC REG_CC))])]) 4995 4996 (define_insn "*rotlqi3" 4997 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r") 4998 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0") 4999 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L"))) 5000 (clobber (reg:CC REG_CC))] 5001 "reload_completed" 5002 "@ 5003 lsl %0\;adc %0,__zero_reg__ 5004 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__ 5005 swap %0\;bst %0,0\;ror %0\;bld %0,7 5006 swap %0 5007 swap %0\;lsl %0\;adc %0,__zero_reg__ 5008 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__ 5009 bst %0,0\;ror %0\;bld %0,7 5010 " ; empty 5011 [(set_attr "length" "2,4,4,1,3,5,3,0")]) 5012 5013 ;; Split all rotates of HI,SI and PSImode registers where rotation is by 5014 ;; a whole number of bytes. The split creates the appropriate moves and 5015 ;; considers all overlap situations. 5016 5017 ;; HImode does not need scratch. Use attribute for this constraint. 5018 5019 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")]) 5020 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")]) 5021 5022 ;; "rotlhi3" 5023 ;; "rotlpsi3" 5024 ;; "rotlsi3" 5025 (define_expand "rotl<mode>3" 5026 [(parallel [(set (match_operand:HISI 0 "register_operand" "") 5027 (rotate:HISI (match_operand:HISI 1 "register_operand" "") 5028 (match_operand:HISI 2 "const_int_operand" ""))) 5029 (clobber (match_dup 3))])] 5030 "" 5031 { 5032 if (!CONST_INT_P (operands[2])) 5033 FAIL; 5034 5035 int offset = INTVAL (operands[2]); 5036 5037 if (0 == offset % 8) 5038 { 5039 if (AVR_HAVE_MOVW && 0 == offset % 16) 5040 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode); 5041 else 5042 operands[3] = gen_rtx_SCRATCH (QImode); 5043 } 5044 else if (offset == 1 5045 || offset == GET_MODE_BITSIZE (<MODE>mode) -1) 5046 { 5047 // Support rotate left/right by 1. 5048 5049 emit_move_insn (operands[0], 5050 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2])); 5051 DONE; 5052 } 5053 else 5054 FAIL; 5055 }) 5056 5057 (define_insn_and_split "*rotlhi2.1_split" 5058 [(set (match_operand:HI 0 "register_operand" "=r") 5059 (rotate:HI (match_operand:HI 1 "register_operand" "0") 5060 (const_int 1)))] 5061 "" 5062 "#" 5063 "&& reload_completed" 5064 [(parallel [(set (match_dup 0) 5065 (rotate:HI (match_dup 1) 5066 (const_int 1))) 5067 (clobber (reg:CC REG_CC))])]) 5068 5069 (define_insn "*rotlhi2.1" 5070 [(set (match_operand:HI 0 "register_operand" "=r") 5071 (rotate:HI (match_operand:HI 1 "register_operand" "0") 5072 (const_int 1))) 5073 (clobber (reg:CC REG_CC))] 5074 "reload_completed" 5075 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__" 5076 [(set_attr "length" "3")]) 5077 5078 (define_insn_and_split "*rotlhi2.15_split" 5079 [(set (match_operand:HI 0 "register_operand" "=r") 5080 (rotate:HI (match_operand:HI 1 "register_operand" "0") 5081 (const_int 15)))] 5082 "" 5083 "#" 5084 "&& reload_completed" 5085 [(parallel [(set (match_dup 0) 5086 (rotate:HI (match_dup 1) 5087 (const_int 15))) 5088 (clobber (reg:CC REG_CC))])]) 5089 5090 (define_insn "*rotlhi2.15" 5091 [(set (match_operand:HI 0 "register_operand" "=r") 5092 (rotate:HI (match_operand:HI 1 "register_operand" "0") 5093 (const_int 15))) 5094 (clobber (reg:CC REG_CC))] 5095 "reload_completed" 5096 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7" 5097 [(set_attr "length" "4")]) 5098 5099 (define_insn_and_split "*rotlpsi2.1_split" 5100 [(set (match_operand:PSI 0 "register_operand" "=r") 5101 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 5102 (const_int 1)))] 5103 "" 5104 "#" 5105 "&& reload_completed" 5106 [(parallel [(set (match_dup 0) 5107 (rotate:PSI (match_dup 1) 5108 (const_int 1))) 5109 (clobber (reg:CC REG_CC))])]) 5110 5111 (define_insn "*rotlpsi2.1" 5112 [(set (match_operand:PSI 0 "register_operand" "=r") 5113 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 5114 (const_int 1))) 5115 (clobber (reg:CC REG_CC))] 5116 "reload_completed" 5117 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__" 5118 [(set_attr "length" "4")]) 5119 5120 (define_insn_and_split "*rotlpsi2.23_split" 5121 [(set (match_operand:PSI 0 "register_operand" "=r") 5122 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 5123 (const_int 23)))] 5124 "" 5125 "#" 5126 "&& reload_completed" 5127 [(parallel [(set (match_dup 0) 5128 (rotate:PSI (match_dup 1) 5129 (const_int 23))) 5130 (clobber (reg:CC REG_CC))])]) 5131 5132 (define_insn "*rotlpsi2.23" 5133 [(set (match_operand:PSI 0 "register_operand" "=r") 5134 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 5135 (const_int 23))) 5136 (clobber (reg:CC REG_CC))] 5137 "reload_completed" 5138 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7" 5139 [(set_attr "length" "5")]) 5140 5141 (define_insn_and_split "*rotlsi2.1_split" 5142 [(set (match_operand:SI 0 "register_operand" "=r") 5143 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5144 (const_int 1)))] 5145 "" 5146 "#" 5147 "&& reload_completed" 5148 [(parallel [(set (match_dup 0) 5149 (rotate:SI (match_dup 1) 5150 (const_int 1))) 5151 (clobber (reg:CC REG_CC))])]) 5152 5153 (define_insn "*rotlsi2.1" 5154 [(set (match_operand:SI 0 "register_operand" "=r") 5155 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5156 (const_int 1))) 5157 (clobber (reg:CC REG_CC))] 5158 "reload_completed" 5159 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__" 5160 [(set_attr "length" "5")]) 5161 5162 (define_insn_and_split "*rotlsi2.31_split" 5163 [(set (match_operand:SI 0 "register_operand" "=r") 5164 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5165 (const_int 31)))] 5166 "" 5167 "#" 5168 "&& reload_completed" 5169 [(parallel [(set (match_dup 0) 5170 (rotate:SI (match_dup 1) 5171 (const_int 31))) 5172 (clobber (reg:CC REG_CC))])]) 5173 5174 (define_insn "*rotlsi2.31" 5175 [(set (match_operand:SI 0 "register_operand" "=r") 5176 (rotate:SI (match_operand:SI 1 "register_operand" "0") 5177 (const_int 31))) 5178 (clobber (reg:CC REG_CC))] 5179 "reload_completed" 5180 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7" 5181 [(set_attr "length" "6")]) 5182 5183 ;; Overlapping non-HImode registers often (but not always) need a scratch. 5184 ;; The best we can do is use early clobber alternative "#&r" so that 5185 ;; completely non-overlapping operands dont get a scratch but # so register 5186 ;; allocation does not prefer non-overlapping. 5187 5188 5189 ;; Split word aligned rotates using scratch that is mode dependent. 5190 5191 ;; "*rotwhi" 5192 ;; "*rotwsi" 5193 (define_insn_and_split "*rotw<mode>" 5194 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r") 5195 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r") 5196 (match_operand 2 "const_int_operand" "n,n,n"))) 5197 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))] 5198 "AVR_HAVE_MOVW 5199 && CONST_INT_P (operands[2]) 5200 && GET_MODE_SIZE (<MODE>mode) % 2 == 0 5201 && 0 == INTVAL (operands[2]) % 16" 5202 "#" 5203 "&& reload_completed" 5204 [(const_int 0)] 5205 { 5206 avr_rotate_bytes (operands); 5207 DONE; 5208 }) 5209 5210 5211 ;; Split byte aligned rotates using scratch that is always QI mode. 5212 5213 ;; "*rotbhi" 5214 ;; "*rotbpsi" 5215 ;; "*rotbsi" 5216 (define_insn_and_split "*rotb<mode>" 5217 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r") 5218 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r") 5219 (match_operand 2 "const_int_operand" "n,n,n"))) 5220 (clobber (match_scratch:QI 3 "=<rotx>"))] 5221 "CONST_INT_P (operands[2]) 5222 && (8 == INTVAL (operands[2]) % 16 5223 || ((!AVR_HAVE_MOVW 5224 || GET_MODE_SIZE (<MODE>mode) % 2 != 0) 5225 && 0 == INTVAL (operands[2]) % 16))" 5226 "#" 5227 "&& reload_completed" 5228 [(const_int 0)] 5229 { 5230 avr_rotate_bytes (operands); 5231 DONE; 5232 }) 5233 5234 5235 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << 5236 ;; arithmetic shift left 5237 5238 ;; "ashlqi3" 5239 ;; "ashlqq3" "ashluqq3" 5240 (define_expand "ashl<mode>3" 5241 [(set (match_operand:ALL1 0 "register_operand" "") 5242 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "") 5243 (match_operand:QI 2 "nop_general_operand" "")))]) 5244 5245 (define_split ; ashlqi3_const4 5246 [(set (match_operand:ALL1 0 "d_register_operand" "") 5247 (ashift:ALL1 (match_dup 0) 5248 (const_int 4)))] 5249 "" 5250 [(set (match_dup 1) 5251 (rotate:QI (match_dup 1) 5252 (const_int 4))) 5253 (set (match_dup 1) 5254 (and:QI (match_dup 1) 5255 (const_int -16)))] 5256 { 5257 operands[1] = avr_to_int_mode (operands[0]); 5258 }) 5259 5260 (define_split ; ashlqi3_const5 5261 [(set (match_operand:ALL1 0 "d_register_operand" "") 5262 (ashift:ALL1 (match_dup 0) 5263 (const_int 5)))] 5264 "" 5265 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 5266 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1))) 5267 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))] 5268 { 5269 operands[1] = avr_to_int_mode (operands[0]); 5270 }) 5271 5272 (define_split ; ashlqi3_const6 5273 [(set (match_operand:ALL1 0 "d_register_operand" "") 5274 (ashift:ALL1 (match_dup 0) 5275 (const_int 6)))] 5276 "" 5277 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 5278 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2))) 5279 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))] 5280 { 5281 operands[1] = avr_to_int_mode (operands[0]); 5282 }) 5283 5284 ;; "*ashlqi3" 5285 ;; "*ashlqq3" "*ashluqq3" 5286 (define_insn_and_split "*ashl<mode>3_split" 5287 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r") 5288 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0") 5289 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))] 5290 "" 5291 "#" 5292 "&& reload_completed" 5293 [(parallel [(set (match_dup 0) 5294 (ashift:ALL1 (match_dup 1) 5295 (match_dup 2))) 5296 (clobber (reg:CC REG_CC))])]) 5297 5298 (define_insn "*ashl<mode>3" 5299 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r") 5300 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0") 5301 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm"))) 5302 (clobber (reg:CC REG_CC))] 5303 "reload_completed" 5304 { 5305 return ashlqi3_out (insn, operands, NULL); 5306 } 5307 [(set_attr "length" "5,0,1,2,4,6,9") 5308 (set_attr "adjust_len" "ashlqi")]) 5309 5310 (define_insn_and_split "ashl<mode>3" 5311 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 5312 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 5313 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 5314 "" 5315 "#" 5316 "&& reload_completed" 5317 [(parallel [(set (match_dup 0) 5318 (ashift:ALL2 (match_dup 1) 5319 (match_dup 2))) 5320 (clobber (reg:CC REG_CC))])]) 5321 5322 (define_insn "*ashl<mode>3" 5323 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 5324 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 5325 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm"))) 5326 (clobber (reg:CC REG_CC))] 5327 "reload_completed" 5328 { 5329 return ashlhi3_out (insn, operands, NULL); 5330 } 5331 [(set_attr "length" "6,0,2,2,4,10,10") 5332 (set_attr "adjust_len" "ashlhi")]) 5333 5334 5335 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts 5336 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation. 5337 5338 ;; "*ashluqihiqi3" 5339 ;; "*ashlsqihiqi3" 5340 (define_insn_and_split "*ashl<extend_su>qihiqi3" 5341 [(set (match_operand:QI 0 "register_operand" "=r") 5342 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0")) 5343 (match_operand:QI 2 "register_operand" "r")) 5344 0))] 5345 "" 5346 "#" 5347 "" 5348 [(set (match_dup 0) 5349 (ashift:QI (match_dup 1) 5350 (match_dup 2)))]) 5351 5352 ;; ??? Combiner does not recognize that it could split the following insn; 5353 ;; presumably because he has no register handy? 5354 5355 ;; "*ashluqihiqi3.mem" 5356 ;; "*ashlsqihiqi3.mem" 5357 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem" 5358 [(set (match_operand:QI 0 "memory_operand" "=m") 5359 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r")) 5360 (match_operand:QI 2 "register_operand" "r")) 5361 0))] 5362 "!reload_completed" 5363 { gcc_unreachable(); } 5364 "&& 1" 5365 [(set (match_dup 3) 5366 (ashift:QI (match_dup 1) 5367 (match_dup 2))) 5368 (set (match_dup 0) 5369 (match_dup 3))] 5370 { 5371 operands[3] = gen_reg_rtx (QImode); 5372 }) 5373 5374 ;; Similar. 5375 5376 (define_insn_and_split "*ashlhiqi3" 5377 [(set (match_operand:QI 0 "nonimmediate_operand" "=r") 5378 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0") 5379 (match_operand:QI 2 "register_operand" "r")) 0))] 5380 "!reload_completed" 5381 { gcc_unreachable(); } 5382 "&& 1" 5383 [(set (match_dup 4) 5384 (ashift:QI (match_dup 3) 5385 (match_dup 2))) 5386 (set (match_dup 0) 5387 (match_dup 4))] 5388 { 5389 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 5390 operands[4] = gen_reg_rtx (QImode); 5391 }) 5392 5393 ;; High part of 16-bit shift is unused after the instruction: 5394 ;; No need to compute it, map to 8-bit shift. 5395 5396 (define_peephole2 5397 [(parallel [(set (match_operand:HI 0 "register_operand" "") 5398 (ashift:HI (match_dup 0) 5399 (match_operand:QI 1 "register_operand" ""))) 5400 (clobber (reg:CC REG_CC))])] 5401 "" 5402 [(parallel [(set (match_dup 2) 5403 (ashift:QI (match_dup 2) 5404 (match_dup 1))) 5405 (clobber (reg:CC REG_CC))]) 5406 (clobber (match_dup 3))] 5407 { 5408 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 5409 5410 if (!peep2_reg_dead_p (1, operands[3])) 5411 FAIL; 5412 5413 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 5414 }) 5415 5416 5417 ;; "ashlsi3" 5418 ;; "ashlsq3" "ashlusq3" 5419 ;; "ashlsa3" "ashlusa3" 5420 (define_insn_and_split "ashl<mode>3" 5421 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 5422 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 5423 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 5424 "" 5425 "#" 5426 "&& reload_completed" 5427 [(parallel [(set (match_dup 0) 5428 (ashift:ALL4 (match_dup 1) 5429 (match_dup 2))) 5430 (clobber (reg:CC REG_CC))])]) 5431 5432 (define_insn "*ashl<mode>3" 5433 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 5434 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 5435 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm"))) 5436 (clobber (reg:CC REG_CC))] 5437 "reload_completed" 5438 { 5439 return ashlsi3_out (insn, operands, NULL); 5440 } 5441 [(set_attr "length" "8,0,4,4,8,10,12") 5442 (set_attr "adjust_len" "ashlsi")]) 5443 5444 ;; Optimize if a scratch register from LD_REGS happens to be available. 5445 5446 (define_peephole2 ; ashlqi3_l_const4 5447 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 5448 (ashift:ALL1 (match_dup 0) 5449 (const_int 4))) 5450 (clobber (reg:CC REG_CC))]) 5451 (match_scratch:QI 1 "d")] 5452 "" 5453 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 5454 (clobber (reg:CC REG_CC))]) 5455 (parallel [(set (match_dup 1) (const_int -16)) 5456 (clobber (reg:CC REG_CC))]) 5457 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 5458 (clobber (reg:CC REG_CC))])] 5459 { 5460 operands[2] = avr_to_int_mode (operands[0]); 5461 }) 5462 5463 (define_peephole2 ; ashlqi3_l_const5 5464 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 5465 (ashift:ALL1 (match_dup 0) 5466 (const_int 5))) 5467 (clobber (reg:CC REG_CC))]) 5468 (match_scratch:QI 1 "d")] 5469 "" 5470 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 5471 (clobber (reg:CC REG_CC))]) 5472 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1))) 5473 (clobber (reg:CC REG_CC))]) 5474 (parallel [(set (match_dup 1) (const_int -32)) 5475 (clobber (reg:CC REG_CC))]) 5476 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 5477 (clobber (reg:CC REG_CC))])] 5478 { 5479 operands[2] = avr_to_int_mode (operands[0]); 5480 }) 5481 5482 (define_peephole2 ; ashlqi3_l_const6 5483 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 5484 (ashift:ALL1 (match_dup 0) 5485 (const_int 6))) 5486 (clobber (reg:CC REG_CC))]) 5487 (match_scratch:QI 1 "d")] 5488 "" 5489 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 5490 (clobber (reg:CC REG_CC))]) 5491 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2))) 5492 (clobber (reg:CC REG_CC))]) 5493 (parallel [(set (match_dup 1) (const_int -64)) 5494 (clobber (reg:CC REG_CC))]) 5495 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 5496 (clobber (reg:CC REG_CC))])] 5497 { 5498 operands[2] = avr_to_int_mode (operands[0]); 5499 }) 5500 5501 (define_peephole2 5502 [(match_scratch:QI 3 "d") 5503 (parallel [(set (match_operand:ALL2 0 "register_operand" "") 5504 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "") 5505 (match_operand:QI 2 "const_int_operand" ""))) 5506 (clobber (reg:CC REG_CC))])] 5507 "" 5508 [(parallel [(set (match_dup 0) 5509 (ashift:ALL2 (match_dup 1) 5510 (match_dup 2))) 5511 (clobber (match_dup 3)) 5512 (clobber (reg:CC REG_CC))])]) 5513 5514 ;; "*ashlhi3_const" 5515 ;; "*ashlhq3_const" "*ashluhq3_const" 5516 ;; "*ashlha3_const" "*ashluha3_const" 5517 (define_insn_and_split "*ashl<mode>3_const_split" 5518 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 5519 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 5520 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 5521 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 5522 "reload_completed" 5523 "#" 5524 "&& reload_completed" 5525 [(parallel [(set (match_dup 0) 5526 (ashift:ALL2 (match_dup 1) 5527 (match_dup 2))) 5528 (clobber (match_dup 3)) 5529 (clobber (reg:CC REG_CC))])]) 5530 5531 (define_insn "*ashl<mode>3_const" 5532 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 5533 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 5534 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 5535 (clobber (match_scratch:QI 3 "=X,X,X,X,&d")) 5536 (clobber (reg:CC REG_CC))] 5537 "reload_completed" 5538 { 5539 return ashlhi3_out (insn, operands, NULL); 5540 } 5541 [(set_attr "length" "0,2,2,4,10") 5542 (set_attr "adjust_len" "ashlhi")]) 5543 5544 (define_peephole2 5545 [(match_scratch:QI 3 "d") 5546 (parallel [(set (match_operand:ALL4 0 "register_operand" "") 5547 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "") 5548 (match_operand:QI 2 "const_int_operand" ""))) 5549 (clobber (reg:CC REG_CC))])] 5550 "" 5551 [(parallel [(set (match_dup 0) 5552 (ashift:ALL4 (match_dup 1) 5553 (match_dup 2))) 5554 (clobber (match_dup 3)) 5555 (clobber (reg:CC REG_CC))])]) 5556 5557 ;; "*ashlsi3_const" 5558 ;; "*ashlsq3_const" "*ashlusq3_const" 5559 ;; "*ashlsa3_const" "*ashlusa3_const" 5560 (define_insn_and_split "*ashl<mode>3_const_split" 5561 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 5562 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 5563 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 5564 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 5565 "reload_completed" 5566 "#" 5567 "&& reload_completed" 5568 [(parallel [(set (match_dup 0) 5569 (ashift:ALL4 (match_dup 1) 5570 (match_dup 2))) 5571 (clobber (match_dup 3)) 5572 (clobber (reg:CC REG_CC))])]) 5573 5574 (define_insn "*ashl<mode>3_const" 5575 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 5576 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 5577 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 5578 (clobber (match_scratch:QI 3 "=X,X,X,&d")) 5579 (clobber (reg:CC REG_CC))] 5580 "reload_completed" 5581 { 5582 return ashlsi3_out (insn, operands, NULL); 5583 } 5584 [(set_attr "length" "0,4,4,10") 5585 (set_attr "adjust_len" "ashlsi")]) 5586 5587 (define_expand "ashlpsi3" 5588 [(parallel [(set (match_operand:PSI 0 "register_operand" "") 5589 (ashift:PSI (match_operand:PSI 1 "register_operand" "") 5590 (match_operand:QI 2 "nonmemory_operand" ""))) 5591 (clobber (scratch:QI))])] 5592 "" 5593 { 5594 if (AVR_HAVE_MUL 5595 && CONST_INT_P (operands[2])) 5596 { 5597 if (IN_RANGE (INTVAL (operands[2]), 3, 6)) 5598 { 5599 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode)); 5600 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1])); 5601 DONE; 5602 } 5603 else if (optimize_insn_for_speed_p () 5604 && INTVAL (operands[2]) != 16 5605 && IN_RANGE (INTVAL (operands[2]), 9, 22)) 5606 { 5607 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode)); 5608 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset)); 5609 DONE; 5610 } 5611 } 5612 }) 5613 5614 (define_insn_and_split "*ashlpsi3_split" 5615 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r") 5616 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0") 5617 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n"))) 5618 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 5619 "" 5620 "#" 5621 "&& reload_completed" 5622 [(parallel [(set (match_dup 0) 5623 (ashift:PSI (match_dup 1) 5624 (match_dup 2))) 5625 (clobber (match_dup 3)) 5626 (clobber (reg:CC REG_CC))])]) 5627 5628 (define_insn "*ashlpsi3" 5629 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r") 5630 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0") 5631 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n"))) 5632 (clobber (match_scratch:QI 3 "=X,X,X,&d")) 5633 (clobber (reg:CC REG_CC))] 5634 "reload_completed" 5635 { 5636 return avr_out_ashlpsi3 (insn, operands, NULL); 5637 } 5638 [(set_attr "adjust_len" "ashlpsi")]) 5639 5640 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> 5641 ;; arithmetic shift right 5642 5643 ;; "ashrqi3" 5644 ;; "ashrqq3" "ashruqq3" 5645 (define_insn_and_split "ashr<mode>3" 5646 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r") 5647 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0") 5648 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))] 5649 "" 5650 "#" 5651 "&& reload_completed" 5652 [(parallel [(set (match_dup 0) 5653 (ashiftrt:ALL1 (match_dup 1) 5654 (match_dup 2))) 5655 (clobber (reg:CC REG_CC))])]) 5656 5657 (define_insn "*ashr<mode>3" 5658 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r") 5659 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0") 5660 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm"))) 5661 (clobber (reg:CC REG_CC))] 5662 "reload_completed" 5663 { 5664 return ashrqi3_out (insn, operands, NULL); 5665 } 5666 [(set_attr "length" "5,0,1,2,5,4,9") 5667 (set_attr "adjust_len" "ashrqi")]) 5668 5669 ;; "ashrhi3" 5670 ;; "ashrhq3" "ashruhq3" 5671 ;; "ashrha3" "ashruha3" 5672 (define_insn_and_split "ashr<mode>3" 5673 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 5674 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 5675 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 5676 "" 5677 "#" 5678 "&& reload_completed" 5679 [(parallel [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 5680 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 5681 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm"))) 5682 (clobber (reg:CC REG_CC))])]) 5683 5684 (define_insn "*ashr<mode>3" 5685 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 5686 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 5687 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm"))) 5688 (clobber (reg:CC REG_CC))] 5689 "reload_completed" 5690 { 5691 return ashrhi3_out (insn, operands, NULL); 5692 } 5693 [(set_attr "length" "6,0,2,4,4,10,10") 5694 (set_attr "adjust_len" "ashrhi")]) 5695 5696 (define_insn_and_split "ashrpsi3" 5697 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r") 5698 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0") 5699 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n"))) 5700 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 5701 "" 5702 "#" 5703 "&& reload_completed" 5704 [(parallel [(set (match_dup 0) 5705 (ashiftrt:PSI (match_dup 1) 5706 (match_dup 2))) 5707 (clobber (match_dup 3)) 5708 (clobber (reg:CC REG_CC))])]) 5709 5710 (define_insn "*ashrpsi3" 5711 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r") 5712 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0") 5713 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n"))) 5714 (clobber (match_scratch:QI 3 "=X,X,X,X,&d")) 5715 (clobber (reg:CC REG_CC))] 5716 "reload_completed" 5717 { 5718 return avr_out_ashrpsi3 (insn, operands, NULL); 5719 } 5720 [(set_attr "adjust_len" "ashrpsi")]) 5721 5722 ;; "ashrsi3" 5723 ;; "ashrsq3" "ashrusq3" 5724 ;; "ashrsa3" "ashrusa3" 5725 (define_insn_and_split "ashr<mode>3" 5726 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 5727 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 5728 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 5729 "" 5730 "#" 5731 "&& reload_completed" 5732 [(parallel [(set (match_dup 0) 5733 (ashiftrt:ALL4 (match_dup 1) 5734 (match_dup 2))) 5735 (clobber (reg:CC REG_CC))])]) 5736 5737 (define_insn "*ashr<mode>3" 5738 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 5739 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 5740 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm"))) 5741 (clobber (reg:CC REG_CC))] 5742 "reload_completed" 5743 { 5744 return ashrsi3_out (insn, operands, NULL); 5745 } 5746 [(set_attr "length" "8,0,4,6,8,10,12") 5747 (set_attr "adjust_len" "ashrsi")]) 5748 5749 ;; Optimize if a scratch register from LD_REGS happens to be available. 5750 5751 (define_peephole2 5752 [(match_scratch:QI 3 "d") 5753 (parallel [(set (match_operand:ALL2 0 "register_operand" "") 5754 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "") 5755 (match_operand:QI 2 "const_int_operand" ""))) 5756 (clobber (reg:CC REG_CC))])] 5757 "" 5758 [(parallel [(set (match_dup 0) 5759 (ashiftrt:ALL2 (match_dup 1) 5760 (match_dup 2))) 5761 (clobber (match_dup 3)) 5762 (clobber (reg:CC REG_CC))])]) 5763 5764 ;; "*ashrhi3_const" 5765 ;; "*ashrhq3_const" "*ashruhq3_const" 5766 ;; "*ashrha3_const" "*ashruha3_const" 5767 (define_insn_and_split "*ashr<mode>3_const_split" 5768 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 5769 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 5770 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 5771 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 5772 "reload_completed" 5773 "#" 5774 "&& reload_completed" 5775 [(parallel [(set (match_dup 0) 5776 (ashiftrt:ALL2 (match_dup 1) 5777 (match_dup 2))) 5778 (clobber (match_dup 3)) 5779 (clobber (reg:CC REG_CC))])]) 5780 5781 (define_insn "*ashr<mode>3_const" 5782 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 5783 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 5784 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 5785 (clobber (match_scratch:QI 3 "=X,X,X,X,&d")) 5786 (clobber (reg:CC REG_CC))] 5787 "reload_completed" 5788 { 5789 return ashrhi3_out (insn, operands, NULL); 5790 } 5791 [(set_attr "length" "0,2,4,4,10") 5792 (set_attr "adjust_len" "ashrhi")]) 5793 5794 (define_peephole2 5795 [(match_scratch:QI 3 "d") 5796 (parallel [(set (match_operand:ALL4 0 "register_operand" "") 5797 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "") 5798 (match_operand:QI 2 "const_int_operand" ""))) 5799 (clobber (reg:CC REG_CC))])] 5800 "" 5801 [(parallel [(set (match_dup 0) 5802 (ashiftrt:ALL4 (match_dup 1) 5803 (match_dup 2))) 5804 (clobber (match_dup 3)) 5805 (clobber (reg:CC REG_CC))])]) 5806 5807 ;; "*ashrsi3_const" 5808 ;; "*ashrsq3_const" "*ashrusq3_const" 5809 ;; "*ashrsa3_const" "*ashrusa3_const" 5810 (define_insn_and_split "*ashr<mode>3_const_split" 5811 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 5812 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 5813 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 5814 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 5815 "reload_completed" 5816 "#" 5817 "&& reload_completed" 5818 [(parallel [(set (match_dup 0) 5819 (ashiftrt:ALL4 (match_dup 1) 5820 (match_dup 2))) 5821 (clobber (match_dup 3)) 5822 (clobber (reg:CC REG_CC))])]) 5823 5824 (define_insn "*ashr<mode>3_const" 5825 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 5826 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 5827 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 5828 (clobber (match_scratch:QI 3 "=X,X,X,&d")) 5829 (clobber (reg:CC REG_CC))] 5830 "reload_completed" 5831 { 5832 return ashrsi3_out (insn, operands, NULL); 5833 } 5834 [(set_attr "length" "0,4,4,10") 5835 (set_attr "adjust_len" "ashrsi")]) 5836 5837 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> 5838 ;; logical shift right 5839 5840 ;; "lshrqi3" 5841 ;; "lshrqq3" "lshruqq3" 5842 (define_expand "lshr<mode>3" 5843 [(set (match_operand:ALL1 0 "register_operand" "") 5844 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "") 5845 (match_operand:QI 2 "nop_general_operand" "")))]) 5846 5847 (define_split ; lshrqi3_const4 5848 [(set (match_operand:ALL1 0 "d_register_operand" "") 5849 (lshiftrt:ALL1 (match_dup 0) 5850 (const_int 4)))] 5851 "" 5852 [(set (match_dup 1) 5853 (rotate:QI (match_dup 1) 5854 (const_int 4))) 5855 (set (match_dup 1) 5856 (and:QI (match_dup 1) 5857 (const_int 15)))] 5858 { 5859 operands[1] = avr_to_int_mode (operands[0]); 5860 }) 5861 5862 (define_split ; lshrqi3_const5 5863 [(set (match_operand:ALL1 0 "d_register_operand" "") 5864 (lshiftrt:ALL1 (match_dup 0) 5865 (const_int 5)))] 5866 "" 5867 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 5868 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1))) 5869 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))] 5870 { 5871 operands[1] = avr_to_int_mode (operands[0]); 5872 }) 5873 5874 (define_split ; lshrqi3_const6 5875 [(set (match_operand:QI 0 "d_register_operand" "") 5876 (lshiftrt:QI (match_dup 0) 5877 (const_int 6)))] 5878 "" 5879 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 5880 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2))) 5881 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))] 5882 { 5883 operands[1] = avr_to_int_mode (operands[0]); 5884 }) 5885 5886 ;; "*lshrqi3" 5887 ;; "*lshrqq3" 5888 ;; "*lshruqq3" 5889 (define_insn_and_split "*lshr<mode>3_split" 5890 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r") 5891 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0") 5892 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm")))] 5893 "" 5894 "#" 5895 "&& reload_completed" 5896 [(parallel [(set (match_dup 0) 5897 (lshiftrt:ALL1 (match_dup 1) 5898 (match_dup 2))) 5899 (clobber (reg:CC REG_CC))])]) 5900 5901 (define_insn "*lshr<mode>3" 5902 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,!d,r,r") 5903 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,r ,0 ,0,0") 5904 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C07,n ,n,Qm"))) 5905 (clobber (reg:CC REG_CC))] 5906 "reload_completed" 5907 { 5908 return lshrqi3_out (insn, operands, NULL); 5909 } 5910 [(set_attr "adjust_len" "lshrqi")]) 5911 5912 ;; "lshrhi3" 5913 ;; "lshrhq3" "lshruhq3" 5914 ;; "lshrha3" "lshruha3" 5915 (define_insn_and_split "lshr<mode>3" 5916 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r ,r,r,r") 5917 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,r ,0,0,0") 5918 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,C15,K,n,Qm")))] 5919 "" 5920 "#" 5921 "&& reload_completed" 5922 [(parallel [(set (match_dup 0) 5923 (lshiftrt:ALL2 (match_dup 1) 5924 (match_dup 2))) 5925 (clobber (reg:CC REG_CC))])]) 5926 5927 (define_insn "*lshr<mode>3" 5928 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r ,r,r,r") 5929 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,r ,0,0,0") 5930 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,C15,K,n,Qm"))) 5931 (clobber (reg:CC REG_CC))] 5932 "reload_completed" 5933 { 5934 return lshrhi3_out (insn, operands, NULL); 5935 } 5936 [(set_attr "adjust_len" "lshrhi")]) 5937 5938 (define_insn_and_split "lshrpsi3" 5939 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r ,r,r") 5940 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,r ,0,0") 5941 (match_operand:QI 2 "nonmemory_operand" "r,P,O,C23,K,n"))) 5942 (clobber (match_scratch:QI 3 "=X,X,X,X ,X,&d"))] 5943 "" 5944 "#" 5945 "&& reload_completed" 5946 [(parallel [(set (match_dup 0) 5947 (lshiftrt:PSI (match_dup 1) 5948 (match_dup 2))) 5949 (clobber (match_dup 3)) 5950 (clobber (reg:CC REG_CC))])]) 5951 5952 (define_insn "*lshrpsi3" 5953 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r ,r,r") 5954 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,r ,0,0") 5955 (match_operand:QI 2 "nonmemory_operand" "r,P,O,C23,K,n"))) 5956 (clobber (match_scratch:QI 3 "=X,X,X,X ,X,&d")) 5957 (clobber (reg:CC REG_CC))] 5958 "reload_completed" 5959 { 5960 return avr_out_lshrpsi3 (insn, operands, NULL); 5961 } 5962 [(set_attr "adjust_len" "lshrpsi")]) 5963 5964 ;; "lshrsi3" 5965 ;; "lshrsq3" "lshrusq3" 5966 ;; "lshrsa3" "lshrusa3" 5967 (define_insn_and_split "lshr<mode>3" 5968 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r ,r,r") 5969 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,r ,0,0") 5970 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,C31,n,Qm")))] 5971 "" 5972 "#" 5973 "&& reload_completed" 5974 [(parallel [(set (match_dup 0) 5975 (lshiftrt:ALL4 (match_dup 1) 5976 (match_dup 2))) 5977 (clobber (reg:CC REG_CC))])]) 5978 5979 (define_insn "*lshr<mode>3" 5980 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r ,r,r") 5981 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,r ,0,0") 5982 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,C31,n,Qm"))) 5983 (clobber (reg:CC REG_CC))] 5984 "reload_completed" 5985 { 5986 return lshrsi3_out (insn, operands, NULL); 5987 } 5988 [(set_attr "adjust_len" "lshrsi")]) 5989 5990 ;; Optimize if a scratch register from LD_REGS happens to be available. 5991 5992 (define_peephole2 ; lshrqi3_l_const4 5993 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 5994 (lshiftrt:ALL1 (match_dup 0) 5995 (const_int 4))) 5996 (clobber (reg:CC REG_CC))]) 5997 (match_scratch:QI 1 "d")] 5998 "" 5999 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 6000 (clobber (reg:CC REG_CC))]) 6001 (parallel [(set (match_dup 1) (const_int 15)) 6002 (clobber (reg:CC REG_CC))]) 6003 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 6004 (clobber (reg:CC REG_CC))])] 6005 { 6006 operands[2] = avr_to_int_mode (operands[0]); 6007 }) 6008 6009 (define_peephole2 ; lshrqi3_l_const5 6010 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 6011 (lshiftrt:ALL1 (match_dup 0) 6012 (const_int 5))) 6013 (clobber (reg:CC REG_CC))]) 6014 (match_scratch:QI 1 "d")] 6015 "" 6016 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 6017 (clobber (reg:CC REG_CC))]) 6018 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1))) 6019 (clobber (reg:CC REG_CC))]) 6020 (parallel [(set (match_dup 1) (const_int 7)) 6021 (clobber (reg:CC REG_CC))]) 6022 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 6023 (clobber (reg:CC REG_CC))])] 6024 { 6025 operands[2] = avr_to_int_mode (operands[0]); 6026 }) 6027 6028 (define_peephole2 ; lshrqi3_l_const6 6029 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "") 6030 (lshiftrt:ALL1 (match_dup 0) 6031 (const_int 6))) 6032 (clobber (reg:CC REG_CC))]) 6033 (match_scratch:QI 1 "d")] 6034 "" 6035 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 6036 (clobber (reg:CC REG_CC))]) 6037 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2))) 6038 (clobber (reg:CC REG_CC))]) 6039 (parallel [(set (match_dup 1) (const_int 3)) 6040 (clobber (reg:CC REG_CC))]) 6041 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1))) 6042 (clobber (reg:CC REG_CC))])] 6043 { 6044 operands[2] = avr_to_int_mode (operands[0]); 6045 }) 6046 6047 (define_peephole2 ; "*lshrhi3_const" 6048 [(match_scratch:QI 3 "d") 6049 (parallel [(set (match_operand:ALL2 0 "register_operand" "") 6050 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "") 6051 (match_operand:QI 2 "const_int_operand" ""))) 6052 (clobber (reg:CC REG_CC))])] 6053 "" 6054 [(parallel [(set (match_dup 0) 6055 (lshiftrt:ALL2 (match_dup 1) 6056 (match_dup 2))) 6057 (clobber (match_dup 3)) 6058 (clobber (reg:CC REG_CC))])]) 6059 6060 ;; "*lshrhi3_const" 6061 ;; "*lshrhq3_const" "*lshruhq3_const" 6062 ;; "*lshrha3_const" "*lshruha3_const" 6063 (define_insn_and_split "*lshr<mode>3_const_split" 6064 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r ,r,r") 6065 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,r ,0,0") 6066 (match_operand:QI 2 "const_int_operand" "L,P,O,C15,K,n"))) 6067 (clobber (match_scratch:QI 3 "=X,X,X,X ,X,&d"))] 6068 "reload_completed" 6069 "#" 6070 "&& reload_completed" 6071 [(parallel [(set (match_dup 0) 6072 (lshiftrt:ALL2 (match_dup 1) 6073 (match_dup 2))) 6074 (clobber (match_dup 3)) 6075 (clobber (reg:CC REG_CC))])]) 6076 6077 (define_insn "*lshr<mode>3_const" 6078 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r ,r,r") 6079 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,r ,0,0") 6080 (match_operand:QI 2 "const_int_operand" "L,P,O,C15,K,n"))) 6081 (clobber (match_scratch:QI 3 "=X,X,X,X ,X,&d")) 6082 (clobber (reg:CC REG_CC))] 6083 "reload_completed" 6084 { 6085 return lshrhi3_out (insn, operands, NULL); 6086 } 6087 [(set_attr "adjust_len" "lshrhi")]) 6088 6089 (define_peephole2 ; "*lshrsi3_const" 6090 [(match_scratch:QI 3 "d") 6091 (parallel [(set (match_operand:ALL4 0 "register_operand" "") 6092 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "") 6093 (match_operand:QI 2 "const_int_operand" ""))) 6094 (clobber (reg:CC REG_CC))])] 6095 "" 6096 [(parallel [(set (match_dup 0) 6097 (lshiftrt:ALL4 (match_dup 1) 6098 (match_dup 2))) 6099 (clobber (match_dup 3)) 6100 (clobber (reg:CC REG_CC))])]) 6101 6102 ;; "*lshrsi3_const" 6103 ;; "*lshrsq3_const" "*lshrusq3_const" 6104 ;; "*lshrsa3_const" "*lshrusa3_const" 6105 (define_insn_and_split "*lshr<mode>3_const_split" 6106 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r ,r") 6107 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,r ,0") 6108 (match_operand:QI 2 "const_int_operand" "L,P,O,C31,n"))) 6109 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))] 6110 "reload_completed" 6111 "#" 6112 "&& reload_completed" 6113 [(parallel [(set (match_dup 0) 6114 (lshiftrt:ALL4 (match_dup 1) 6115 (match_dup 2))) 6116 (clobber (match_dup 3)) 6117 (clobber (reg:CC REG_CC))])]) 6118 6119 (define_insn "*lshr<mode>3_const" 6120 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r ,r") 6121 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,r ,0") 6122 (match_operand:QI 2 "const_int_operand" "L,P,O,C31,n"))) 6123 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d")) 6124 (clobber (reg:CC REG_CC))] 6125 "reload_completed" 6126 { 6127 return lshrsi3_out (insn, operands, NULL); 6128 } 6129 [(set_attr "adjust_len" "lshrsi")]) 6130 6131 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) 6132 ;; abs 6133 6134 (define_insn_and_split "absqi2" 6135 [(set (match_operand:QI 0 "register_operand" "=r") 6136 (abs:QI (match_operand:QI 1 "register_operand" "0")))] 6137 "" 6138 "#" 6139 "&& reload_completed" 6140 [(parallel [(set (match_dup 0) 6141 (abs:QI (match_dup 1))) 6142 (clobber (reg:CC REG_CC))])]) 6143 6144 (define_insn "*absqi2" 6145 [(set (match_operand:QI 0 "register_operand" "=r") 6146 (abs:QI (match_operand:QI 1 "register_operand" "0"))) 6147 (clobber (reg:CC REG_CC))] 6148 "reload_completed" 6149 "sbrc %0,7 6150 neg %0" 6151 [(set_attr "length" "2")]) 6152 6153 6154 (define_insn_and_split "abssf2" 6155 [(set (match_operand:SF 0 "register_operand" "=d,r") 6156 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))] 6157 "" 6158 "#" 6159 "&& reload_completed" 6160 [(parallel [(set (match_dup 0) 6161 (abs:SF (match_dup 1))) 6162 (clobber (reg:CC REG_CC))])]) 6163 6164 (define_insn "*abssf2" 6165 [(set (match_operand:SF 0 "register_operand" "=d,r") 6166 (abs:SF (match_operand:SF 1 "register_operand" "0,0"))) 6167 (clobber (reg:CC REG_CC))] 6168 "reload_completed" 6169 "@ 6170 andi %D0,0x7f 6171 clt\;bld %D0,7" 6172 [(set_attr "length" "1,2")]) 6173 6174 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 6175 ;; neg 6176 6177 (define_insn_and_split "negqi2" 6178 [(set (match_operand:QI 0 "register_operand" "=r") 6179 (neg:QI (match_operand:QI 1 "register_operand" "0")))] 6180 "" 6181 "#" 6182 "&& reload_completed" 6183 [(parallel [(set (match_dup 0) 6184 (neg:QI (match_dup 1))) 6185 (clobber (reg:CC REG_CC))])]) 6186 6187 (define_insn "*negqi2" 6188 [(set (match_operand:QI 0 "register_operand" "=r") 6189 (neg:QI (match_operand:QI 1 "register_operand" "0"))) 6190 (clobber (reg:CC REG_CC))] 6191 "reload_completed" 6192 "neg %0" 6193 [(set_attr "length" "1")]) 6194 6195 (define_insn_and_split "*negqihi2_split" 6196 [(set (match_operand:HI 0 "register_operand" "=r") 6197 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))] 6198 "" 6199 "#" 6200 "&& reload_completed" 6201 [(parallel [(set (match_dup 0) 6202 (neg:HI (sign_extend:HI (match_dup 1)))) 6203 (clobber (reg:CC REG_CC))])]) 6204 6205 (define_insn "*negqihi2" 6206 [(set (match_operand:HI 0 "register_operand" "=r") 6207 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))) 6208 (clobber (reg:CC REG_CC))] 6209 "reload_completed" 6210 "clr %B0\;neg %A0\;brge .+2\;com %B0" 6211 [(set_attr "length" "4")]) 6212 6213 (define_insn_and_split "neghi2" 6214 [(set (match_operand:HI 0 "register_operand" "=r,&r") 6215 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))] 6216 "" 6217 "#" 6218 "&& reload_completed" 6219 [(parallel [(set (match_dup 0) 6220 (neg:HI (match_dup 1))) 6221 (clobber (reg:CC REG_CC))])]) 6222 6223 (define_insn "*neghi2" 6224 [(set (match_operand:HI 0 "register_operand" "=r,&r") 6225 (neg:HI (match_operand:HI 1 "register_operand" "0,r"))) 6226 (clobber (reg:CC REG_CC))] 6227 "reload_completed" 6228 "@ 6229 neg %B0\;neg %A0\;sbc %B0,__zero_reg__ 6230 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1" 6231 [(set_attr "length" "3,4")]) 6232 6233 (define_insn_and_split "negpsi2" 6234 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r") 6235 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))] 6236 "" 6237 "#" 6238 "&& reload_completed" 6239 [(parallel [(set (match_dup 0) 6240 (neg:PSI (match_dup 1))) 6241 (clobber (reg:CC REG_CC))])]) 6242 6243 (define_insn "*negpsi2" 6244 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r") 6245 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r"))) 6246 (clobber (reg:CC REG_CC))] 6247 "reload_completed" 6248 "@ 6249 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1 6250 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__ 6251 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1" 6252 [(set_attr "length" "5,6,6")]) 6253 6254 (define_insn_and_split "negsi2" 6255 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r") 6256 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))] 6257 "" 6258 "#" 6259 "&& reload_completed" 6260 [(parallel [(set (match_dup 0) 6261 (neg:SI (match_dup 1))) 6262 (clobber (reg:CC REG_CC))])] 6263 "" 6264 [(set_attr "isa" "*,*,mov,movw")]) 6265 6266 (define_insn "*negsi2" 6267 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r") 6268 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r"))) 6269 (clobber (reg:CC REG_CC))] 6270 "reload_completed" 6271 "@ 6272 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1) 6273 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__ 6274 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1 6275 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1" 6276 [(set_attr "length" "7,8,8,7") 6277 (set_attr "isa" "*,*,mov,movw")]) 6278 6279 (define_insn_and_split "negsf2" 6280 [(set (match_operand:SF 0 "register_operand" "=d,r") 6281 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))] 6282 "" 6283 "#" 6284 "&& reload_completed" 6285 [(parallel [(set (match_dup 0) 6286 (neg:SF (match_dup 1))) 6287 (clobber (reg:CC REG_CC))])]) 6288 6289 (define_insn "*negsf2" 6290 [(set (match_operand:SF 0 "register_operand" "=d,r") 6291 (neg:SF (match_operand:SF 1 "register_operand" "0,0"))) 6292 (clobber (reg:CC REG_CC))] 6293 "reload_completed" 6294 "@ 6295 subi %D0,0x80 6296 bst %D0,7\;com %D0\;bld %D0,7\;com %D0" 6297 [(set_attr "length" "1,4")]) 6298 6299 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6300 ;; not 6301 6302 (define_insn_and_split "one_cmplqi2" 6303 [(set (match_operand:QI 0 "register_operand" "=r") 6304 (not:QI (match_operand:QI 1 "register_operand" "0")))] 6305 "" 6306 "#" 6307 "&& reload_completed" 6308 [(parallel [(set (match_dup 0) 6309 (not:QI (match_dup 1))) 6310 (clobber (reg:CC REG_CC))])]) 6311 6312 (define_insn "*one_cmplqi2" 6313 [(set (match_operand:QI 0 "register_operand" "=r") 6314 (not:QI (match_operand:QI 1 "register_operand" "0"))) 6315 (clobber (reg:CC REG_CC))] 6316 "reload_completed" 6317 "com %0" 6318 [(set_attr "length" "1")]) 6319 6320 (define_insn_and_split "one_cmplhi2" 6321 [(set (match_operand:HI 0 "register_operand" "=r") 6322 (not:HI (match_operand:HI 1 "register_operand" "0")))] 6323 "" 6324 "#" 6325 "&& reload_completed" 6326 [(parallel [(set (match_dup 0) 6327 (not:HI (match_dup 1))) 6328 (clobber (reg:CC REG_CC))])]) 6329 6330 (define_insn "*one_cmplhi2" 6331 [(set (match_operand:HI 0 "register_operand" "=r") 6332 (not:HI (match_operand:HI 1 "register_operand" "0"))) 6333 (clobber (reg:CC REG_CC))] 6334 "reload_completed" 6335 "com %0 6336 com %B0" 6337 [(set_attr "length" "2")]) 6338 6339 (define_insn_and_split "one_cmplpsi2" 6340 [(set (match_operand:PSI 0 "register_operand" "=r") 6341 (not:PSI (match_operand:PSI 1 "register_operand" "0")))] 6342 "" 6343 "#" 6344 "&& reload_completed" 6345 [(parallel [(set (match_dup 0) 6346 (not:PSI (match_dup 1))) 6347 (clobber (reg:CC REG_CC))])]) 6348 6349 (define_insn "*one_cmplpsi2" 6350 [(set (match_operand:PSI 0 "register_operand" "=r") 6351 (not:PSI (match_operand:PSI 1 "register_operand" "0"))) 6352 (clobber (reg:CC REG_CC))] 6353 "reload_completed" 6354 "com %0\;com %B0\;com %C0" 6355 [(set_attr "length" "3")]) 6356 6357 (define_insn_and_split "one_cmplsi2" 6358 [(set (match_operand:SI 0 "register_operand" "=r") 6359 (not:SI (match_operand:SI 1 "register_operand" "0")))] 6360 "" 6361 "#" 6362 "&& reload_completed" 6363 [(parallel [(set (match_dup 0) 6364 (not:SI (match_dup 1))) 6365 (clobber (reg:CC REG_CC))])]) 6366 6367 (define_insn "*one_cmplsi2" 6368 [(set (match_operand:SI 0 "register_operand" "=r") 6369 (not:SI (match_operand:SI 1 "register_operand" "0"))) 6370 (clobber (reg:CC REG_CC))] 6371 "reload_completed" 6372 "com %0 6373 com %B0 6374 com %C0 6375 com %D0" 6376 [(set_attr "length" "4")]) 6377 6378 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x 6379 ;; sign extend 6380 6381 ;; We keep combiner from inserting hard registers into the input of sign- and 6382 ;; zero-extends. A hard register in the input operand is not wanted because 6383 ;; 32-bit multiply patterns clobber some hard registers and extends with a 6384 ;; hard register that overlaps these clobbers won't be combined to a widening 6385 ;; multiplication. There is no need for combine to propagate hard registers, 6386 ;; register allocation can do it just as well. 6387 6388 (define_insn_and_split "extendqihi2" 6389 [(set (match_operand:HI 0 "register_operand" "=r,r") 6390 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 6391 "" 6392 "#" 6393 "&& reload_completed" 6394 [(parallel [(set (match_dup 0) 6395 (sign_extend:HI (match_dup 1))) 6396 (clobber (reg:CC REG_CC))])]) 6397 6398 (define_insn "*extendqihi2" 6399 [(set (match_operand:HI 0 "register_operand" "=r,r") 6400 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r"))) 6401 (clobber (reg:CC REG_CC))] 6402 "reload_completed" 6403 { 6404 return avr_out_sign_extend (insn, operands, NULL); 6405 } 6406 [(set_attr "length" "3,4") 6407 (set_attr "adjust_len" "sext")]) 6408 6409 (define_insn_and_split "extendqipsi2" 6410 [(set (match_operand:PSI 0 "register_operand" "=r,r") 6411 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 6412 "" 6413 "#" 6414 "&& reload_completed" 6415 [(parallel [(set (match_dup 0) 6416 (sign_extend:PSI (match_dup 1))) 6417 (clobber (reg:CC REG_CC))])]) 6418 6419 (define_insn "*extendqipsi2" 6420 [(set (match_operand:PSI 0 "register_operand" "=r,r") 6421 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r"))) 6422 (clobber (reg:CC REG_CC))] 6423 "reload_completed" 6424 { 6425 return avr_out_sign_extend (insn, operands, NULL); 6426 } 6427 [(set_attr "length" "4,5") 6428 (set_attr "adjust_len" "sext")]) 6429 6430 (define_insn_and_split "extendqisi2" 6431 [(set (match_operand:SI 0 "register_operand" "=r,r") 6432 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 6433 "" 6434 "#" 6435 "&& reload_completed" 6436 [(parallel [(set (match_dup 0) 6437 (sign_extend:SI (match_dup 1))) 6438 (clobber (reg:CC REG_CC))])]) 6439 6440 (define_insn "*extendqisi2" 6441 [(set (match_operand:SI 0 "register_operand" "=r,r") 6442 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r"))) 6443 (clobber (reg:CC REG_CC))] 6444 "reload_completed" 6445 { 6446 return avr_out_sign_extend (insn, operands, NULL); 6447 } 6448 [(set_attr "length" "5,6") 6449 (set_attr "adjust_len" "sext")]) 6450 6451 (define_insn_and_split "extendhipsi2" 6452 [(set (match_operand:PSI 0 "register_operand" "=r,r") 6453 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))] 6454 "" 6455 "#" 6456 "&& reload_completed" 6457 [(parallel [(set (match_dup 0) 6458 (sign_extend:PSI (match_dup 1))) 6459 (clobber (reg:CC REG_CC))])]) 6460 6461 (define_insn "*extendhipsi2" 6462 [(set (match_operand:PSI 0 "register_operand" "=r,r") 6463 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r"))) 6464 (clobber (reg:CC REG_CC))] 6465 "reload_completed" 6466 { 6467 return avr_out_sign_extend (insn, operands, NULL); 6468 } 6469 [(set_attr "length" "3,5") 6470 (set_attr "adjust_len" "sext")]) 6471 6472 (define_insn_and_split "extendhisi2" 6473 [(set (match_operand:SI 0 "register_operand" "=r,r") 6474 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))] 6475 "" 6476 "#" 6477 "&& reload_completed" 6478 [(parallel [(set (match_dup 0) 6479 (sign_extend:SI (match_dup 1))) 6480 (clobber (reg:CC REG_CC))])]) 6481 6482 (define_insn "*extendhisi2" 6483 [(set (match_operand:SI 0 "register_operand" "=r,r") 6484 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r"))) 6485 (clobber (reg:CC REG_CC))] 6486 "reload_completed" 6487 { 6488 return avr_out_sign_extend (insn, operands, NULL); 6489 } 6490 [(set_attr "length" "4,6") 6491 (set_attr "adjust_len" "sext")]) 6492 6493 (define_insn_and_split "extendpsisi2" 6494 [(set (match_operand:SI 0 "register_operand" "=r") 6495 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))] 6496 "" 6497 "#" 6498 "&& reload_completed" 6499 [(parallel [(set (match_dup 0) 6500 (sign_extend:SI (match_dup 1))) 6501 (clobber (reg:CC REG_CC))])]) 6502 6503 (define_insn "*extendpsisi2" 6504 [(set (match_operand:SI 0 "register_operand" "=r") 6505 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0"))) 6506 (clobber (reg:CC REG_CC))] 6507 "reload_completed" 6508 { 6509 return avr_out_sign_extend (insn, operands, NULL); 6510 } 6511 [(set_attr "length" "3") 6512 (set_attr "adjust_len" "sext")]) 6513 6514 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x 6515 ;; zero extend 6516 6517 (define_insn_and_split "zero_extendqihi2" 6518 [(set (match_operand:HI 0 "register_operand" "=r") 6519 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 6520 "" 6521 "#" 6522 "reload_completed" 6523 [(set (match_dup 2) (match_dup 1)) 6524 (set (match_dup 3) (const_int 0))] 6525 { 6526 unsigned int low_off = subreg_lowpart_offset (QImode, HImode); 6527 unsigned int high_off = subreg_highpart_offset (QImode, HImode); 6528 6529 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off); 6530 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off); 6531 }) 6532 6533 (define_insn_and_split "zero_extendqipsi2" 6534 [(set (match_operand:PSI 0 "register_operand" "=r") 6535 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 6536 "" 6537 "#" 6538 "reload_completed" 6539 [(set (match_dup 2) (match_dup 1)) 6540 (set (match_dup 3) (const_int 0)) 6541 (set (match_dup 4) (const_int 0))] 6542 { 6543 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0); 6544 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1); 6545 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 6546 }) 6547 6548 (define_insn_and_split "zero_extendqisi2" 6549 [(set (match_operand:SI 0 "register_operand" "=r") 6550 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 6551 "" 6552 "#" 6553 "reload_completed" 6554 [(set (match_dup 2) (zero_extend:HI (match_dup 1))) 6555 (set (match_dup 3) (const_int 0))] 6556 { 6557 unsigned int low_off = subreg_lowpart_offset (HImode, SImode); 6558 unsigned int high_off = subreg_highpart_offset (HImode, SImode); 6559 6560 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); 6561 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); 6562 }) 6563 6564 (define_insn_and_split "zero_extendhipsi2" 6565 [(set (match_operand:PSI 0 "register_operand" "=r") 6566 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))] 6567 "" 6568 "#" 6569 "reload_completed" 6570 [(set (match_dup 2) (match_dup 1)) 6571 (set (match_dup 3) (const_int 0))] 6572 { 6573 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0); 6574 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 6575 }) 6576 6577 (define_insn_and_split "n_extendhipsi2" 6578 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r") 6579 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n") 6580 (match_operand:HI 2 "register_operand" "r,r,r,r"))) 6581 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 6582 "" 6583 "#" 6584 "reload_completed" 6585 [(set (match_dup 4) (match_dup 2)) 6586 (set (match_dup 3) (match_dup 6)) 6587 ; no-op move in the case where no scratch is needed 6588 (set (match_dup 5) (match_dup 3))] 6589 { 6590 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0); 6591 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 6592 operands[6] = operands[1]; 6593 6594 if (GET_CODE (operands[3]) == SCRATCH) 6595 operands[3] = operands[5]; 6596 }) 6597 6598 (define_insn_and_split "zero_extendhisi2" 6599 [(set (match_operand:SI 0 "register_operand" "=r") 6600 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))] 6601 "" 6602 "#" 6603 "reload_completed" 6604 [(set (match_dup 2) (match_dup 1)) 6605 (set (match_dup 3) (const_int 0))] 6606 { 6607 unsigned int low_off = subreg_lowpart_offset (HImode, SImode); 6608 unsigned int high_off = subreg_highpart_offset (HImode, SImode); 6609 6610 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); 6611 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); 6612 }) 6613 6614 (define_insn_and_split "zero_extendpsisi2" 6615 [(set (match_operand:SI 0 "register_operand" "=r") 6616 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))] 6617 "" 6618 "#" 6619 "reload_completed" 6620 [(set (match_dup 2) (match_dup 1)) 6621 (set (match_dup 3) (const_int 0))] 6622 { 6623 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0); 6624 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3); 6625 }) 6626 6627 (define_insn_and_split "zero_extendqidi2" 6628 [(set (match_operand:DI 0 "register_operand" "=r") 6629 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] 6630 "" 6631 "#" 6632 "reload_completed" 6633 [(set (match_dup 2) (zero_extend:SI (match_dup 1))) 6634 (set (match_dup 3) (const_int 0))] 6635 { 6636 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 6637 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 6638 6639 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 6640 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 6641 }) 6642 6643 (define_insn_and_split "zero_extendhidi2" 6644 [(set (match_operand:DI 0 "register_operand" "=r") 6645 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))] 6646 "" 6647 "#" 6648 "reload_completed" 6649 [(set (match_dup 2) (zero_extend:SI (match_dup 1))) 6650 (set (match_dup 3) (const_int 0))] 6651 { 6652 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 6653 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 6654 6655 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 6656 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 6657 }) 6658 6659 (define_insn_and_split "zero_extendsidi2" 6660 [(set (match_operand:DI 0 "register_operand" "=r") 6661 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] 6662 "" 6663 "#" 6664 "reload_completed" 6665 [(set (match_dup 2) (match_dup 1)) 6666 (set (match_dup 3) (const_int 0))] 6667 { 6668 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 6669 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 6670 6671 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 6672 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 6673 }) 6674 6675 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=> 6676 ;; compare 6677 6678 ;; "*swapped_tstqi" "*swapped_tstqq" 6679 (define_insn "*swapped_tst<mode>" 6680 [(set (reg:CC REG_CC) 6681 (compare:CC (match_operand:ALLs1 0 "const0_operand" "Y00") 6682 (match_operand:ALLs1 1 "register_operand" "r")))] 6683 "reload_completed" 6684 "cp __zero_reg__,%1" 6685 [(set_attr "length" "1")]) 6686 6687 6688 ;; "*swapped_tsthi" "*swapped_tsthq" "*swapped_tstha" 6689 (define_insn "*swapped_tst<mode>" 6690 [(set (reg:CC REG_CC) 6691 (compare:CC (match_operand:ALLs2 0 "const0_operand" "Y00") 6692 (match_operand:ALLs2 1 "register_operand" "r")))] 6693 "reload_completed" 6694 "cp __zero_reg__,%A1 6695 cpc __zero_reg__,%B1" 6696 [(set_attr "length" "2")]) 6697 6698 6699 (define_insn "*swapped_tstpsi" 6700 [(set (reg:CC REG_CC) 6701 (compare:CC (const_int 0) 6702 (match_operand:PSI 0 "register_operand" "r")))] 6703 "reload_completed" 6704 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0" 6705 [(set_attr "length" "3")]) 6706 6707 6708 ;; "*swapped_tstsi" "*swapped_tstsq" "*swapped_tstsa" 6709 (define_insn "*swapped_tst<mode>" 6710 [(set (reg:CC REG_CC) 6711 (compare:CC (match_operand:ALLs4 0 "const0_operand" "Y00") 6712 (match_operand:ALLs4 1 "register_operand" "r")))] 6713 "reload_completed" 6714 "cp __zero_reg__,%A1 6715 cpc __zero_reg__,%B1 6716 cpc __zero_reg__,%C1 6717 cpc __zero_reg__,%D1" 6718 [(set_attr "length" "4")]) 6719 6720 6721 ;; "cmpqi3" 6722 ;; "cmpqq3" "cmpuqq3" 6723 (define_insn "cmp<mode>3" 6724 [(set (reg:CC REG_CC) 6725 (compare:CC (match_operand:ALL1 0 "register_operand" "r ,r,d") 6726 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))] 6727 "reload_completed" 6728 "@ 6729 cp %0, __zero_reg__ 6730 cp %0,%1 6731 cpi %0,lo8(%1)" 6732 [(set_attr "length" "1,1,1")]) 6733 6734 6735 ;; May be generated by "*cbranch<HISI:mode>.<code><QIPSI:mode>.0/1". 6736 (define_insn "*cmp<HISI:mode>.<code><QIPSI:mode>.0" 6737 [(set (reg:CC REG_CC) 6738 (compare:CC (any_extend:HISI (match_operand:QIPSI 0 "register_operand" "r")) 6739 (match_operand:HISI 1 "register_operand" "r")))] 6740 "reload_completed 6741 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)" 6742 { 6743 return avr_out_cmp_ext (operands, <CODE>, nullptr); 6744 } 6745 [(set_attr "adjust_len" "cmp_<extend_su>ext")]) 6746 6747 ;; Swapped version of the above. 6748 ;; May be generated by "*cbranch<HISI:mode>.<code><QIPSI:mode>.0/1". 6749 (define_insn "*cmp<HISI:mode>.<code><QIPSI:mode>.1" 6750 [(set (reg:CC REG_CC) 6751 (compare:CC (match_operand:HISI 0 "register_operand" "r") 6752 (any_extend:HISI (match_operand:QIPSI 1 "register_operand" "r"))))] 6753 "reload_completed 6754 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)" 6755 { 6756 return avr_out_cmp_ext (operands, <CODE>, nullptr); 6757 } 6758 [(set_attr "adjust_len" "cmp_<extend_su>ext")]) 6759 6760 6761 ;; "cmphi3" 6762 ;; "cmphq3" "cmpuhq3" 6763 ;; "cmpha3" "cmpuha3" 6764 (define_insn "cmp<mode>3" 6765 [(set (reg:CC REG_CC) 6766 (compare:CC (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r") 6767 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn"))) 6768 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))] 6769 "reload_completed" 6770 { 6771 switch (which_alternative) 6772 { 6773 case 0: 6774 case 1: 6775 return avr_out_tsthi (insn, operands, NULL); 6776 6777 case 2: 6778 return "cp %A0,%A1\;cpc %B0,%B1"; 6779 6780 case 3: 6781 if (<MODE>mode != HImode) 6782 break; 6783 return reg_unused_after (insn, operands[0]) 6784 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)" 6785 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2"; 6786 6787 case 4: 6788 if (<MODE>mode != HImode) 6789 break; 6790 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2"; 6791 } 6792 6793 return avr_out_compare (insn, operands, NULL); 6794 } 6795 [(set_attr "length" "2,2,2,3,4,2,4") 6796 (set_attr "isa" "adiw,*,*,*,*,*,*") 6797 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")]) 6798 6799 (define_insn "*cmppsi" 6800 [(set (reg:CC REG_CC) 6801 (compare:CC (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r") 6802 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n"))) 6803 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))] 6804 "reload_completed" 6805 { 6806 switch (which_alternative) 6807 { 6808 case 0: 6809 return avr_out_tstpsi (insn, operands, NULL); 6810 6811 case 1: 6812 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1"; 6813 6814 case 2: 6815 return reg_unused_after (insn, operands[0]) 6816 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)" 6817 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2"; 6818 6819 case 3: 6820 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2"; 6821 } 6822 6823 return avr_out_compare (insn, operands, NULL); 6824 } 6825 [(set_attr "length" "3,3,5,6,3,7") 6826 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")]) 6827 6828 ;; "*cmpsi" 6829 ;; "*cmpsq" "*cmpusq" 6830 ;; "*cmpsa" "*cmpusa" 6831 (define_insn "*cmp<mode>" 6832 [(set (reg:CC REG_CC) 6833 (compare:CC (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r") 6834 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn"))) 6835 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))] 6836 "reload_completed" 6837 { 6838 if (0 == which_alternative) 6839 return avr_out_tstsi (insn, operands, NULL); 6840 else if (1 == which_alternative) 6841 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1"; 6842 6843 return avr_out_compare (insn, operands, NULL); 6844 } 6845 [(set_attr "length" "4,4,4,5,8") 6846 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")]) 6847 6848 6849 ;; A helper for avr_pass_ifelse::avr_rest_of_handle_ifelse(). 6850 (define_expand "gen_compare<mode>" 6851 [(parallel [(set (reg:CC REG_CC) 6852 (compare:CC (match_operand:HISI 0 "register_operand") 6853 (match_operand:HISI 1 "const_int_operand"))) 6854 (clobber (match_operand:QI 2 "scratch_operand"))])]) 6855 6856 (define_expand "gen_move_clobbercc" 6857 [(parallel [(set (match_operand 0) 6858 (match_operand 1)) 6859 (clobber (reg:CC REG_CC))])]) 6860 6861 ;; ---------------------------------------------------------------------- 6862 ;; JUMP INSTRUCTIONS 6863 ;; ---------------------------------------------------------------------- 6864 ;; Conditional jump instructions 6865 6866 (define_expand "cbranch<mode>4" 6867 [(set (pc) 6868 (if_then_else (match_operator 0 "ordered_comparison_operator" 6869 [(match_operand:ALL1 1 "register_operand") 6870 (match_operand:ALL1 2 "nonmemory_operand")]) 6871 (label_ref (match_operand 3)) 6872 (pc)))] 6873 "" 6874 { 6875 int icode = (int) GET_CODE (operands[0]); 6876 6877 targetm.canonicalize_comparison (&icode, &operands[1], &operands[2], false); 6878 PUT_CODE (operands[0], (enum rtx_code) icode); 6879 }) 6880 6881 (define_expand "cbranch<mode>4" 6882 [(parallel 6883 [(set (pc) 6884 (if_then_else (match_operator 0 "ordered_comparison_operator" 6885 [(match_operand:ALL234 1 "register_operand") 6886 (match_operand:ALL234 2 "nonmemory_operand")]) 6887 (label_ref (match_operand 3)) 6888 (pc))) 6889 (clobber (match_scratch:QI 4))])] 6890 "" 6891 { 6892 int icode = (int) GET_CODE (operands[0]); 6893 6894 targetm.canonicalize_comparison (&icode, &operands[1], &operands[2], false); 6895 PUT_CODE (operands[0], (enum rtx_code) icode); 6896 }) 6897 6898 6899 ;; "cbranchqi4_insn" 6900 ;; "cbranchqq4_insn" "cbranchuqq4_insn" 6901 (define_insn_and_split "cbranch<mode>4_insn" 6902 [(set (pc) 6903 (if_then_else (match_operator 0 "ordered_comparison_operator" 6904 [(match_operand:ALL1 1 "register_operand" "r ,r,d") 6905 (match_operand:ALL1 2 "nonmemory_operand" "Y00,r,i")]) 6906 (label_ref (match_operand 3)) 6907 (pc)))] 6908 "" 6909 "#" 6910 "reload_completed" 6911 [(set (reg:CC REG_CC) 6912 (compare:CC (match_dup 1) (match_dup 2))) 6913 (set (pc) 6914 (if_then_else (match_op_dup 0 6915 [(reg:CC REG_CC) (const_int 0)]) 6916 (label_ref (match_dup 3)) 6917 (pc)))]) 6918 6919 ;; "cbranchsi4_insn" 6920 ;; "cbranchsq4_insn" "cbranchusq4_insn" "cbranchsa4_insn" "cbranchusa4_insn" 6921 (define_insn_and_split "cbranch<mode>4_insn" 6922 [(set (pc) 6923 (if_then_else 6924 (match_operator 0 "ordered_comparison_operator" 6925 [(match_operand:ALL4 1 "register_operand" "r ,r,d,r ,r") 6926 (match_operand:ALL4 2 "nonmemory_operand" "Y00,r,M,M ,n Ynn")]) 6927 (label_ref (match_operand 3)) 6928 (pc))) 6929 (clobber (match_scratch:QI 4 "=X ,X,X,&d,&d"))] 6930 "" 6931 "#" 6932 "reload_completed" 6933 [(parallel [(set (reg:CC REG_CC) 6934 (compare:CC (match_dup 1) (match_dup 2))) 6935 (clobber (match_dup 4))]) 6936 (set (pc) 6937 (if_then_else (match_op_dup 0 6938 [(reg:CC REG_CC) (const_int 0)]) 6939 (label_ref (match_dup 3)) 6940 (pc)))]) 6941 6942 ;; "cbranchpsi4_insn" 6943 (define_insn_and_split "cbranchpsi4_insn" 6944 [(set (pc) 6945 (if_then_else 6946 (match_operator 0 "ordered_comparison_operator" 6947 [(match_operand:PSI 1 "register_operand" "r,r,d ,r ,d,r") 6948 (match_operand:PSI 2 "nonmemory_operand" "L,r,s ,s ,M,n")]) 6949 (label_ref (match_operand 3)) 6950 (pc))) 6951 (clobber (match_scratch:QI 4 "=X,X,&d,&d,X,&d"))] 6952 "" 6953 "#" 6954 "reload_completed" 6955 [(parallel [(set (reg:CC REG_CC) 6956 (compare:CC (match_dup 1) (match_dup 2))) 6957 (clobber (match_dup 4))]) 6958 (set (pc) 6959 (if_then_else (match_op_dup 0 6960 [(reg:CC REG_CC) (const_int 0)]) 6961 (label_ref (match_dup 3)) 6962 (pc)))]) 6963 6964 ;; "cbranchhi4_insn" 6965 ;; "cbranchhq4_insn" "cbranchuhq4_insn" "cbranchha4_insn" "cbranchuha4_insn" 6966 (define_insn_and_split "cbranch<mode>4_insn" 6967 [(set (pc) 6968 (if_then_else 6969 (match_operator 0 "ordered_comparison_operator" 6970 [(match_operand:ALL2 1 "register_operand" "!w ,r ,r,d ,r ,d,r") 6971 (match_operand:ALL2 2 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")]) 6972 (label_ref (match_operand 3)) 6973 (pc))) 6974 (clobber (match_scratch:QI 4 "=X ,X ,X,&d,&d,X,&d"))] 6975 "" 6976 "#" 6977 "reload_completed" 6978 [(parallel [(set (reg:CC REG_CC) 6979 (compare:CC (match_dup 1) (match_dup 2))) 6980 (clobber (match_dup 4))]) 6981 (set (pc) 6982 (if_then_else (match_op_dup 0 6983 [(reg:CC REG_CC) (const_int 0)]) 6984 (label_ref (match_dup 3)) 6985 (pc)))]) 6986 6987 ;; Combiner pattern to compare sign- or zero-extended register against 6988 ;; a wider register, like comparing uint8_t against uint16_t. 6989 (define_insn_and_split "*cbranch<HISI:mode>.<code><QIPSI:mode>.0" 6990 [(set (pc) 6991 (if_then_else (match_operator 0 "ordered_comparison_operator" 6992 [(any_extend:HISI (match_operand:QIPSI 1 "register_operand" "r")) 6993 (match_operand:HISI 2 "register_operand" "r")]) 6994 (label_ref (match_operand 3)) 6995 (pc)))] 6996 "optimize 6997 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)" 6998 "#" 6999 "&& reload_completed" 7000 [; "*cmp<HISI:mode>.<code><QIPSI:mode>.0" 7001 (set (reg:CC REG_CC) 7002 (compare:CC (match_dup 1) 7003 (match_dup 2))) 7004 ; "branch" 7005 (set (pc) 7006 (if_then_else (match_op_dup 0 [(reg:CC REG_CC) 7007 (const_int 0)]) 7008 (label_ref (match_dup 3)) 7009 (pc)))] 7010 { 7011 operands[1] = gen_rtx_<CODE> (<HISI:MODE>mode, operands[1]); 7012 if (difficult_comparison_operator (operands[0], VOIDmode)) 7013 { 7014 PUT_CODE (operands[0], swap_condition (GET_CODE (operands[0]))); 7015 std::swap (operands[1], operands[2]); 7016 } 7017 }) 7018 7019 ;; Same combiner pattern, but with swapped operands. 7020 (define_insn_and_split "*cbranch<HISI:mode>.<code><QIPSI:mode>.0" 7021 [(set (pc) 7022 (if_then_else (match_operator 0 "ordered_comparison_operator" 7023 [(match_operand:HISI 1 "register_operand" "r") 7024 (any_extend:HISI (match_operand:QIPSI 2 "register_operand" "r"))]) 7025 (label_ref (match_operand 3)) 7026 (pc)))] 7027 "optimize 7028 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)" 7029 "#" 7030 "&& reload_completed" 7031 [; "*cmp<HISI:mode>.<code><QIPSI:mode>.0" 7032 (set (reg:CC REG_CC) 7033 (compare:CC (match_dup 1) 7034 (match_dup 2))) 7035 ; "branch" 7036 (set (pc) 7037 (if_then_else (match_op_dup 0 [(reg:CC REG_CC) 7038 (const_int 0)]) 7039 (label_ref (match_dup 3)) 7040 (pc)))] 7041 { 7042 operands[2] = gen_rtx_<CODE> (<HISI:MODE>mode, operands[2]); 7043 if (difficult_comparison_operator (operands[0], VOIDmode)) 7044 { 7045 PUT_CODE (operands[0], swap_condition (GET_CODE (operands[0]))); 7046 std::swap (operands[1], operands[2]); 7047 } 7048 }) 7049 7050 7051 ;; Test a single bit in a QI/HI/SImode register. 7052 ;; Combine will create zero-extract patterns for single-bit tests. 7053 ;; Permit any mode in source pattern by using VOIDmode. 7054 7055 (define_insn_and_split "*sbrx_branch<mode>_split" 7056 [(set (pc) 7057 (if_then_else 7058 (match_operator 0 "eqne_operator" 7059 [(zero_extract:QIDI 7060 (match_operand:VOID 1 "register_operand" "r") 7061 (const_int 1) 7062 (match_operand 2 "const_int_operand" "n")) 7063 (const_int 0)]) 7064 (label_ref (match_operand 3 "" "")) 7065 (pc)))] 7066 "" 7067 "#" 7068 "&& reload_completed" 7069 [(parallel [(set (pc) 7070 (if_then_else 7071 (match_op_dup 0 7072 [(zero_extract:QIDI 7073 (match_dup 1) 7074 (const_int 1) 7075 (match_dup 2)) 7076 (const_int 0)]) 7077 (label_ref (match_dup 3)) 7078 (pc))) 7079 (clobber (reg:CC REG_CC))])]) 7080 7081 (define_insn "*sbrx_branch<mode>" 7082 [(set (pc) 7083 (if_then_else 7084 (match_operator 0 "eqne_operator" 7085 [(zero_extract:QIDI 7086 (match_operand:VOID 1 "register_operand" "r") 7087 (const_int 1) 7088 (match_operand 2 "const_int_operand" "n")) 7089 (const_int 0)]) 7090 (label_ref (match_operand 3 "" "")) 7091 (pc))) 7092 (clobber (reg:CC REG_CC))] 7093 "reload_completed" 7094 { 7095 return avr_out_sbxx_branch (insn, operands); 7096 } 7097 [(set (attr "length") 7098 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 7099 (le (minus (pc) (match_dup 3)) (const_int 2046))) 7100 (const_int 2) 7101 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7102 (const_int 2) 7103 (const_int 4))))]) 7104 7105 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns 7106 ;; or for text peepholes. 7107 ;; Fixme - bitwise Mask will not work for DImode 7108 7109 (define_insn_and_split "*sbrx_and_branch<mode>_split" 7110 [(set (pc) 7111 (if_then_else 7112 (match_operator 0 "eqne_operator" 7113 [(and:QISI 7114 (match_operand:QISI 1 "register_operand" "r") 7115 (match_operand:QISI 2 "single_one_operand" "n")) 7116 (const_int 0)]) 7117 (label_ref (match_operand 3 "" "")) 7118 (pc)))] 7119 "" 7120 "#" 7121 "&& reload_completed" 7122 [(parallel [(set (pc) 7123 (if_then_else (match_op_dup 0 [(and:QISI (match_dup 1) 7124 (match_dup 2)) 7125 (const_int 0)]) 7126 (label_ref (match_dup 3)) 7127 (pc))) 7128 (clobber (reg:CC REG_CC))])]) 7129 7130 (define_insn "*sbrx_and_branch<mode>" 7131 [(set (pc) 7132 (if_then_else 7133 (match_operator 0 "eqne_operator" 7134 [(and:QISI 7135 (match_operand:QISI 1 "register_operand" "r") 7136 (match_operand:QISI 2 "single_one_operand" "n")) 7137 (const_int 0)]) 7138 (label_ref (match_operand 3 "" "")) 7139 (pc))) 7140 (clobber (reg:CC REG_CC))] 7141 "reload_completed" 7142 { 7143 HOST_WIDE_INT bitnumber; 7144 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2])); 7145 operands[2] = GEN_INT (bitnumber); 7146 return avr_out_sbxx_branch (insn, operands); 7147 } 7148 [(set (attr "length") 7149 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 7150 (le (minus (pc) (match_dup 3)) (const_int 2046))) 7151 (const_int 2) 7152 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7153 (const_int 2) 7154 (const_int 4))))]) 7155 7156 7157 ;; Convert sign tests to bit 7 tests that match the above insns. 7158 (define_peephole2 ; "*sbrx_branch<mode>" 7159 [(set (reg:CC REG_CC) 7160 (compare:CC (match_operand:ALLs1 0 "register_operand") 7161 (match_operand:ALLs1 1 "const0_operand"))) 7162 (set (pc) 7163 (if_then_else (gelt (reg:CC REG_CC) 7164 (const_int 0)) 7165 (label_ref (match_operand 2)) 7166 (pc)))] 7167 "peep2_regno_dead_p (2, REG_CC)" 7168 [(parallel [(set (pc) 7169 (if_then_else (<gelt_eqne> (zero_extract:HI (match_dup 0) 7170 (const_int 1) 7171 (match_dup 1)) 7172 (const_int 0)) 7173 (label_ref (match_dup 2)) 7174 (pc))) 7175 (clobber (reg:CC REG_CC))])] 7176 { 7177 operands[0] = avr_to_int_mode (operands[0]); 7178 operands[1] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); 7179 }) 7180 7181 ;; Convert sign tests to bit 15/23/31 tests that match the above insns. 7182 (define_peephole2 ; "*sbrx_branch<mode>" 7183 [(parallel [(set (reg:CC REG_CC) 7184 (compare:CC (match_operand:ALLs234 0 "register_operand") 7185 (match_operand:ALLs234 1 "const0_operand"))) 7186 (clobber (match_operand:QI 3 "scratch_operand"))]) 7187 (set (pc) 7188 (if_then_else (gelt (reg:CC REG_CC) 7189 (const_int 0)) 7190 (label_ref (match_operand 2)) 7191 (pc)))] 7192 "peep2_regno_dead_p (2, REG_CC)" 7193 [(parallel [(set (pc) 7194 (if_then_else (<gelt_eqne> (zero_extract:HI (match_dup 0) 7195 (const_int 1) 7196 (match_dup 1)) 7197 (const_int 0)) 7198 (label_ref (match_dup 2)) 7199 (pc))) 7200 (clobber (reg:CC REG_CC))])] 7201 { 7202 operands[0] = avr_to_int_mode (operands[0]); 7203 operands[1] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); 7204 }) 7205 7206 7207 ;; ************************************************************************ 7208 ;; Implementation of conditional jumps here. 7209 ;; Compare with 0 (test) jumps 7210 ;; ************************************************************************ 7211 7212 (define_insn "branch" 7213 [(set (pc) 7214 (if_then_else (match_operator 1 "simple_comparison_operator" 7215 [(reg:CC REG_CC) 7216 (const_int 0)]) 7217 (label_ref (match_operand 0)) 7218 (pc)))] 7219 "reload_completed" 7220 { 7221 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0); 7222 } 7223 [(set_attr "type" "branch")]) 7224 7225 7226 (define_insn "difficult_branch" 7227 [(set (pc) 7228 (if_then_else (match_operator 1 "difficult_comparison_operator" 7229 [(reg:CC REG_CC) 7230 (const_int 0)]) 7231 (label_ref (match_operand 0 "" "")) 7232 (pc)))] 7233 "reload_completed" 7234 { 7235 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0); 7236 } 7237 [(set_attr "type" "branch1")]) 7238 7239 7240 ;; ************************************************************************** 7241 ;; Unconditional and other jump instructions. 7242 7243 (define_insn "jump" 7244 [(set (pc) 7245 (label_ref (match_operand 0 "" "")))] 7246 "" 7247 { 7248 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1 7249 ? "jmp %x0" 7250 : "rjmp %x0"; 7251 } 7252 [(set (attr "length") 7253 (if_then_else (match_operand 0 "symbol_ref_operand" "") 7254 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7255 (const_int 1) 7256 (const_int 2)) 7257 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047)) 7258 (le (minus (pc) (match_dup 0)) (const_int 2047))) 7259 (const_int 1) 7260 (const_int 2))))]) 7261 7262 ;; call 7263 7264 ;; Operand 1 not used on the AVR. 7265 ;; Operand 2 is 1 for tail-call, 0 otherwise. 7266 (define_expand "call" 7267 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "") 7268 (match_operand:HI 1 "general_operand" "")) 7269 (use (const_int 0))])]) 7270 7271 ;; Operand 1 not used on the AVR. 7272 ;; Operand 2 is 1 for tail-call, 0 otherwise. 7273 (define_expand "sibcall" 7274 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "") 7275 (match_operand:HI 1 "general_operand" "")) 7276 (use (const_int 1))])]) 7277 7278 ;; call value 7279 7280 ;; Operand 2 not used on the AVR. 7281 ;; Operand 3 is 1 for tail-call, 0 otherwise. 7282 (define_expand "call_value" 7283 [(parallel[(set (match_operand 0 "register_operand" "") 7284 (call (match_operand:HI 1 "call_insn_operand" "") 7285 (match_operand:HI 2 "general_operand" ""))) 7286 (use (const_int 0))])]) 7287 7288 ;; Operand 2 not used on the AVR. 7289 ;; Operand 3 is 1 for tail-call, 0 otherwise. 7290 (define_expand "sibcall_value" 7291 [(parallel[(set (match_operand 0 "register_operand" "") 7292 (call (match_operand:HI 1 "call_insn_operand" "") 7293 (match_operand:HI 2 "general_operand" ""))) 7294 (use (const_int 1))])]) 7295 7296 (define_insn "call_insn" 7297 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s")) 7298 (match_operand:HI 1 "general_operand" "X,X,X,X")) 7299 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])] 7300 ;; Operand 1 not used on the AVR. 7301 ;; Operand 2 is 1 for tail-call, 0 otherwise. 7302 "" 7303 "@ 7304 %!icall 7305 %~call %x0 7306 %!ijmp 7307 %~jmp %x0" 7308 [(set_attr "length" "1,*,1,*") 7309 (set_attr "adjust_len" "*,call,*,call")]) 7310 7311 (define_insn "call_value_insn" 7312 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r") 7313 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s")) 7314 (match_operand:HI 2 "general_operand" "X,X,X,X"))) 7315 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])] 7316 ;; Operand 2 not used on the AVR. 7317 ;; Operand 3 is 1 for tail-call, 0 otherwise. 7318 "" 7319 "@ 7320 %!icall 7321 %~call %x1 7322 %!ijmp 7323 %~jmp %x1" 7324 [(set_attr "length" "1,*,1,*") 7325 (set_attr "adjust_len" "*,call,*,call")]) 7326 7327 (define_insn "nop" 7328 [(const_int 0)] 7329 "" 7330 "nop" 7331 [(set_attr "length" "1")]) 7332 7333 ; indirect jump 7334 7335 (define_expand "indirect_jump" 7336 [(set (pc) 7337 (match_operand:HI 0 "nonmemory_operand" ""))] 7338 "" 7339 { 7340 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode)) 7341 { 7342 operands[0] = copy_to_mode_reg (HImode, operands[0]); 7343 } 7344 }) 7345 7346 ; indirect jump 7347 (define_insn "*indirect_jump" 7348 [(set (pc) 7349 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))] 7350 "" 7351 "@ 7352 rjmp %x0 7353 jmp %x0 7354 ijmp 7355 push %A0\;push %B0\;ret 7356 eijmp" 7357 [(set_attr "length" "1,2,1,3,1") 7358 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")]) 7359 7360 ;; table jump 7361 ;; For entries in jump table see avr_output_addr_vec. 7362 7363 ;; Table made from 7364 ;; "rjmp .L<n>" instructions for <= 8K devices 7365 ;; ".word gs(.L<n>)" addresses for > 8K devices 7366 (define_insn_and_split "*tablejump_split" 7367 [(set (pc) 7368 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")] 7369 UNSPEC_INDEX_JMP)) 7370 (use (label_ref (match_operand 1 "" ""))) 7371 (clobber (match_dup 0)) 7372 (clobber (const_int 0))] 7373 "!AVR_HAVE_EIJMP_EICALL" 7374 "#" 7375 "&& reload_completed" 7376 [(parallel [(set (pc) 7377 (unspec:HI [(match_dup 0)] 7378 UNSPEC_INDEX_JMP)) 7379 (use (label_ref (match_dup 1))) 7380 (clobber (match_dup 0)) 7381 (clobber (const_int 0)) 7382 (clobber (reg:CC REG_CC))])] 7383 "" 7384 [(set_attr "isa" "rjmp,rjmp,jmp")]) 7385 7386 (define_insn "*tablejump" 7387 [(set (pc) 7388 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")] 7389 UNSPEC_INDEX_JMP)) 7390 (use (label_ref (match_operand 1 "" ""))) 7391 (clobber (match_dup 0)) 7392 (clobber (const_int 0)) 7393 (clobber (reg:CC REG_CC))] 7394 "!AVR_HAVE_EIJMP_EICALL && reload_completed" 7395 "@ 7396 ijmp 7397 push %A0\;push %B0\;ret 7398 jmp __tablejump2__" 7399 [(set_attr "length" "1,3,2") 7400 (set_attr "isa" "rjmp,rjmp,jmp")]) 7401 7402 (define_insn_and_split "*tablejump.3byte-pc_split" 7403 [(set (pc) 7404 (unspec:HI [(reg:HI REG_Z)] 7405 UNSPEC_INDEX_JMP)) 7406 (use (label_ref (match_operand 0 "" ""))) 7407 (clobber (reg:HI REG_Z)) 7408 (clobber (reg:QI 24))] 7409 "AVR_HAVE_EIJMP_EICALL" 7410 "#" 7411 "&& reload_completed" 7412 [(parallel [(set (pc) 7413 (unspec:HI [(reg:HI REG_Z)] 7414 UNSPEC_INDEX_JMP)) 7415 (use (label_ref (match_dup 0))) 7416 (clobber (reg:HI REG_Z)) 7417 (clobber (reg:QI 24)) 7418 (clobber (reg:CC REG_CC))])] 7419 "" 7420 [(set_attr "isa" "eijmp")]) 7421 7422 7423 (define_insn "*tablejump.3byte-pc" 7424 [(set (pc) 7425 (unspec:HI [(reg:HI REG_Z)] 7426 UNSPEC_INDEX_JMP)) 7427 (use (label_ref (match_operand 0 "" ""))) 7428 (clobber (reg:HI REG_Z)) 7429 (clobber (reg:QI 24)) 7430 (clobber (reg:CC REG_CC))] 7431 "AVR_HAVE_EIJMP_EICALL && reload_completed" 7432 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__" 7433 [(set_attr "length" "6") 7434 (set_attr "isa" "eijmp")]) 7435 7436 7437 ;; FIXME: casesi comes up with an SImode switch value $0 which 7438 ;; is quite some overhead because most code would use HI or 7439 ;; even QI. We add an AVR specific pass .avr-casesi which 7440 ;; tries to recover from the superfluous extension to SImode. 7441 ;; 7442 ;; Using "tablejump" could be a way out, but this also does 7443 ;; not perform in a satisfying manner as the middle end will 7444 ;; already multiply the table index by 2. Note that this 7445 ;; multiplication is performed by libgcc's __tablejump2__. 7446 ;; The multiplication there, however, runs *after* the table 7447 ;; start (a byte address) has been added, not before it like 7448 ;; "tablejump" will do. 7449 ;; 7450 ;; The preferred solution would be to let the middle ends pass 7451 ;; down information on the index as an additional casesi operand. 7452 ;; 7453 ;; If this expander is changed, you'll likely have to go through 7454 ;; "casesi_<mode>_sequence" (used to recog + extract casesi 7455 ;; sequences in pass .avr-casesi) and propagate all adjustments 7456 ;; also to that pattern and the code of the extra pass. 7457 7458 (define_expand "casesi" 7459 [(parallel [(set (match_dup 5) 7460 (plus:SI (match_operand:SI 0 "register_operand") 7461 (match_operand:SI 1 "const_int_operand"))) 7462 (clobber (scratch:QI))]) 7463 7464 (parallel [(set (pc) 7465 (if_then_else (gtu (match_dup 5) 7466 (match_operand:SI 2 "const_int_operand")) 7467 (label_ref (match_operand 4)) 7468 (pc))) 7469 (clobber (scratch:QI))]) 7470 7471 (set (match_dup 7) 7472 (match_dup 6)) 7473 7474 (parallel [(set (pc) 7475 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP)) 7476 (use (label_ref (match_dup 3))) 7477 (clobber (match_dup 7)) 7478 (clobber (match_dup 8))])] 7479 "" 7480 { 7481 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode); 7482 operands[5] = gen_reg_rtx (SImode); 7483 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0); 7484 7485 if (AVR_HAVE_EIJMP_EICALL) 7486 { 7487 operands[7] = gen_rtx_REG (HImode, REG_Z); 7488 operands[8] = all_regs_rtx[24]; 7489 } 7490 else 7491 { 7492 operands[6] = gen_rtx_PLUS (HImode, operands[6], 7493 gen_rtx_LABEL_REF (VOIDmode, operands[3])); 7494 operands[7] = gen_reg_rtx (HImode); 7495 operands[8] = const0_rtx; 7496 } 7497 }) 7498 7499 7500 ;; This insn is used only for easy operand extraction. 7501 ;; The elements must match an extension to SImode plus 7502 ;; a sequence generated by casesi above. 7503 7504 ;; "casesi_qi_sequence" 7505 ;; "casesi_hi_sequence" 7506 (define_insn "casesi_<mode>_sequence" 7507 [(set (match_operand:SI 0 "register_operand") 7508 (match_operator:SI 9 "extend_operator" 7509 [(match_operand:QIHI 10 "register_operand")])) 7510 7511 ;; What follows is a matcher for code from casesi. 7512 ;; We keep the same operand numbering (except for $9 and $10 7513 ;; which don't appear in casesi). 7514 (parallel [(set (match_operand:SI 5 "register_operand") 7515 (plus:SI (match_dup 0) 7516 (match_operand:SI 1 "const_int_operand"))) 7517 (clobber (scratch:QI))]) 7518 7519 (parallel [(set (pc) 7520 (if_then_else (gtu (match_dup 5) 7521 (match_operand:SI 2 "const_int_operand")) 7522 (label_ref (match_operand 4)) 7523 (pc))) 7524 (clobber (scratch:QI))]) 7525 7526 (set (match_operand:HI 7 "register_operand") 7527 (match_operand:HI 6)) 7528 7529 (parallel [(set (pc) 7530 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP)) 7531 (use (label_ref (match_operand 3))) 7532 (clobber (match_dup 7)) 7533 (clobber (match_operand:QI 8))])] 7534 "optimize 7535 && avr_casei_sequence_check_operands (operands)" 7536 { gcc_unreachable(); } 7537 ) 7538 7539 7540 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 7541 ;; Clear/set/test a single bit in I/O address space. 7542 7543 (define_insn "*cbi" 7544 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i")) 7545 (and:QI (mem:QI (match_dup 0)) 7546 (match_operand:QI 1 "single_zero_operand" "n")))] 7547 "" 7548 { 7549 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); 7550 return "cbi %i0,%2"; 7551 } 7552 [(set_attr "length" "1")]) 7553 7554 (define_insn "*sbi" 7555 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i")) 7556 (ior:QI (mem:QI (match_dup 0)) 7557 (match_operand:QI 1 "single_one_operand" "n")))] 7558 "" 7559 { 7560 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); 7561 return "sbi %i0,%2"; 7562 } 7563 [(set_attr "length" "1")]) 7564 7565 ;; Lower half of the I/O space - use sbic/sbis directly. 7566 (define_insn_and_split "*sbix_branch_split" 7567 [(set (pc) 7568 (if_then_else 7569 (match_operator 0 "eqne_operator" 7570 [(zero_extract:QIHI 7571 (mem:QI (match_operand 1 "low_io_address_operand" "i")) 7572 (const_int 1) 7573 (match_operand 2 "const_int_operand" "n")) 7574 (const_int 0)]) 7575 (label_ref (match_operand 3 "" "")) 7576 (pc)))] 7577 "" 7578 "#" 7579 "&& reload_completed" 7580 [(parallel [(set (pc) 7581 (if_then_else 7582 (match_operator 0 "eqne_operator" 7583 [(zero_extract:QIHI 7584 (mem:QI (match_dup 1)) 7585 (const_int 1) 7586 (match_dup 2)) 7587 (const_int 0)]) 7588 (label_ref (match_dup 3)) 7589 (pc))) 7590 (clobber (reg:CC REG_CC))])]) 7591 7592 (define_insn "*sbix_branch" 7593 [(set (pc) 7594 (if_then_else 7595 (match_operator 0 "eqne_operator" 7596 [(zero_extract:QIHI 7597 (mem:QI (match_operand 1 "low_io_address_operand" "i")) 7598 (const_int 1) 7599 (match_operand 2 "const_int_operand" "n")) 7600 (const_int 0)]) 7601 (label_ref (match_operand 3 "" "")) 7602 (pc))) 7603 (clobber (reg:CC REG_CC))] 7604 "reload_completed" 7605 { 7606 return avr_out_sbxx_branch (insn, operands); 7607 } 7608 [(set (attr "length") 7609 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 7610 (le (minus (pc) (match_dup 3)) (const_int 2046))) 7611 (const_int 2) 7612 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7613 (const_int 2) 7614 (const_int 4))))]) 7615 7616 ;; Tests of bit 7 are pessimized to sign tests, so we need this too... 7617 (define_insn_and_split "*sbix_branch_bit7_split" 7618 [(set (pc) 7619 (if_then_else 7620 (match_operator 0 "gelt_operator" 7621 [(mem:QI (match_operand 1 "low_io_address_operand" "i")) 7622 (const_int 0)]) 7623 (label_ref (match_operand 2 "" "")) 7624 (pc)))] 7625 "" 7626 "#" 7627 "&& reload_completed" 7628 [(parallel [(set (pc) 7629 (if_then_else 7630 (match_operator 0 "gelt_operator" 7631 [(mem:QI (match_dup 1)) 7632 (const_int 0)]) 7633 (label_ref (match_dup 2)) 7634 (pc))) 7635 (clobber (reg:CC REG_CC))])]) 7636 7637 (define_insn "*sbix_branch_bit7" 7638 [(set (pc) 7639 (if_then_else 7640 (match_operator 0 "gelt_operator" 7641 [(mem:QI (match_operand 1 "low_io_address_operand" "i")) 7642 (const_int 0)]) 7643 (label_ref (match_operand 2 "" "")) 7644 (pc))) 7645 (clobber (reg:CC REG_CC))] 7646 "reload_completed" 7647 { 7648 operands[3] = operands[2]; 7649 operands[2] = GEN_INT (7); 7650 return avr_out_sbxx_branch (insn, operands); 7651 } 7652 [(set (attr "length") 7653 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046)) 7654 (le (minus (pc) (match_dup 2)) (const_int 2046))) 7655 (const_int 2) 7656 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7657 (const_int 2) 7658 (const_int 4))))]) 7659 7660 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs. 7661 (define_insn_and_split "*sbix_branch_tmp_split" 7662 [(set (pc) 7663 (if_then_else 7664 (match_operator 0 "eqne_operator" 7665 [(zero_extract:QIHI 7666 (mem:QI (match_operand 1 "high_io_address_operand" "n")) 7667 (const_int 1) 7668 (match_operand 2 "const_int_operand" "n")) 7669 (const_int 0)]) 7670 (label_ref (match_operand 3 "" "")) 7671 (pc)))] 7672 "" 7673 "#" 7674 "&& reload_completed" 7675 [(parallel [(set (pc) 7676 (if_then_else 7677 (match_operator 0 "eqne_operator" 7678 [(zero_extract:QIHI 7679 (mem:QI (match_dup 1)) 7680 (const_int 1) 7681 (match_dup 2)) 7682 (const_int 0)]) 7683 (label_ref (match_dup 3)) 7684 (pc))) 7685 (clobber (reg:CC REG_CC))])]) 7686 7687 (define_insn "*sbix_branch_tmp" 7688 [(set (pc) 7689 (if_then_else 7690 (match_operator 0 "eqne_operator" 7691 [(zero_extract:QIHI 7692 (mem:QI (match_operand 1 "high_io_address_operand" "n")) 7693 (const_int 1) 7694 (match_operand 2 "const_int_operand" "n")) 7695 (const_int 0)]) 7696 (label_ref (match_operand 3 "" "")) 7697 (pc))) 7698 (clobber (reg:CC REG_CC))] 7699 "reload_completed" 7700 { 7701 return avr_out_sbxx_branch (insn, operands); 7702 } 7703 [(set (attr "length") 7704 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 7705 (le (minus (pc) (match_dup 3)) (const_int 2045))) 7706 (const_int 3) 7707 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7708 (const_int 3) 7709 (const_int 5))))]) 7710 7711 (define_insn_and_split "*sbix_branch_tmp_bit7_split" 7712 [(set (pc) 7713 (if_then_else 7714 (match_operator 0 "gelt_operator" 7715 [(mem:QI (match_operand 1 "high_io_address_operand" "n")) 7716 (const_int 0)]) 7717 (label_ref (match_operand 2 "" "")) 7718 (pc)))] 7719 "" 7720 "#" 7721 "&& reload_completed" 7722 [(parallel [(set (pc) 7723 (if_then_else 7724 (match_operator 0 "gelt_operator" 7725 [(mem:QI (match_dup 1)) 7726 (const_int 0)]) 7727 (label_ref (match_dup 2)) 7728 (pc))) 7729 (clobber (reg:CC REG_CC))])]) 7730 7731 (define_insn "*sbix_branch_tmp_bit7" 7732 [(set (pc) 7733 (if_then_else 7734 (match_operator 0 "gelt_operator" 7735 [(mem:QI (match_operand 1 "high_io_address_operand" "n")) 7736 (const_int 0)]) 7737 (label_ref (match_operand 2 "" "")) 7738 (pc))) 7739 (clobber (reg:CC REG_CC))] 7740 "reload_completed" 7741 { 7742 operands[3] = operands[2]; 7743 operands[2] = GEN_INT (7); 7744 return avr_out_sbxx_branch (insn, operands); 7745 } 7746 [(set (attr "length") 7747 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046)) 7748 (le (minus (pc) (match_dup 2)) (const_int 2045))) 7749 (const_int 3) 7750 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 7751 (const_int 3) 7752 (const_int 5))))]) 7753 7754 ;; ************************* Peepholes ******************************** 7755 7756 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber" 7757 [(parallel [(set (match_operand:SI 0 "d_register_operand" "") 7758 (plus:SI (match_dup 0) 7759 (const_int -1))) 7760 (clobber (scratch:QI)) 7761 (clobber (reg:CC REG_CC))]) 7762 (parallel [(set (reg:CC REG_CC) 7763 (compare:CC (match_dup 0) 7764 (const_int -1))) 7765 (clobber (match_operand:QI 1 "scratch_or_d_register_operand"))]) 7766 (set (pc) 7767 (if_then_else (eqne (reg:CC REG_CC) 7768 (const_int 0)) 7769 (label_ref (match_operand 2)) 7770 (pc)))] 7771 "dead_or_set_regno_p (insn, REG_CC)" 7772 { 7773 if (avr_adiw_reg_p (operands[0])) 7774 output_asm_insn ("sbiw %0,1" CR_TAB 7775 "sbc %C0,__zero_reg__" CR_TAB 7776 "sbc %D0,__zero_reg__", operands); 7777 else 7778 output_asm_insn ("subi %A0,1" CR_TAB 7779 "sbc %B0,__zero_reg__" CR_TAB 7780 "sbc %C0,__zero_reg__" CR_TAB 7781 "sbc %D0,__zero_reg__", operands); 7782 7783 int jump_mode = avr_jump_mode (operands[2], insn, 3 - avr_adiw_reg_p (operands[0])); 7784 const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 7785 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 7786 7787 switch (jump_mode) 7788 { 7789 case 1: return "%1 %2"; 7790 case 2: return "%1 .+2\;rjmp %2"; 7791 case 3: return "%1 .+4\;jmp %2"; 7792 } 7793 7794 gcc_unreachable(); 7795 return ""; 7796 }) 7797 7798 (define_peephole ; "*dec-and-branchhi!=-1" 7799 [(parallel [(set (match_operand:HI 0 "d_register_operand" "") 7800 (plus:HI (match_dup 0) 7801 (const_int -1))) 7802 (clobber (reg:CC REG_CC))]) 7803 (parallel [(set (reg:CC REG_CC) 7804 (compare:CC (match_dup 0) 7805 (const_int -1))) 7806 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 7807 (set (pc) 7808 (if_then_else (eqne (reg:CC REG_CC) 7809 (const_int 0)) 7810 (label_ref (match_operand 2)) 7811 (pc)))] 7812 "dead_or_set_regno_p (insn, REG_CC)" 7813 { 7814 if (avr_adiw_reg_p (operands[0])) 7815 output_asm_insn ("sbiw %0,1", operands); 7816 else 7817 output_asm_insn ("subi %A0,1" CR_TAB 7818 "sbc %B0,__zero_reg__", operands); 7819 7820 int jump_mode = avr_jump_mode (operands[2], insn, 1 - avr_adiw_reg_p (operands[0])); 7821 const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 7822 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 7823 7824 switch (jump_mode) 7825 { 7826 case 1: return "%1 %2"; 7827 case 2: return "%1 .+2\;rjmp %2"; 7828 case 3: return "%1 .+4\;jmp %2"; 7829 } 7830 7831 gcc_unreachable(); 7832 return ""; 7833 }) 7834 7835 ;; Same as above but with clobber flavour of addhi3 7836 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber" 7837 [(parallel [(set (match_operand:HI 0 "d_register_operand" "") 7838 (plus:HI (match_dup 0) 7839 (const_int -1))) 7840 (clobber (scratch:QI)) 7841 (clobber (reg:CC REG_CC))]) 7842 (parallel [(set (reg:CC REG_CC) 7843 (compare:CC (match_dup 0) 7844 (const_int -1))) 7845 (clobber (match_operand:QI 1 "scratch_or_d_register_operand"))]) 7846 (set (pc) 7847 (if_then_else (eqne (reg:CC REG_CC) 7848 (const_int 0)) 7849 (label_ref (match_operand 2)) 7850 (pc)))] 7851 "dead_or_set_regno_p (insn, REG_CC)" 7852 { 7853 if (avr_adiw_reg_p (operands[0])) 7854 output_asm_insn ("sbiw %0,1", operands); 7855 else 7856 output_asm_insn ("subi %A0,1" CR_TAB 7857 "sbc %B0,__zero_reg__", operands); 7858 7859 int jump_mode = avr_jump_mode (operands[2], insn, 1 - avr_adiw_reg_p (operands[0])); 7860 const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 7861 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 7862 7863 switch (jump_mode) 7864 { 7865 case 1: return "%1 %2"; 7866 case 2: return "%1 .+2\;rjmp %2"; 7867 case 3: return "%1 .+4\;jmp %2"; 7868 } 7869 7870 gcc_unreachable(); 7871 return ""; 7872 }) 7873 7874 ;; Same as above but with clobber flavour of addhi3 7875 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber" 7876 [(parallel [(set (match_operand:HI 0 "l_register_operand" "") 7877 (plus:HI (match_dup 0) 7878 (const_int -1))) 7879 (clobber (match_operand:QI 3 "d_register_operand" "")) 7880 (clobber (reg:CC REG_CC))]) 7881 (parallel [(set (reg:CC REG_CC) 7882 (compare:CC (match_dup 0) 7883 (const_int -1))) 7884 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 7885 (set (pc) 7886 (if_then_else (eqne (reg:CC REG_CC) 7887 (const_int 0)) 7888 (label_ref (match_operand 2)) 7889 (pc)))] 7890 "dead_or_set_regno_p (insn, REG_CC)" 7891 { 7892 output_asm_insn ("ldi %3,1" CR_TAB 7893 "sub %A0,%3" CR_TAB 7894 "sbc %B0,__zero_reg__", operands); 7895 7896 int jump_mode = avr_jump_mode (operands[2], insn, 2); 7897 const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 7898 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 7899 7900 switch (jump_mode) 7901 { 7902 case 1: return "%1 %2"; 7903 case 2: return "%1 .+2\;rjmp %2"; 7904 case 3: return "%1 .+4\;jmp %2"; 7905 } 7906 7907 gcc_unreachable(); 7908 return ""; 7909 }) 7910 7911 (define_peephole ; "*dec-and-branchqi!=-1" 7912 [(parallel [(set (match_operand:QI 0 "d_register_operand" "") 7913 (plus:QI (match_dup 0) 7914 (const_int -1))) 7915 (clobber (reg:CC REG_CC))]) 7916 (set (reg:CC REG_CC) 7917 (compare:CC (match_dup 0) 7918 (const_int -1))) 7919 (set (pc) 7920 (if_then_else (eqne (reg:CC REG_CC) 7921 (const_int 0)) 7922 (label_ref (match_operand 1)) 7923 (pc)))] 7924 "dead_or_set_regno_p (insn, REG_CC)" 7925 { 7926 output_asm_insn ("subi %A0,1", operands); 7927 7928 int jump_mode = avr_jump_mode (operands[1], insn); 7929 const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 7930 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op); 7931 7932 switch (jump_mode) 7933 { 7934 case 1: return "%0 %1"; 7935 case 2: return "%0 .+2\;rjmp %1"; 7936 case 3: return "%0 .+4\;jmp %1"; 7937 } 7938 7939 gcc_unreachable(); 7940 return ""; 7941 }) 7942 7943 7944 (define_peephole ; "*cpse.eq" 7945 [(set (reg:CC REG_CC) 7946 (compare:CC (match_operand:ALL1 1 "register_operand" "r,r") 7947 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00"))) 7948 (set (pc) 7949 (if_then_else (eq (reg:CC REG_CC) 7950 (const_int 0)) 7951 (label_ref (match_operand 0)) 7952 (pc)))] 7953 "jump_over_one_insn_p (insn, operands[0]) 7954 && dead_or_set_regno_p (insn, REG_CC)" 7955 "@ 7956 cpse %1,%2 7957 cpse %1,__zero_reg__") 7958 7959 ;; This peephole avoids code like 7960 ;; 7961 ;; TST Rn ; cmpqi3 7962 ;; BREQ .+2 ; branch 7963 ;; RJMP .Lm 7964 ;; 7965 ;; Notice that the peephole is always shorter than cmpqi + branch. 7966 ;; The reason to write it as peephole is that sequences like 7967 ;; 7968 ;; AND Rm, Rn 7969 ;; BRNE .La 7970 ;; 7971 ;; shall not be superseeded. With a respective combine pattern 7972 ;; the latter sequence would be 7973 ;; 7974 ;; AND Rm, Rn 7975 ;; CPSE Rm, __zero_reg__ 7976 ;; RJMP .La 7977 ;; 7978 ;; and thus longer and slower and not easy to be rolled back. 7979 7980 (define_peephole ; "*cpse.ne" 7981 [(set (reg:CC REG_CC) 7982 (compare:CC (match_operand:ALL1 1 "register_operand") 7983 (match_operand:ALL1 2 "reg_or_0_operand"))) 7984 (set (pc) 7985 (if_then_else (ne (reg:CC REG_CC) 7986 (const_int 0)) 7987 (label_ref (match_operand 0)) 7988 (pc)))] 7989 "(!AVR_HAVE_JMP_CALL 7990 || !TARGET_SKIP_BUG) 7991 && dead_or_set_regno_p (insn, REG_CC)" 7992 { 7993 if (operands[2] == CONST0_RTX (<MODE>mode)) 7994 operands[2] = zero_reg_rtx; 7995 7996 return 3 == avr_jump_mode (operands[0], insn) 7997 ? "cpse %1,%2\;jmp %0" 7998 : "cpse %1,%2\;rjmp %0"; 7999 }) 8000 8001 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp 8002 ;;prologue/epilogue support instructions 8003 8004 (define_insn "popqi" 8005 [(set (match_operand:QI 0 "register_operand" "=r") 8006 (mem:QI (pre_inc:HI (reg:HI REG_SP))))] 8007 "" 8008 "pop %0" 8009 [(set_attr "length" "1")]) 8010 8011 ;; Enable Interrupts 8012 (define_expand "enable_interrupt" 8013 [(clobber (const_int 0))] 8014 "" 8015 { 8016 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8017 MEM_VOLATILE_P (mem) = 1; 8018 emit_insn (gen_cli_sei (const1_rtx, mem)); 8019 DONE; 8020 }) 8021 8022 ;; Disable Interrupts 8023 (define_expand "disable_interrupt" 8024 [(clobber (const_int 0))] 8025 "" 8026 { 8027 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8028 MEM_VOLATILE_P (mem) = 1; 8029 emit_insn (gen_cli_sei (const0_rtx, mem)); 8030 DONE; 8031 }) 8032 8033 (define_insn "cli_sei" 8034 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")] 8035 UNSPECV_ENABLE_IRQS) 8036 (set (match_operand:BLK 1 "" "") 8037 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))] 8038 "" 8039 "@ 8040 cli 8041 sei" 8042 [(set_attr "length" "1")]) 8043 8044 ;; Library prologue saves 8045 (define_insn "call_prologue_saves" 8046 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES) 8047 (match_operand:HI 0 "immediate_operand" "i,i") 8048 (set (reg:HI REG_SP) 8049 (minus:HI (reg:HI REG_SP) 8050 (match_operand:HI 1 "immediate_operand" "i,i"))) 8051 (use (reg:HI REG_X)) 8052 (clobber (reg:HI REG_Z)) 8053 (clobber (reg:CC REG_CC))] 8054 "" 8055 "ldi r30,lo8(gs(1f)) 8056 ldi r31,hi8(gs(1f)) 8057 %~jmp __prologue_saves__+((18 - %0) * 2) 8058 1:" 8059 [(set_attr "length" "5,6") 8060 (set_attr "isa" "rjmp,jmp")]) 8061 8062 ; epilogue restores using library 8063 (define_insn "epilogue_restores" 8064 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES) 8065 (set (reg:HI REG_Y) 8066 (plus:HI (reg:HI REG_Y) 8067 (match_operand:HI 0 "immediate_operand" "i,i"))) 8068 (set (reg:HI REG_SP) 8069 (plus:HI (reg:HI REG_Y) 8070 (match_dup 0))) 8071 (clobber (reg:QI REG_Z)) 8072 (clobber (reg:CC REG_CC))] 8073 "" 8074 "ldi r30, lo8(%0) 8075 %~jmp __epilogue_restores__ + ((18 - %0) * 2)" 8076 [(set_attr "length" "2,3") 8077 (set_attr "isa" "rjmp,jmp")]) 8078 8079 8080 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue 8081 ;; $1 = Register as printed by chunk 0 (Done) in final postscan. 8082 (define_expand "gasisr" 8083 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand") 8084 (match_operand:QI 1 "const_int_operand")] 8085 UNSPECV_GASISR) 8086 (set (reg:HI REG_SP) 8087 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR)) 8088 (set (match_dup 2) 8089 (unspec_volatile:BLK [(match_dup 2)] 8090 UNSPECV_MEMORY_BARRIER)) 8091 (clobber (reg:CC REG_CC))])] 8092 "avr_gasisr_prologues" 8093 { 8094 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8095 MEM_VOLATILE_P (operands[2]) = 1; 8096 }) 8097 8098 (define_insn "*gasisr" 8099 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K") 8100 (match_operand:QI 1 "const_int_operand" "n,n")] 8101 UNSPECV_GASISR) 8102 (set (reg:HI REG_SP) 8103 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR)) 8104 (set (match_operand:BLK 2) 8105 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER)) 8106 (clobber (reg:CC REG_CC))] 8107 "avr_gasisr_prologues" 8108 "__gcc_isr %0" 8109 [(set_attr "length" "6,5")]) 8110 8111 8112 ; return 8113 (define_insn "return" 8114 [(return)] 8115 "reload_completed && avr_simple_epilogue ()" 8116 "ret" 8117 [(set_attr "length" "1")]) 8118 8119 (define_insn "return_from_epilogue" 8120 [(return)] 8121 "reload_completed 8122 && cfun->machine 8123 && !(cfun->machine->is_interrupt || cfun->machine->is_signal) 8124 && !cfun->machine->is_naked" 8125 "ret" 8126 [(set_attr "length" "1")]) 8127 8128 (define_insn "return_from_interrupt_epilogue" 8129 [(return)] 8130 "reload_completed 8131 && cfun->machine 8132 && (cfun->machine->is_interrupt || cfun->machine->is_signal) 8133 && !cfun->machine->is_naked" 8134 "reti" 8135 [(set_attr "length" "1")]) 8136 8137 (define_insn "return_from_naked_epilogue" 8138 [(return)] 8139 "reload_completed 8140 && cfun->machine 8141 && cfun->machine->is_naked" 8142 "" 8143 [(set_attr "length" "0")]) 8144 8145 (define_expand "prologue" 8146 [(const_int 0)] 8147 "" 8148 { 8149 avr_expand_prologue (); 8150 DONE; 8151 }) 8152 8153 (define_expand "epilogue" 8154 [(const_int 0)] 8155 "" 8156 { 8157 avr_expand_epilogue (false /* sibcall_p */); 8158 DONE; 8159 }) 8160 8161 (define_expand "sibcall_epilogue" 8162 [(const_int 0)] 8163 "" 8164 { 8165 avr_expand_epilogue (true /* sibcall_p */); 8166 DONE; 8167 }) 8168 8169 ;; Some instructions resp. instruction sequences available 8170 ;; via builtins. 8171 8172 (define_insn_and_split "delay_cycles_1" 8173 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n") 8174 (const_int 1)] 8175 UNSPECV_DELAY_CYCLES) 8176 (set (match_operand:BLK 1 "" "") 8177 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8178 (clobber (match_scratch:QI 2 "=&d"))] 8179 "" 8180 "#" 8181 "&& reload_completed" 8182 [(parallel [(unspec_volatile [(match_dup 0) 8183 (const_int 1)] 8184 UNSPECV_DELAY_CYCLES) 8185 (set (match_dup 1) 8186 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8187 (clobber (match_dup 2)) 8188 (clobber (reg:CC REG_CC))])]) 8189 8190 (define_insn "*delay_cycles_1" 8191 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n") 8192 (const_int 1)] 8193 UNSPECV_DELAY_CYCLES) 8194 (set (match_operand:BLK 1 "" "") 8195 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8196 (clobber (match_scratch:QI 2 "=&d")) 8197 (clobber (reg:CC REG_CC))] 8198 "reload_completed" 8199 "ldi %2,lo8(%0) 8200 1: dec %2 8201 brne 1b" 8202 [(set_attr "length" "3")]) 8203 8204 (define_insn_and_split "delay_cycles_2" 8205 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n") 8206 (const_int 2)] 8207 UNSPECV_DELAY_CYCLES) 8208 (set (match_operand:BLK 1 "" "") 8209 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8210 (clobber (match_scratch:HI 2 "=&w,&d"))] 8211 "" 8212 "#" 8213 "&& reload_completed" 8214 [(parallel [(unspec_volatile [(match_dup 0) 8215 (const_int 2)] 8216 UNSPECV_DELAY_CYCLES) 8217 (set (match_dup 1) 8218 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8219 (clobber (match_dup 2)) 8220 (clobber (reg:CC REG_CC))])] 8221 "" 8222 [(set_attr "isa" "adiw,no_adiw")]) 8223 8224 (define_insn "*delay_cycles_2" 8225 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n") 8226 (const_int 2)] 8227 UNSPECV_DELAY_CYCLES) 8228 (set (match_operand:BLK 1 "" "") 8229 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8230 (clobber (match_scratch:HI 2 "=&w,&d")) 8231 (clobber (reg:CC REG_CC))] 8232 "reload_completed" 8233 "@ 8234 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b 8235 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b" 8236 [(set_attr "length" "4,5") 8237 (set_attr "isa" "adiw,no_adiw")]) 8238 8239 (define_insn_and_split "delay_cycles_3" 8240 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 8241 (const_int 3)] 8242 UNSPECV_DELAY_CYCLES) 8243 (set (match_operand:BLK 1 "" "") 8244 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8245 (clobber (match_scratch:QI 2 "=&d")) 8246 (clobber (match_scratch:QI 3 "=&d")) 8247 (clobber (match_scratch:QI 4 "=&d"))] 8248 "" 8249 "#" 8250 "&& reload_completed" 8251 [(parallel [(unspec_volatile [(match_dup 0) 8252 (const_int 3)] 8253 UNSPECV_DELAY_CYCLES) 8254 (set (match_dup 1) 8255 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8256 (clobber (match_dup 2)) 8257 (clobber (match_dup 3)) 8258 (clobber (match_dup 4)) 8259 (clobber (reg:CC REG_CC))])]) 8260 8261 (define_insn "*delay_cycles_3" 8262 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 8263 (const_int 3)] 8264 UNSPECV_DELAY_CYCLES) 8265 (set (match_operand:BLK 1 "" "") 8266 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8267 (clobber (match_scratch:QI 2 "=&d")) 8268 (clobber (match_scratch:QI 3 "=&d")) 8269 (clobber (match_scratch:QI 4 "=&d")) 8270 (clobber (reg:CC REG_CC))] 8271 "reload_completed" 8272 "ldi %2,lo8(%0) 8273 ldi %3,hi8(%0) 8274 ldi %4,hlo8(%0) 8275 1: subi %2,1 8276 sbci %3,0 8277 sbci %4,0 8278 brne 1b" 8279 [(set_attr "length" "7")]) 8280 8281 (define_insn_and_split "delay_cycles_4" 8282 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 8283 (const_int 4)] 8284 UNSPECV_DELAY_CYCLES) 8285 (set (match_operand:BLK 1 "" "") 8286 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8287 (clobber (match_scratch:QI 2 "=&d")) 8288 (clobber (match_scratch:QI 3 "=&d")) 8289 (clobber (match_scratch:QI 4 "=&d")) 8290 (clobber (match_scratch:QI 5 "=&d"))] 8291 "" 8292 "#" 8293 "&& reload_completed" 8294 [(parallel [(unspec_volatile [(match_dup 0) 8295 (const_int 4)] 8296 UNSPECV_DELAY_CYCLES) 8297 (set (match_dup 1) 8298 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8299 (clobber (match_dup 2)) 8300 (clobber (match_dup 3)) 8301 (clobber (match_dup 4)) 8302 (clobber (match_dup 5)) 8303 (clobber (reg:CC REG_CC))])]) 8304 8305 (define_insn "*delay_cycles_4" 8306 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 8307 (const_int 4)] 8308 UNSPECV_DELAY_CYCLES) 8309 (set (match_operand:BLK 1 "" "") 8310 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 8311 (clobber (match_scratch:QI 2 "=&d")) 8312 (clobber (match_scratch:QI 3 "=&d")) 8313 (clobber (match_scratch:QI 4 "=&d")) 8314 (clobber (match_scratch:QI 5 "=&d")) 8315 (clobber (reg:CC REG_CC))] 8316 "reload_completed" 8317 "ldi %2,lo8(%0) 8318 ldi %3,hi8(%0) 8319 ldi %4,hlo8(%0) 8320 ldi %5,hhi8(%0) 8321 1: subi %2,1 8322 sbci %3,0 8323 sbci %4,0 8324 sbci %5,0 8325 brne 1b" 8326 [(set_attr "length" "9")]) 8327 8328 8329 ;; __builtin_avr_insert_bits 8330 8331 (define_insn_and_split "insert_bits" 8332 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r") 8333 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f") 8334 (match_operand:QI 2 "register_operand" "r ,r ,r") 8335 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")] 8336 UNSPEC_INSERT_BITS))] 8337 "" 8338 "#" 8339 "&& reload_completed" 8340 [(parallel [(set (match_dup 0) 8341 (unspec:QI [(match_dup 1) 8342 (match_dup 2) 8343 (match_dup 3)] 8344 UNSPEC_INSERT_BITS)) 8345 (clobber (reg:CC REG_CC))])]) 8346 8347 (define_insn "*insert_bits" 8348 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r") 8349 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f") 8350 (match_operand:QI 2 "register_operand" "r ,r ,r") 8351 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")] 8352 UNSPEC_INSERT_BITS)) 8353 (clobber (reg:CC REG_CC))] 8354 "reload_completed" 8355 { 8356 return avr_out_insert_bits (operands, NULL); 8357 } 8358 [(set_attr "adjust_len" "insert_bits")]) 8359 8360 8361 ;; __builtin_avr_flash_segment 8362 8363 ;; Just a helper for the next "official" expander. 8364 8365 (define_expand "flash_segment1" 8366 [(set (match_operand:QI 0 "register_operand" "") 8367 (subreg:QI (match_operand:PSI 1 "register_operand" "") 8368 2)) 8369 (set (pc) 8370 (if_then_else (ge (match_dup 0) 8371 (const_int 0)) 8372 (label_ref (match_operand 2 "" "")) 8373 (pc))) 8374 (set (match_dup 0) 8375 (const_int -1))]) 8376 8377 (define_insn_and_split "*flash_segment1" 8378 [(set (pc) 8379 (if_then_else (ge (match_operand:QI 0 "register_operand" "") 8380 (const_int 0)) 8381 (label_ref (match_operand 1 "" "")) 8382 (pc)))] 8383 "" 8384 "#" 8385 "reload_completed" 8386 [(set (reg:CC REG_CC) 8387 (compare:CC (match_dup 0) (const_int 0))) 8388 (set (pc) 8389 (if_then_else (ge (reg:CC REG_CC) (const_int 0)) 8390 (label_ref (match_dup 1)) 8391 (pc)))] 8392 "") 8393 8394 (define_expand "flash_segment" 8395 [(parallel [(match_operand:QI 0 "register_operand" "") 8396 (match_operand:PSI 1 "register_operand" "")])] 8397 "" 8398 { 8399 rtx label = gen_label_rtx (); 8400 emit (gen_flash_segment1 (operands[0], operands[1], label)); 8401 emit_label (label); 8402 DONE; 8403 }) 8404 8405 ;; Actually, it's too late now to work out address spaces known at compiletime. 8406 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin. 8407 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR 8408 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved. 8409 8410 (define_insn_and_split "*split.flash_segment" 8411 [(set (match_operand:QI 0 "register_operand" "=d") 8412 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri") 8413 (match_operand:HI 2 "register_operand" "r")) 8414 2))] 8415 "" 8416 { gcc_unreachable(); } 8417 "" 8418 [(set (match_dup 0) 8419 (match_dup 1))]) 8420 8421 8422 ;; Parity 8423 8424 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for 8425 ;; better 8-bit parity recognition. 8426 8427 (define_expand "parityhi2" 8428 [(parallel [(set (match_operand:HI 0 "register_operand" "") 8429 (parity:HI (match_operand:HI 1 "register_operand" ""))) 8430 (clobber (reg:HI 24))])]) 8431 8432 (define_insn_and_split "*parityhi2" 8433 [(set (match_operand:HI 0 "register_operand" "=r") 8434 (parity:HI (match_operand:HI 1 "register_operand" "r"))) 8435 (clobber (reg:HI 24))] 8436 "!reload_completed" 8437 { gcc_unreachable(); } 8438 "&& 1" 8439 [(set (reg:HI 24) 8440 (match_dup 1)) 8441 (set (reg:HI 24) 8442 (parity:HI (reg:HI 24))) 8443 (set (match_dup 0) 8444 (reg:HI 24))]) 8445 8446 (define_insn_and_split "*parityqihi2.1" 8447 [(set (match_operand:HI 0 "register_operand" "=r") 8448 (zero_extend:HI 8449 (parity:QI (match_operand:QI 1 "register_operand" "r")))) 8450 (clobber (reg:HI 24))] 8451 "!reload_completed" 8452 { gcc_unreachable(); } 8453 "&& 1" 8454 [(set (reg:QI 24) 8455 (match_dup 1)) 8456 (set (reg:HI 24) 8457 (zero_extend:HI (parity:QI (reg:QI 24)))) 8458 (set (match_dup 0) 8459 (reg:HI 24))]) 8460 8461 (define_insn_and_split "*parityqihi2.2" 8462 [(set (match_operand:HI 0 "register_operand" "=r") 8463 (parity:HI (match_operand:QI 1 "register_operand" "r"))) 8464 (clobber (reg:HI 24))] 8465 "!reload_completed" 8466 { gcc_unreachable(); } 8467 "&& 1" 8468 [(set (reg:QI 24) 8469 (match_dup 1)) 8470 (set (reg:HI 24) 8471 (zero_extend:HI (parity:QI (reg:QI 24)))) 8472 (set (match_dup 0) 8473 (reg:HI 24))]) 8474 8475 (define_expand "paritysi2" 8476 [(set (reg:SI 22) 8477 (match_operand:SI 1 "register_operand" "")) 8478 (set (reg:HI 24) 8479 (truncate:HI (parity:SI (reg:SI 22)))) 8480 (set (match_dup 2) 8481 (reg:HI 24)) 8482 (set (match_operand:SI 0 "register_operand" "") 8483 (zero_extend:SI (match_dup 2)))] 8484 "" 8485 { 8486 operands[2] = gen_reg_rtx (HImode); 8487 }) 8488 8489 (define_insn_and_split "*parityhi2.libgcc_split" 8490 [(set (reg:HI 24) 8491 (parity:HI (reg:HI 24)))] 8492 "" 8493 "#" 8494 "&& reload_completed" 8495 [(parallel [(set (reg:HI 24) 8496 (parity:HI (reg:HI 24))) 8497 (clobber (reg:CC REG_CC))])]) 8498 8499 (define_insn "*parityhi2.libgcc" 8500 [(set (reg:HI 24) 8501 (parity:HI (reg:HI 24))) 8502 (clobber (reg:CC REG_CC))] 8503 "reload_completed" 8504 "%~call __parityhi2" 8505 [(set_attr "type" "xcall")]) 8506 8507 (define_insn_and_split "*parityqihi2.libgcc_split" 8508 [(set (reg:HI 24) 8509 (zero_extend:HI (parity:QI (reg:QI 24))))] 8510 "" 8511 "#" 8512 "&& reload_completed" 8513 [(parallel [(set (reg:HI 24) 8514 (zero_extend:HI (parity:QI (reg:QI 24)))) 8515 (clobber (reg:CC REG_CC))])]) 8516 8517 (define_insn "*parityqihi2.libgcc" 8518 [(set (reg:HI 24) 8519 (zero_extend:HI (parity:QI (reg:QI 24)))) 8520 (clobber (reg:CC REG_CC))] 8521 "reload_completed" 8522 "%~call __parityqi2" 8523 [(set_attr "type" "xcall")]) 8524 8525 (define_insn_and_split "*paritysihi2.libgcc_split" 8526 [(set (reg:HI 24) 8527 (truncate:HI (parity:SI (reg:SI 22))))] 8528 "" 8529 "#" 8530 "&& reload_completed" 8531 [(parallel [(set (reg:HI 24) 8532 (truncate:HI (parity:SI (reg:SI 22)))) 8533 (clobber (reg:CC REG_CC))])]) 8534 8535 (define_insn "*paritysihi2.libgcc" 8536 [(set (reg:HI 24) 8537 (truncate:HI (parity:SI (reg:SI 22)))) 8538 (clobber (reg:CC REG_CC))] 8539 "reload_completed" 8540 "%~call __paritysi2" 8541 [(set_attr "type" "xcall")]) 8542 8543 8544 ;; Popcount 8545 8546 (define_expand "popcounthi2" 8547 [(set (reg:HI 24) 8548 (match_operand:HI 1 "register_operand" "")) 8549 (set (reg:HI 24) 8550 (popcount:HI (reg:HI 24))) 8551 (set (match_operand:HI 0 "register_operand" "") 8552 (reg:HI 24))] 8553 "" 8554 "") 8555 8556 (define_expand "popcountsi2" 8557 [(set (reg:SI 22) 8558 (match_operand:SI 1 "register_operand" "")) 8559 (set (reg:HI 24) 8560 (truncate:HI (popcount:SI (reg:SI 22)))) 8561 (set (match_dup 2) 8562 (reg:HI 24)) 8563 (set (match_operand:SI 0 "register_operand" "") 8564 (zero_extend:SI (match_dup 2)))] 8565 "" 8566 { 8567 operands[2] = gen_reg_rtx (HImode); 8568 }) 8569 8570 (define_insn_and_split "*popcounthi2.split8" 8571 [(set (reg:HI 24) 8572 (zero_extend:HI (popcount:QI (match_operand:QI 0 "register_operand"))))] 8573 "! reload_completed" 8574 { gcc_unreachable(); } 8575 "&& 1" 8576 [(set (reg:QI 24) 8577 (match_dup 0)) 8578 (set (reg:QI 24) 8579 (popcount:QI (reg:QI 24))) 8580 (set (reg:QI 25) 8581 (const_int 0))]) 8582 8583 (define_insn_and_split "*popcounthi2.libgcc_split" 8584 [(set (reg:HI 24) 8585 (popcount:HI (reg:HI 24)))] 8586 "" 8587 "#" 8588 "&& reload_completed" 8589 [(parallel [(set (reg:HI 24) 8590 (popcount:HI (reg:HI 24))) 8591 (clobber (reg:CC REG_CC))])]) 8592 8593 (define_insn "*popcounthi2.libgcc" 8594 [(set (reg:HI 24) 8595 (popcount:HI (reg:HI 24))) 8596 (clobber (reg:CC REG_CC))] 8597 "reload_completed" 8598 "%~call __popcounthi2" 8599 [(set_attr "type" "xcall")]) 8600 8601 (define_insn_and_split "*popcountsi2.libgcc_split" 8602 [(set (reg:HI 24) 8603 (truncate:HI (popcount:SI (reg:SI 22))))] 8604 "" 8605 "#" 8606 "&& reload_completed" 8607 [(parallel [(set (reg:HI 24) 8608 (truncate:HI (popcount:SI (reg:SI 22)))) 8609 (clobber (reg:CC REG_CC))])]) 8610 8611 (define_insn "*popcountsi2.libgcc" 8612 [(set (reg:HI 24) 8613 (truncate:HI (popcount:SI (reg:SI 22)))) 8614 (clobber (reg:CC REG_CC))] 8615 "reload_completed" 8616 "%~call __popcountsi2" 8617 [(set_attr "type" "xcall")]) 8618 8619 (define_insn_and_split "*popcountqi2.libgcc_split" 8620 [(set (reg:QI 24) 8621 (popcount:QI (reg:QI 24)))] 8622 "" 8623 "#" 8624 "&& reload_completed" 8625 [(parallel [(set (reg:QI 24) 8626 (popcount:QI (reg:QI 24))) 8627 (clobber (reg:CC REG_CC))])]) 8628 8629 (define_insn "*popcountqi2.libgcc" 8630 [(set (reg:QI 24) 8631 (popcount:QI (reg:QI 24))) 8632 (clobber (reg:CC REG_CC))] 8633 "reload_completed" 8634 "%~call __popcountqi2" 8635 [(set_attr "type" "xcall")]) 8636 8637 (define_insn_and_split "*popcountqihi2.libgcc" 8638 [(set (reg:HI 24) 8639 (zero_extend:HI (popcount:QI (reg:QI 24))))] 8640 "" 8641 "#" 8642 "" 8643 [(set (reg:QI 24) 8644 (popcount:QI (reg:QI 24))) 8645 (set (reg:QI 25) 8646 (const_int 0))]) 8647 8648 ;; Count Leading Zeros 8649 8650 (define_expand "clzhi2" 8651 [(set (reg:HI 24) 8652 (match_operand:HI 1 "register_operand" "")) 8653 (parallel [(set (reg:HI 24) 8654 (clz:HI (reg:HI 24))) 8655 (clobber (reg:QI 26))]) 8656 (set (match_operand:HI 0 "register_operand" "") 8657 (reg:HI 24))]) 8658 8659 (define_expand "clzsi2" 8660 [(set (reg:SI 22) 8661 (match_operand:SI 1 "register_operand" "")) 8662 (parallel [(set (reg:HI 24) 8663 (truncate:HI (clz:SI (reg:SI 22)))) 8664 (clobber (reg:QI 26))]) 8665 (set (match_dup 2) 8666 (reg:HI 24)) 8667 (set (match_operand:SI 0 "register_operand" "") 8668 (zero_extend:SI (match_dup 2)))] 8669 "" 8670 { 8671 operands[2] = gen_reg_rtx (HImode); 8672 }) 8673 8674 (define_insn_and_split "*clzhi2.libgcc_split" 8675 [(set (reg:HI 24) 8676 (clz:HI (reg:HI 24))) 8677 (clobber (reg:QI 26))] 8678 "" 8679 "#" 8680 "&& reload_completed" 8681 [(parallel [(set (reg:HI 24) 8682 (clz:HI (reg:HI 24))) 8683 (clobber (reg:QI 26)) 8684 (clobber (reg:CC REG_CC))])]) 8685 8686 (define_insn "*clzhi2.libgcc" 8687 [(set (reg:HI 24) 8688 (clz:HI (reg:HI 24))) 8689 (clobber (reg:QI 26)) 8690 (clobber (reg:CC REG_CC))] 8691 "reload_completed" 8692 "%~call __clzhi2" 8693 [(set_attr "type" "xcall")]) 8694 8695 (define_insn_and_split "*clzsihi2.libgcc_split" 8696 [(set (reg:HI 24) 8697 (truncate:HI (clz:SI (reg:SI 22)))) 8698 (clobber (reg:QI 26))] 8699 "" 8700 "#" 8701 "&& reload_completed" 8702 [(parallel [(set (reg:HI 24) 8703 (truncate:HI (clz:SI (reg:SI 22)))) 8704 (clobber (reg:QI 26)) 8705 (clobber (reg:CC REG_CC))])]) 8706 8707 (define_insn "*clzsihi2.libgcc" 8708 [(set (reg:HI 24) 8709 (truncate:HI (clz:SI (reg:SI 22)))) 8710 (clobber (reg:QI 26)) 8711 (clobber (reg:CC REG_CC))] 8712 "reload_completed" 8713 "%~call __clzsi2" 8714 [(set_attr "type" "xcall")]) 8715 8716 ;; Count Trailing Zeros 8717 8718 (define_expand "ctzhi2" 8719 [(set (reg:HI 24) 8720 (match_operand:HI 1 "register_operand" "")) 8721 (parallel [(set (reg:HI 24) 8722 (ctz:HI (reg:HI 24))) 8723 (clobber (reg:QI 26))]) 8724 (set (match_operand:HI 0 "register_operand" "") 8725 (reg:HI 24))]) 8726 8727 (define_expand "ctzsi2" 8728 [(set (reg:SI 22) 8729 (match_operand:SI 1 "register_operand" "")) 8730 (parallel [(set (reg:HI 24) 8731 (truncate:HI (ctz:SI (reg:SI 22)))) 8732 (clobber (reg:QI 22)) 8733 (clobber (reg:QI 26))]) 8734 (set (match_dup 2) 8735 (reg:HI 24)) 8736 (set (match_operand:SI 0 "register_operand" "") 8737 (zero_extend:SI (match_dup 2)))] 8738 "" 8739 { 8740 operands[2] = gen_reg_rtx (HImode); 8741 }) 8742 8743 (define_insn_and_split "*ctzhi2.libgcc_split" 8744 [(set (reg:HI 24) 8745 (ctz:HI (reg:HI 24))) 8746 (clobber (reg:QI 26))] 8747 "" 8748 "#" 8749 "&& reload_completed" 8750 [(parallel [(set (reg:HI 24) 8751 (ctz:HI (reg:HI 24))) 8752 (clobber (reg:QI 26)) 8753 (clobber (reg:CC REG_CC))])]) 8754 8755 (define_insn "*ctzhi2.libgcc" 8756 [(set (reg:HI 24) 8757 (ctz:HI (reg:HI 24))) 8758 (clobber (reg:QI 26)) 8759 (clobber (reg:CC REG_CC))] 8760 "reload_completed" 8761 "%~call __ctzhi2" 8762 [(set_attr "type" "xcall")]) 8763 8764 (define_insn_and_split "*ctzsihi2.libgcc_split" 8765 [(set (reg:HI 24) 8766 (truncate:HI (ctz:SI (reg:SI 22)))) 8767 (clobber (reg:QI 22)) 8768 (clobber (reg:QI 26))] 8769 "" 8770 "#" 8771 "&& reload_completed" 8772 [(parallel [(set (reg:HI 24) 8773 (truncate:HI (ctz:SI (reg:SI 22)))) 8774 (clobber (reg:QI 22)) 8775 (clobber (reg:QI 26)) 8776 (clobber (reg:CC REG_CC))])]) 8777 8778 (define_insn "*ctzsihi2.libgcc" 8779 [(set (reg:HI 24) 8780 (truncate:HI (ctz:SI (reg:SI 22)))) 8781 (clobber (reg:QI 22)) 8782 (clobber (reg:QI 26)) 8783 (clobber (reg:CC REG_CC))] 8784 "reload_completed" 8785 "%~call __ctzsi2" 8786 [(set_attr "type" "xcall")]) 8787 8788 ;; Find First Set 8789 8790 (define_expand "ffshi2" 8791 [(set (reg:HI 24) 8792 (match_operand:HI 1 "register_operand" "")) 8793 (parallel [(set (reg:HI 24) 8794 (ffs:HI (reg:HI 24))) 8795 (clobber (reg:QI 26))]) 8796 (set (match_operand:HI 0 "register_operand" "") 8797 (reg:HI 24))]) 8798 8799 (define_expand "ffssi2" 8800 [(set (reg:SI 22) 8801 (match_operand:SI 1 "register_operand" "")) 8802 (parallel [(set (reg:HI 24) 8803 (truncate:HI (ffs:SI (reg:SI 22)))) 8804 (clobber (reg:QI 22)) 8805 (clobber (reg:QI 26))]) 8806 (set (match_dup 2) 8807 (reg:HI 24)) 8808 (set (match_operand:SI 0 "register_operand" "") 8809 (zero_extend:SI (match_dup 2)))] 8810 "" 8811 { 8812 operands[2] = gen_reg_rtx (HImode); 8813 }) 8814 8815 (define_insn_and_split "*ffshi2.libgcc_split" 8816 [(set (reg:HI 24) 8817 (ffs:HI (reg:HI 24))) 8818 (clobber (reg:QI 26))] 8819 "" 8820 "#" 8821 "&& reload_completed" 8822 [(parallel [(set (reg:HI 24) 8823 (ffs:HI (reg:HI 24))) 8824 (clobber (reg:QI 26)) 8825 (clobber (reg:CC REG_CC))])]) 8826 8827 (define_insn "*ffshi2.libgcc" 8828 [(set (reg:HI 24) 8829 (ffs:HI (reg:HI 24))) 8830 (clobber (reg:QI 26)) 8831 (clobber (reg:CC REG_CC))] 8832 "reload_completed" 8833 "%~call __ffshi2" 8834 [(set_attr "type" "xcall")]) 8835 8836 (define_insn_and_split "*ffssihi2.libgcc_split" 8837 [(set (reg:HI 24) 8838 (truncate:HI (ffs:SI (reg:SI 22)))) 8839 (clobber (reg:QI 22)) 8840 (clobber (reg:QI 26))] 8841 "" 8842 "#" 8843 "&& reload_completed" 8844 [(parallel [(set (reg:HI 24) 8845 (truncate:HI (ffs:SI (reg:SI 22)))) 8846 (clobber (reg:QI 22)) 8847 (clobber (reg:QI 26)) 8848 (clobber (reg:CC REG_CC))])]) 8849 8850 (define_insn "*ffssihi2.libgcc" 8851 [(set (reg:HI 24) 8852 (truncate:HI (ffs:SI (reg:SI 22)))) 8853 (clobber (reg:QI 22)) 8854 (clobber (reg:QI 26)) 8855 (clobber (reg:CC REG_CC))] 8856 "reload_completed" 8857 "%~call __ffssi2" 8858 [(set_attr "type" "xcall")]) 8859 8860 ;; Copysign 8861 8862 (define_insn "copysignsf3" 8863 [(set (match_operand:SF 0 "register_operand" "=r") 8864 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 8865 (match_operand:SF 2 "register_operand" "r")] 8866 UNSPEC_COPYSIGN))] 8867 "" 8868 "bst %D2,7\;bld %D0,7" 8869 [(set_attr "length" "2")]) 8870 8871 ;; Swap Bytes (change byte-endianness) 8872 8873 (define_expand "bswapsi2" 8874 [(set (reg:SI 22) 8875 (match_operand:SI 1 "register_operand" "")) 8876 (set (reg:SI 22) 8877 (bswap:SI (reg:SI 22))) 8878 (set (match_operand:SI 0 "register_operand" "") 8879 (reg:SI 22))]) 8880 8881 (define_insn_and_split "*bswapsi2.libgcc_split" 8882 [(set (reg:SI 22) 8883 (bswap:SI (reg:SI 22)))] 8884 "" 8885 "#" 8886 "&& reload_completed" 8887 [(parallel [(set (reg:SI 22) 8888 (bswap:SI (reg:SI 22))) 8889 (clobber (reg:CC REG_CC))])]) 8890 8891 (define_insn "*bswapsi2.libgcc" 8892 [(set (reg:SI 22) 8893 (bswap:SI (reg:SI 22))) 8894 (clobber (reg:CC REG_CC))] 8895 "reload_completed" 8896 "%~call __bswapsi2" 8897 [(set_attr "type" "xcall")]) 8898 8899 8900 ;; CPU instructions 8901 8902 ;; NOP taking 1 or 2 Ticks 8903 (define_expand "nopv" 8904 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")] 8905 UNSPECV_NOP) 8906 (set (match_dup 1) 8907 (unspec_volatile:BLK [(match_dup 1)] 8908 UNSPECV_MEMORY_BARRIER))])] 8909 "" 8910 { 8911 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8912 MEM_VOLATILE_P (operands[1]) = 1; 8913 }) 8914 8915 (define_insn "*nopv" 8916 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")] 8917 UNSPECV_NOP) 8918 (set (match_operand:BLK 1 "" "") 8919 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))] 8920 "" 8921 "@ 8922 nop 8923 rjmp ." 8924 [(set_attr "length" "1")]) 8925 8926 ;; SLEEP 8927 (define_expand "sleep" 8928 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP) 8929 (set (match_dup 0) 8930 (unspec_volatile:BLK [(match_dup 0)] 8931 UNSPECV_MEMORY_BARRIER))])] 8932 "" 8933 { 8934 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8935 MEM_VOLATILE_P (operands[0]) = 1; 8936 }) 8937 8938 (define_insn "*sleep" 8939 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP) 8940 (set (match_operand:BLK 0 "" "") 8941 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))] 8942 "" 8943 "sleep" 8944 [(set_attr "length" "1")]) 8945 8946 ;; WDR 8947 (define_expand "wdr" 8948 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR) 8949 (set (match_dup 0) 8950 (unspec_volatile:BLK [(match_dup 0)] 8951 UNSPECV_MEMORY_BARRIER))])] 8952 "" 8953 { 8954 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 8955 MEM_VOLATILE_P (operands[0]) = 1; 8956 }) 8957 8958 (define_insn "*wdr" 8959 [(unspec_volatile [(const_int 0)] UNSPECV_WDR) 8960 (set (match_operand:BLK 0 "" "") 8961 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))] 8962 "" 8963 "wdr" 8964 [(set_attr "length" "1")]) 8965 8966 ;; FMUL 8967 (define_expand "fmul" 8968 [(set (reg:QI 24) 8969 (match_operand:QI 1 "register_operand" "")) 8970 (set (reg:QI 25) 8971 (match_operand:QI 2 "register_operand" "")) 8972 (parallel [(set (reg:HI 22) 8973 (unspec:HI [(reg:QI 24) 8974 (reg:QI 25)] UNSPEC_FMUL)) 8975 (clobber (reg:HI 24))]) 8976 (set (match_operand:HI 0 "register_operand" "") 8977 (reg:HI 22))] 8978 "" 8979 { 8980 if (AVR_HAVE_MUL) 8981 { 8982 emit_insn (gen_fmul_insn (operand0, operand1, operand2)); 8983 DONE; 8984 } 8985 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 8986 }) 8987 8988 (define_insn_and_split "fmul_insn" 8989 [(set (match_operand:HI 0 "register_operand" "=r") 8990 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 8991 (match_operand:QI 2 "register_operand" "a")] 8992 UNSPEC_FMUL))] 8993 "AVR_HAVE_MUL" 8994 "#" 8995 "&& reload_completed" 8996 [(parallel [(set (match_dup 0) 8997 (unspec:HI [(match_dup 1) 8998 (match_dup 2)] 8999 UNSPEC_FMUL)) 9000 (clobber (reg:CC REG_CC))])]) 9001 9002 (define_insn "*fmul_insn" 9003 [(set (match_operand:HI 0 "register_operand" "=r") 9004 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 9005 (match_operand:QI 2 "register_operand" "a")] 9006 UNSPEC_FMUL)) 9007 (clobber (reg:CC REG_CC))] 9008 "AVR_HAVE_MUL && reload_completed" 9009 "fmul %1,%2 9010 movw %0,r0 9011 clr __zero_reg__" 9012 [(set_attr "length" "3")]) 9013 9014 (define_insn_and_split "*fmul.call_split" 9015 [(set (reg:HI 22) 9016 (unspec:HI [(reg:QI 24) 9017 (reg:QI 25)] UNSPEC_FMUL)) 9018 (clobber (reg:HI 24))] 9019 "!AVR_HAVE_MUL" 9020 "#" 9021 "&& reload_completed" 9022 [(parallel [(set (reg:HI 22) 9023 (unspec:HI [(reg:QI 24) 9024 (reg:QI 25)] UNSPEC_FMUL)) 9025 (clobber (reg:HI 24)) 9026 (clobber (reg:CC REG_CC))])]) 9027 9028 (define_insn "*fmul.call" 9029 [(set (reg:HI 22) 9030 (unspec:HI [(reg:QI 24) 9031 (reg:QI 25)] UNSPEC_FMUL)) 9032 (clobber (reg:HI 24)) 9033 (clobber (reg:CC REG_CC))] 9034 "!AVR_HAVE_MUL && reload_completed" 9035 "%~call __fmul" 9036 [(set_attr "type" "xcall")]) 9037 9038 ;; FMULS 9039 (define_expand "fmuls" 9040 [(set (reg:QI 24) 9041 (match_operand:QI 1 "register_operand" "")) 9042 (set (reg:QI 25) 9043 (match_operand:QI 2 "register_operand" "")) 9044 (parallel [(set (reg:HI 22) 9045 (unspec:HI [(reg:QI 24) 9046 (reg:QI 25)] UNSPEC_FMULS)) 9047 (clobber (reg:HI 24))]) 9048 (set (match_operand:HI 0 "register_operand" "") 9049 (reg:HI 22))] 9050 "" 9051 { 9052 if (AVR_HAVE_MUL) 9053 { 9054 emit_insn (gen_fmuls_insn (operand0, operand1, operand2)); 9055 DONE; 9056 } 9057 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 9058 }) 9059 9060 (define_insn_and_split "fmuls_insn" 9061 [(set (match_operand:HI 0 "register_operand" "=r") 9062 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 9063 (match_operand:QI 2 "register_operand" "a")] 9064 UNSPEC_FMULS))] 9065 "AVR_HAVE_MUL" 9066 "#" 9067 "&& reload_completed" 9068 [(parallel [(set (match_dup 0) 9069 (unspec:HI [(match_dup 1) 9070 (match_dup 2)] 9071 UNSPEC_FMULS)) 9072 (clobber (reg:CC REG_CC))])]) 9073 9074 (define_insn "*fmuls_insn" 9075 [(set (match_operand:HI 0 "register_operand" "=r") 9076 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 9077 (match_operand:QI 2 "register_operand" "a")] 9078 UNSPEC_FMULS)) 9079 (clobber (reg:CC REG_CC))] 9080 "AVR_HAVE_MUL && reload_completed" 9081 "fmuls %1,%2 9082 movw %0,r0 9083 clr __zero_reg__" 9084 [(set_attr "length" "3")]) 9085 9086 (define_insn_and_split "*fmuls.call_split" 9087 [(set (reg:HI 22) 9088 (unspec:HI [(reg:QI 24) 9089 (reg:QI 25)] UNSPEC_FMULS)) 9090 (clobber (reg:HI 24))] 9091 "!AVR_HAVE_MUL" 9092 "#" 9093 "&& reload_completed" 9094 [(parallel [(set (reg:HI 22) 9095 (unspec:HI [(reg:QI 24) 9096 (reg:QI 25)] UNSPEC_FMULS)) 9097 (clobber (reg:HI 24)) 9098 (clobber (reg:CC REG_CC))])]) 9099 9100 (define_insn "*fmuls.call" 9101 [(set (reg:HI 22) 9102 (unspec:HI [(reg:QI 24) 9103 (reg:QI 25)] UNSPEC_FMULS)) 9104 (clobber (reg:HI 24)) 9105 (clobber (reg:CC REG_CC))] 9106 "!AVR_HAVE_MUL && reload_completed" 9107 "%~call __fmuls" 9108 [(set_attr "type" "xcall")]) 9109 9110 ;; FMULSU 9111 (define_expand "fmulsu" 9112 [(set (reg:QI 24) 9113 (match_operand:QI 1 "register_operand" "")) 9114 (set (reg:QI 25) 9115 (match_operand:QI 2 "register_operand" "")) 9116 (parallel [(set (reg:HI 22) 9117 (unspec:HI [(reg:QI 24) 9118 (reg:QI 25)] UNSPEC_FMULSU)) 9119 (clobber (reg:HI 24))]) 9120 (set (match_operand:HI 0 "register_operand" "") 9121 (reg:HI 22))] 9122 "" 9123 { 9124 if (AVR_HAVE_MUL) 9125 { 9126 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2)); 9127 DONE; 9128 } 9129 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 9130 }) 9131 9132 (define_insn_and_split "fmulsu_insn" 9133 [(set (match_operand:HI 0 "register_operand" "=r") 9134 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 9135 (match_operand:QI 2 "register_operand" "a")] 9136 UNSPEC_FMULSU))] 9137 "AVR_HAVE_MUL" 9138 "#" 9139 "&& reload_completed" 9140 [(parallel [(set (match_dup 0) 9141 (unspec:HI [(match_dup 1) 9142 (match_dup 2)] 9143 UNSPEC_FMULSU)) 9144 (clobber (reg:CC REG_CC))])]) 9145 9146 (define_insn "*fmulsu_insn" 9147 [(set (match_operand:HI 0 "register_operand" "=r") 9148 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 9149 (match_operand:QI 2 "register_operand" "a")] 9150 UNSPEC_FMULSU)) 9151 (clobber (reg:CC REG_CC))] 9152 "AVR_HAVE_MUL && reload_completed" 9153 "fmulsu %1,%2 9154 movw %0,r0 9155 clr __zero_reg__" 9156 [(set_attr "length" "3")]) 9157 9158 (define_insn_and_split "*fmulsu.call_split" 9159 [(set (reg:HI 22) 9160 (unspec:HI [(reg:QI 24) 9161 (reg:QI 25)] UNSPEC_FMULSU)) 9162 (clobber (reg:HI 24))] 9163 "!AVR_HAVE_MUL" 9164 "#" 9165 "&& reload_completed" 9166 [(parallel [(set (reg:HI 22) 9167 (unspec:HI [(reg:QI 24) 9168 (reg:QI 25)] UNSPEC_FMULSU)) 9169 (clobber (reg:HI 24)) 9170 (clobber (reg:CC REG_CC))])]) 9171 9172 (define_insn "*fmulsu.call" 9173 [(set (reg:HI 22) 9174 (unspec:HI [(reg:QI 24) 9175 (reg:QI 25)] UNSPEC_FMULSU)) 9176 (clobber (reg:HI 24)) 9177 (clobber (reg:CC REG_CC))] 9178 "!AVR_HAVE_MUL && reload_completed" 9179 "%~call __fmulsu" 9180 [(set_attr "type" "xcall") 9181 ]) 9182 9183 9185 ;; Some combiner patterns dealing with bits. 9186 ;; See PR42210 9187 9188 ;; Move bit $3.0 into bit $0.$4 9189 (define_insn "*movbitqi.1-6.a" 9190 [(set (match_operand:QI 0 "register_operand" "=r") 9191 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 9192 (match_operand:QI 2 "single_zero_operand" "n")) 9193 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r") 9194 (match_operand:QI 4 "const_0_to_7_operand" "n")) 9195 (match_operand:QI 5 "single_one_operand" "n"))))] 9196 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode)) 9197 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))" 9198 "bst %3,0\;bld %0,%4" 9199 [(set_attr "length" "2")]) 9200 9201 ;; Move bit $3.0 into bit $0.$4 9202 ;; Variation of above. Unfortunately, there is no canonicalized representation 9203 ;; of moving around bits. So what we see here depends on how user writes down 9204 ;; bit manipulations. 9205 (define_insn "*movbitqi.1-6.b" 9206 [(set (match_operand:QI 0 "register_operand" "=r") 9207 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 9208 (match_operand:QI 2 "single_zero_operand" "n")) 9209 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r") 9210 (const_int 1)) 9211 (match_operand:QI 4 "const_0_to_7_operand" "n"))))] 9212 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" 9213 "bst %3,0\;bld %0,%4" 9214 [(set_attr "length" "2")]) 9215 9216 ;; Move bit $3.x into bit $0.x. 9217 (define_insn "*movbit<mode>.0-6" 9218 [(set (match_operand:QISI 0 "register_operand" "=r") 9219 (ior:QISI (and:QISI (match_operand:QISI 1 "register_operand" "0") 9220 (match_operand:QISI 2 "single_zero_operand" "n")) 9221 (and:QISI (match_operand:QISI 3 "register_operand" "r") 9222 (match_operand:QISI 4 "single_one_operand" "n"))))] 9223 "GET_MODE_MASK(<MODE>mode) 9224 == (GET_MODE_MASK(<MODE>mode) & (INTVAL(operands[2]) ^ INTVAL(operands[4])))" 9225 { 9226 auto bitmask = GET_MODE_MASK (<MODE>mode) & UINTVAL (operands[4]); 9227 operands[4] = GEN_INT (exact_log2 (bitmask)); 9228 return "bst %T3%T4" CR_TAB "bld %T0%T4"; 9229 } 9230 [(set_attr "length" "2")]) 9231 9232 ;; Move bit $2.0 into bit $0.7. 9233 ;; For bit 7, combiner generates slightly different pattern 9234 (define_insn "*movbitqi.7" 9235 [(set (match_operand:QI 0 "register_operand" "=r") 9236 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 9237 (const_int 127)) 9238 (ashift:QI (match_operand:QI 2 "register_operand" "r") 9239 (const_int 7))))] 9240 "" 9241 "bst %2,0\;bld %0,7" 9242 [(set_attr "length" "2")]) 9243 9244 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM 9245 ;; and input/output match. We provide a special pattern for this, because 9246 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the 9247 ;; operation on I/O is atomic. 9248 (define_insn "*insv.io" 9249 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i")) 9250 (const_int 1) 9251 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n")) 9252 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))] 9253 "" 9254 "@ 9255 cbi %i0,%1 9256 sbi %i0,%1 9257 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1" 9258 [(set_attr "length" "1,1,4")]) 9259 9260 (define_insn "*insv.not.io" 9261 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i")) 9262 (const_int 1) 9263 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9264 (not:QI (match_operand:QI 2 "register_operand" "r")))] 9265 "" 9266 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1" 9267 [(set_attr "length" "4")]) 9268 9269 ;; The insv expander. 9270 ;; We only support 1-bit inserts 9271 (define_expand "insv" 9272 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "") 9273 (match_operand:QI 1 "const1_operand" "") ; width 9274 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos 9275 (match_operand:QI 3 "nonmemory_operand" ""))] 9276 "optimize") 9277 9278 ;; Some more patterns to support moving around one bit which can be accomplished 9279 ;; by BST + BLD in most situations. Unfortunately, there is no canonical 9280 ;; representation, and we just implement some more cases that are not too 9281 ;; complicated. 9282 9283 ;; Insert bit $2.0 into $0.$1 9284 (define_insn_and_split "*insv.reg_split" 9285 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l") 9286 (const_int 1) 9287 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n")) 9288 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))] 9289 "" 9290 "#" 9291 "&& reload_completed" 9292 [(parallel [(set (zero_extract:QI (match_dup 0) 9293 (const_int 1) 9294 (match_dup 1)) 9295 (match_dup 2)) 9296 (clobber (reg:CC REG_CC))])]) 9297 9298 (define_insn "*insv.reg" 9299 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l") 9300 (const_int 1) 9301 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n")) 9302 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P")) 9303 (clobber (reg:CC REG_CC))] 9304 "reload_completed" 9305 "@ 9306 bst %2,0\;bld %0,%1 9307 andi %0,lo8(~(1<<%1)) 9308 ori %0,lo8(1<<%1) 9309 clt\;bld %0,%1 9310 set\;bld %0,%1" 9311 [(set_attr "length" "2,1,1,2,2")]) 9312 9313 ;; Insert bit $2.$3 into $0.$1 9314 (define_insn "*insv.extract" 9315 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9316 (const_int 1) 9317 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9318 (any_extract:QI (match_operand:QI 2 "register_operand" "r") 9319 (const_int 1) 9320 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 9321 "" 9322 "bst %2,%3\;bld %0,%1" 9323 [(set_attr "length" "2")]) 9324 9325 ;; Insert bit $2.$3 into $0.$1 9326 (define_insn "*insv.shiftrt" 9327 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9328 (const_int 1) 9329 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9330 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r") 9331 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 9332 "" 9333 "bst %2,%3\;bld %0,%1" 9334 [(set_attr "length" "2")]) 9335 9336 ;; Same, but with a NOT inverting the source bit. 9337 ;; Insert bit ~$2.$3 into $0.$1 9338 (define_insn "insv_notbit" 9339 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9340 (const_int 1) 9341 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9342 (not:QI (zero_extract:QI (match_operand:QI 2 "register_operand" "r") 9343 (const_int 1) 9344 (match_operand:QI 3 "const_0_to_7_operand" "n")))) 9345 (clobber (reg:CC REG_CC))] 9346 "reload_completed" 9347 { 9348 return avr_out_insert_notbit (insn, operands, NULL); 9349 } 9350 [(set_attr "adjust_len" "insv_notbit")]) 9351 9352 ;; Insert bit ~$2.$3 into $0.$1 9353 (define_insn_and_split "*insv.not-shiftrt_split" 9354 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9355 (const_int 1) 9356 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9357 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r") 9358 (match_operand:QI 3 "const_0_to_7_operand" "n"))))] 9359 "" 9360 "#" 9361 "&& reload_completed" 9362 [(scratch)] 9363 { 9364 emit (gen_insv_notbit (operands[0], operands[1], operands[2], operands[3])); 9365 DONE; 9366 }) 9367 9368 ;; Insert bit ~$2.0 into $0.$1 9369 (define_insn_and_split "*insv.xor1-bit.0_split" 9370 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9371 (const_int 1) 9372 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9373 (xor:QI (match_operand:QI 2 "register_operand" "r") 9374 (const_int 1)))] 9375 "" 9376 "#" 9377 "&& reload_completed" 9378 [(scratch)] 9379 { 9380 emit (gen_insv_notbit (operands[0], operands[1], operands[2], const0_rtx)); 9381 DONE; 9382 }) 9383 9384 ;; Insert bit ~$2.0 into $0.$1 9385 (define_insn_and_split "*insv.not-bit.0_split" 9386 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9387 (const_int 1) 9388 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9389 (not:QI (match_operand:QI 2 "register_operand" "r")))] 9390 "" 9391 "#" 9392 "&& reload_completed" 9393 [(scratch)] 9394 { 9395 emit (gen_insv_notbit (operands[0], operands[1], operands[2], const0_rtx)); 9396 DONE; 9397 }) 9398 9399 ;; Insert bit ~$2.7 into $0.$1 9400 (define_insn_and_split "*insv.not-bit.7_split" 9401 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9402 (const_int 1) 9403 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9404 (ge:QI (match_operand:QI 2 "register_operand" "r") 9405 (const_int 0)))] 9406 "" 9407 "#" 9408 "&& reload_completed" 9409 [(scratch)] 9410 { 9411 emit (gen_insv_notbit (operands[0], operands[1], operands[2], GEN_INT(7))); 9412 DONE; 9413 }) 9414 9415 ;; Insert bit ~$2.$3 into $0.$1 9416 (define_insn_and_split "*insv.xor-extract_split" 9417 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 9418 (const_int 1) 9419 (match_operand:QI 1 "const_0_to_7_operand" "n")) 9420 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r") 9421 (match_operand:QI 4 "const_int_operand" "n")) 9422 (const_int 1) 9423 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 9424 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))" 9425 "#" 9426 "&& reload_completed" 9427 [(scratch)] 9428 { 9429 emit (gen_insv_notbit (operands[0], operands[1], operands[2], operands[3])); 9430 DONE; 9431 }) 9432 9433 9434 ;; Some combine patterns that try to fix bad code when a value is composed 9435 ;; from byte parts like in PR27663. 9436 ;; The patterns give some release but the code still is not optimal, 9437 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on. 9438 ;; That switch obfuscates things here and in many other places. 9439 9440 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0" 9441 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0" 9442 (define_insn_and_split "*<code_stdname><mode>qi.byte0" 9443 [(set (match_operand:HISI 0 "register_operand" "=r") 9444 (xior:HISI 9445 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) 9446 (match_operand:HISI 2 "register_operand" "0")))] 9447 "" 9448 "#" 9449 "reload_completed" 9450 [(set (match_dup 3) 9451 (xior:QI (match_dup 3) 9452 (match_dup 1)))] 9453 { 9454 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0); 9455 }) 9456 9457 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3" 9458 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3" 9459 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3" 9460 [(set (match_operand:HISI 0 "register_operand" "=r") 9461 (xior:HISI 9462 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) 9463 (match_operand:QI 2 "const_8_16_24_operand" "n")) 9464 (match_operand:HISI 3 "register_operand" "0")))] 9465 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 9466 "#" 9467 "&& reload_completed" 9468 [(set (match_dup 4) 9469 (xior:QI (match_dup 4) 9470 (match_dup 1)))] 9471 { 9472 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT; 9473 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno); 9474 }) 9475 9476 9477 (define_insn_and_split "*iorhi3.ashift8-ext.zerox" 9478 [(set (match_operand:HI 0 "register_operand" "=r,r") 9479 (ior:HI (ashift:HI (any_extend:HI 9480 (match_operand:QI 1 "register_operand" "r,r")) 9481 (const_int 8)) 9482 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))] 9483 "optimize" 9484 { gcc_unreachable(); } 9485 "&& reload_completed" 9486 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2))) 9487 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1))) 9488 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))] 9489 { 9490 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1); 9491 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0); 9492 9493 if (!reg_overlap_mentioned_p (hi, operands[2])) 9494 { 9495 emit_move_insn (hi, operands[1]); 9496 emit_move_insn (lo, operands[2]); 9497 DONE; 9498 } 9499 else if (!reg_overlap_mentioned_p (lo, operands[1])) 9500 { 9501 emit_move_insn (lo, operands[2]); 9502 emit_move_insn (hi, operands[1]); 9503 DONE; 9504 } 9505 9506 gcc_assert (REGNO (operands[1]) == REGNO (operands[0])); 9507 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0])); 9508 }) 9509 9510 (define_insn_and_split "*iorhi3.ashift8-ext.reg" 9511 [(set (match_operand:HI 0 "register_operand" "=r") 9512 (ior:HI (ashift:HI (any_extend:HI 9513 (match_operand:QI 1 "register_operand" "r")) 9514 (const_int 8)) 9515 (match_operand:HI 2 "register_operand" "0")))] 9516 "optimize" 9517 { gcc_unreachable(); } 9518 "&& reload_completed" 9519 [(set (match_dup 3) 9520 (ior:QI (match_dup 4) 9521 (match_dup 1)))] 9522 { 9523 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 9524 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1); 9525 }) 9526 9527 (define_insn_and_split "*iorhi3.ashift8-reg.zerox" 9528 [(set (match_operand:HI 0 "register_operand" "=r") 9529 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r") 9530 (const_int 8)) 9531 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))] 9532 "optimize" 9533 { gcc_unreachable(); } 9534 "&& reload_completed" 9535 [(set (match_dup 3) 9536 (match_dup 4))] 9537 { 9538 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 9539 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 9540 }) 9541 9542 9543 (define_peephole2 9544 [(parallel [(set (match_operand:QI 0 "register_operand") 9545 (const_int 0)) 9546 (clobber (reg:CC REG_CC))]) 9547 (parallel [(set (match_dup 0) 9548 (ior:QI (match_dup 0) 9549 (match_operand:QI 1 "register_operand"))) 9550 (clobber (reg:CC REG_CC))])] 9551 "" 9552 [(parallel [(set (match_dup 0) 9553 (match_dup 1)) 9554 (clobber (reg:CC REG_CC))])]) 9555 9556 9557 ;; Try optimize decrement-and-branch. When we have an addition followed 9558 ;; by a comparison of the result against zero, we can output the addition 9559 ;; in such a way that SREG.N and SREG.Z are set according to the result. 9560 9561 ;; { -1, +1 } for QImode, otherwise the empty set. 9562 (define_mode_attr p1m1 [(QI "N P") 9563 (HI "Yxx") (PSI "Yxx") (SI "Yxx")]) 9564 9565 ;; FIXME: reload1.cc::do_output_reload() does not support output reloads 9566 ;; for JUMP_INSNs, hence letting combine doing decrement-and-branch like 9567 ;; the following might run into ICE. Doing reloads by hand is too painful... 9568 ; 9569 ; (define_insn_and_split "*add.for.eqne.<mode>.cbranch" 9570 ; [(set (pc) 9571 ; (if_then_else (eqne (match_operand:QISI 1 "register_operand" "0") 9572 ; (match_operand:QISI 2 "const_int_operand" "n")) 9573 ; (label_ref (match_operand 4)) 9574 ; (pc))) 9575 ; (set (match_operand:QISI 0 "register_operand" "=r") 9576 ; (plus:QISI (match_dup 1) 9577 ; (match_operand:QISI 3 "const_int_operand" "n")))] 9578 ; ;; No clobber for now as combine might not have one handy. 9579 ; ;; We pop a scatch in split1. 9580 ; "!reload_completed 9581 ; && const0_rtx == simplify_binary_operation (PLUS, <MODE>mode, 9582 ; operands[2], operands[3])" 9583 ; { gcc_unreachable(); } 9584 ; "&& 1" 9585 ; [(parallel [(set (pc) 9586 ; (if_then_else (eqne (match_dup 1) 9587 ; (match_dup 2)) 9588 ; (label_ref (match_dup 4)) 9589 ; (pc))) 9590 ; (set (match_dup 0) 9591 ; (plus:QISI (match_dup 1) 9592 ; (match_dup 3))) 9593 ; (clobber (scratch:QI))])]) 9594 ; 9595 ;; ...Hence, stick with RTL peepholes for now. Unfortunately, there is no 9596 ;; canonical form, and if reload shuffles registers around, we might miss 9597 ;; opportunities to match a decrement-and-branch. 9598 ;; doloop_end doesn't reload either, so doloop_end also won't work. 9599 9600 (define_expand "gen_add_for_<code>_<mode>" 9601 ; "*add.for.eqne.<mode>" 9602 [(parallel [(set (reg:CC REG_CC) 9603 (compare:CC (plus:QISI (match_operand:QISI 0 "register_operand") 9604 (match_operand:QISI 1 "const_int_operand")) 9605 (const_int 0))) 9606 (set (match_dup 0) 9607 (plus:QISI (match_dup 0) 9608 (match_dup 1))) 9609 (clobber (match_operand:QI 3))]) 9610 ; "branch" 9611 (set (pc) 9612 (if_then_else (eqne (reg:CC REG_CC) 9613 (const_int 0)) 9614 (label_ref (match_dup 2)) 9615 (pc)))]) 9616 9617 9618 ;; 1/3: A version without clobber: d-reg or 8-bit adds +/-1. 9619 (define_peephole2 9620 [(parallel [(set (match_operand:QISI 0 "register_operand") 9621 (plus:QISI (match_dup 0) 9622 (match_operand:QISI 1 "const_int_operand"))) 9623 (clobber (reg:CC REG_CC))]) 9624 (set (reg:CC REG_CC) 9625 (compare:CC (match_dup 0) 9626 (const_int 0))) 9627 (set (pc) 9628 (if_then_else (eqne (reg:CC REG_CC) 9629 (const_int 0)) 9630 (label_ref (match_operand 2)) 9631 (pc)))] 9632 "peep2_regno_dead_p (3, REG_CC) 9633 && (d_register_operand (operands[0], <MODE>mode) 9634 || (<MODE>mode == QImode 9635 && (INTVAL (operands[1]) == 1 9636 || INTVAL (operands[1]) == -1)))" 9637 [(scratch)] 9638 { 9639 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2], 9640 gen_rtx_SCRATCH (QImode))); 9641 DONE; 9642 }) 9643 9644 ;; 2/3: A version with clobber from the insn. 9645 (define_peephole2 9646 [(parallel [(set (match_operand:QISI 0 "register_operand") 9647 (plus:QISI (match_dup 0) 9648 (match_operand:QISI 1 "const_int_operand"))) 9649 (clobber (match_operand:QI 3 "scratch_or_d_register_operand")) 9650 (clobber (reg:CC REG_CC))]) 9651 (parallel [(set (reg:CC REG_CC) 9652 (compare:CC (match_dup 0) 9653 (const_int 0))) 9654 (clobber (match_operand:QI 4 "scratch_or_d_register_operand"))]) 9655 (set (pc) 9656 (if_then_else (eqne (reg:CC REG_CC) 9657 (const_int 0)) 9658 (label_ref (match_operand 2)) 9659 (pc)))] 9660 "peep2_regno_dead_p (3, REG_CC)" 9661 [(scratch)] 9662 { 9663 rtx scratch = REG_P (operands[3]) ? operands[3] : operands[4]; 9664 9665 // We need either a d-register or a scratch register to clobber. 9666 if (! REG_P (scratch) 9667 && ! d_register_operand (operands[0], <MODE>mode) 9668 && ! (QImode == <MODE>mode 9669 && (INTVAL (operands[1]) == 1 9670 || INTVAL (operands[1]) == -1))) 9671 { 9672 FAIL; 9673 } 9674 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2], 9675 scratch)); 9676 DONE; 9677 }) 9678 9679 ;; 3/3 A version with a clobber from peephole2. 9680 (define_peephole2 9681 [(match_scratch:QI 3 "d") 9682 (parallel [(set (match_operand:QISI 0 "register_operand") 9683 (plus:QISI (match_dup 0) 9684 (match_operand:QISI 1 "const_int_operand"))) 9685 (clobber (reg:CC REG_CC))]) 9686 (set (reg:CC REG_CC) 9687 (compare:CC (match_dup 0) 9688 (const_int 0))) 9689 (set (pc) 9690 (if_then_else (eqne (reg:CC REG_CC) 9691 (const_int 0)) 9692 (label_ref (match_operand 2)) 9693 (pc)))] 9694 "peep2_regno_dead_p (3, REG_CC)" 9695 [(scratch)] 9696 { 9697 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2], 9698 operands[3])); 9699 DONE; 9700 }) 9701 9702 ;; Result of the above three peepholes is an addition that also 9703 ;; performs an EQ or NE comparison (of the result) against zero. 9704 ;; FIXME: Using (match_dup 0) instead of operands[3/4] makes rnregs 9705 ;; barf in regrename.cc::merge_overlapping_regs(). For now, use the 9706 ;; fix from PR50788: Constrain as "0". 9707 (define_insn "*add.for.eqne.<mode>" 9708 [(set (reg:CC REG_CC) 9709 (compare:CC 9710 (plus:QISI (match_operand:QISI 3 "register_operand" "0,0 ,0") 9711 (match_operand:QISI 1 "const_int_operand" "n,<p1m1>,n")) 9712 (const_int 0))) 9713 (set (match_operand:QISI 0 "register_operand" "=d,*r ,r") 9714 (plus:QISI (match_operand:QISI 4 "register_operand" "0,0 ,0") 9715 (match_dup 1))) 9716 (clobber (match_scratch:QI 2 "=X,X ,&d"))] 9717 "reload_completed" 9718 { 9719 return avr_out_plus_set_ZN (operands, nullptr); 9720 } 9721 [(set_attr "adjust_len" "add_set_ZN")]) 9722 9723 9724 ;; Swapping both comparison and branch condition. This can turn difficult 9725 ;; branches to easy ones. And in some cases, a comparison against one can 9726 ;; be turned into a comparison against zero. 9727 9728 (define_peephole2 ; "*swapped_tst<mode>" 9729 [(parallel [(set (reg:CC REG_CC) 9730 (compare:CC (match_operand:ALLs234 1 "register_operand") 9731 (match_operand:ALLs234 2 "const_operand"))) 9732 (clobber (match_operand:QI 3 "scratch_operand"))]) 9733 (set (pc) 9734 (if_then_else (match_operator 0 "ordered_comparison_operator" 9735 [(reg:CC REG_CC) 9736 (const_int 0)]) 9737 (label_ref (match_operand 4)) 9738 (pc)))] 9739 "peep2_regno_dead_p (2, REG_CC)" 9740 [(set (reg:CC REG_CC) 9741 (compare:CC (match_dup 2) 9742 (match_dup 1))) 9743 ; "branch" 9744 (set (pc) 9745 (if_then_else (match_op_dup 0 [(reg:CC REG_CC) 9746 (const_int 0)]) 9747 (label_ref (match_dup 4)) 9748 (pc)))] 9749 { 9750 rtx xval = avr_to_int_mode (operands[2]); 9751 enum rtx_code code = GET_CODE (operands[0]); 9752 9753 if (code == GT && xval == const0_rtx) 9754 code = LT; 9755 else if (code == GE && xval == const1_rtx) 9756 code = LT; 9757 else if (code == LE && xval == const0_rtx) 9758 code = GE; 9759 else if (code == LT && xval == const1_rtx) 9760 code = GE; 9761 else 9762 FAIL; 9763 9764 operands[2] = CONST0_RTX (<MODE>mode); 9765 PUT_CODE (operands[0], code); 9766 }) 9767 9768 ;; Same, but for 8-bit modes which have no scratch reg. 9769 (define_peephole2 ; "*swapped_tst<mode>" 9770 [(set (reg:CC REG_CC) 9771 (compare:CC (match_operand:ALLs1 1 "register_operand") 9772 (match_operand:ALLs1 2 "const_operand"))) 9773 (set (pc) 9774 (if_then_else (match_operator 0 "ordered_comparison_operator" 9775 [(reg:CC REG_CC) 9776 (const_int 0)]) 9777 (label_ref (match_operand 4)) 9778 (pc)))] 9779 "peep2_regno_dead_p (2, REG_CC)" 9780 [(set (reg:CC REG_CC) 9781 (compare:CC (match_dup 2) 9782 (match_dup 1))) 9783 ; "branch" 9784 (set (pc) 9785 (if_then_else (match_op_dup 0 [(reg:CC REG_CC) 9786 (const_int 0)]) 9787 (label_ref (match_dup 4)) 9788 (pc)))] 9789 { 9790 rtx xval = avr_to_int_mode (operands[2]); 9791 enum rtx_code code = GET_CODE (operands[0]); 9792 9793 if (code == GT && xval == const0_rtx) 9794 code = LT; 9795 else if (code == GE && xval == const1_rtx) 9796 code = LT; 9797 else if (code == LE && xval == const0_rtx) 9798 code = GE; 9799 else if (code == LT && xval == const1_rtx) 9800 code = GE; 9801 else 9802 FAIL; 9803 9804 operands[2] = CONST0_RTX (<MODE>mode); 9805 PUT_CODE (operands[0], code); 9806 }) 9807 9808 9809 (define_expand "extzv<mode>" 9810 [(set (match_operand:QI 0 "register_operand") 9811 (zero_extract:QI (match_operand:QISI 1 "register_operand") 9812 (match_operand:QI 2 "const1_operand") 9813 (match_operand:QI 3 "const_0_to_<MSB>_operand")))]) 9814 9815 (define_insn_and_split "*extzv<mode>_split" 9816 [(set (match_operand:QI 0 "register_operand" "=r") 9817 (zero_extract:QI (match_operand:QISI 1 "reg_or_low_io_operand" "r Yil") 9818 (const_int 1) 9819 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n")))] 9820 "" 9821 "#" 9822 "&& reload_completed" 9823 [(parallel [(set (match_dup 0) 9824 (zero_extract:QI (match_dup 1) 9825 (const_int 1) 9826 (match_dup 2))) 9827 (clobber (reg:CC REG_CC))])] 9828 { 9829 if (! MEM_P (operands[1])) 9830 { 9831 int bitno = INTVAL (operands[2]); 9832 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8); 9833 operands[2] = GEN_INT (bitno % 8); 9834 } 9835 }) 9836 9837 (define_insn "*extzv<mode>" 9838 [(set (match_operand:QI 0 "register_operand" "=r") 9839 (zero_extract:QI (match_operand:QISI 1 "reg_or_low_io_operand" "r Yil") 9840 (const_int 1) 9841 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n"))) 9842 (clobber (reg:CC REG_CC))] 9843 "reload_completed" 9844 { 9845 return avr_out_extr (insn, operands, nullptr); 9846 } 9847 [(set_attr "adjust_len" "extr")]) 9848 9849 9850 (define_insn_and_split "*extzv.qihi1" 9851 [(set (match_operand:HI 0 "register_operand" "=r") 9852 (zero_extract:HI (match_operand:QI 1 "register_operand" "r") 9853 (const_int 1) 9854 (match_operand:QI 2 "const_0_to_7_operand" "n")))] 9855 "" 9856 "#" 9857 "" 9858 [(set (match_dup 3) 9859 (zero_extract:QI (match_dup 1) 9860 (const_int 1) 9861 (match_dup 2))) 9862 (set (match_dup 4) 9863 (const_int 0))] 9864 { 9865 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 9866 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 9867 }) 9868 9869 (define_insn_and_split "*extzv.not_split" 9870 [(set (match_operand:QI 0 "register_operand" "=r") 9871 (zero_extract:QI (not:QI (match_operand:QI 1 "reg_or_low_io_operand" "r Yil")) 9872 (const_int 1) 9873 (match_operand:QI 2 "const_0_to_7_operand" "n")))] 9874 "" 9875 "#" 9876 "&& reload_completed" 9877 [(parallel [(set (match_dup 0) 9878 (zero_extract:QI (not:QI (match_dup 1)) 9879 (const_int 1) 9880 (match_dup 2))) 9881 (clobber (reg:CC REG_CC))])]) 9882 9883 (define_insn "*extzv.not" 9884 [(set (match_operand:QI 0 "register_operand" "=r") 9885 (zero_extract:QI (not:QI (match_operand:QI 1 "reg_or_low_io_operand" "r Yil")) 9886 (const_int 1) 9887 (match_operand:QI 2 "const_0_to_7_operand" "n"))) 9888 (clobber (reg:CC REG_CC))] 9889 "reload_completed" 9890 { 9891 return avr_out_extr_not (insn, operands, nullptr); 9892 } 9893 [(set_attr "adjust_len" "extr_not")]) 9894 9895 (define_insn_and_split "*extzv.subreg.<mode>" 9896 [(set (match_operand:QI 0 "register_operand" "=r") 9897 (subreg:QI (zero_extract:HISI (match_operand:HISI 1 "register_operand" "r") 9898 (const_int 1) 9899 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n")) 9900 0))] 9901 "! reload_completed" 9902 { gcc_unreachable(); } 9903 "&& 1" 9904 [; "*extzv<mode>_split" 9905 (set (match_dup 0) 9906 (zero_extract:QI (match_dup 1) 9907 (const_int 1) 9908 (match_dup 2)))]) 9909 9910 ;; Possible subreg bytes. 9911 (define_int_iterator SuReB [0 1 2 3]) 9912 9913 (define_insn_and_split "*extzv.<mode>.subreg<SuReB>" 9914 [(set (match_operand:QI 0 "register_operand" "=r") 9915 (zero_extract:QI (subreg:QI 9916 (and:HISI (match_operand:HISI 1 "register_operand" "r") 9917 (match_operand:HISI 2 "single_one_operand" "n")) 9918 SuReB) 9919 (const_int 1) 9920 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 9921 "! reload_completed 9922 && IN_RANGE (UINTVAL(operands[2]) & GET_MODE_MASK(<MODE>mode), 9923 1U << (8 * <SuReB>), 0x80U << (8 * <SuReB>)) 9924 && exact_log2 (UINTVAL(operands[2]) & GET_MODE_MASK(<MODE>mode)) 9925 == 8 * <SuReB> + INTVAL (operands[3])" 9926 { gcc_unreachable(); } 9927 "&& 1" 9928 [; "*extzv<mode>_split" 9929 (set (match_dup 0) 9930 (zero_extract:QI (match_dup 1) 9931 (const_int 1) 9932 (match_dup 4)))] 9933 { 9934 operands[4] = plus_constant (QImode, operands[3], 8 * <SuReB>); 9935 }) 9936 9937 9938 (define_insn_and_split "*extzv.xor" 9939 [(set (match_operand:QI 0 "register_operand") 9940 (zero_extract:QI (xor:QI (match_operand:QI 1 "reg_or_low_io_operand") 9941 (match_operand:QI 2 "single_one_operand")) 9942 (const_int 1) 9943 (match_operand:QI 3 "const_0_to_7_operand")))] 9944 "! reload_completed 9945 && ((1 << INTVAL (operands[3])) & INTVAL (operands[2])) != 0" 9946 { gcc_unreachable(); } 9947 "&& 1" 9948 [; "*extzv.not_split" 9949 (set (match_dup 0) 9950 (zero_extract:QI (not:QI (match_dup 1)) 9951 (const_int 1) 9952 (match_dup 3)))]) 9953 9954 9955 (define_insn_and_split "*extzv<mode>.ge" 9956 [(set (match_operand:QI 0 "register_operand" "=r") 9957 (ge:QI (match_operand:QISI 1 "reg_or_low_io_operand" "r Yil") 9958 (match_operand:QISI 2 "const0_operand" "Y00")))] 9959 "" 9960 "#" 9961 "reload_completed" 9962 [; "*extzv.not" 9963 (parallel [(set (match_dup 0) 9964 (zero_extract:QI (not:QI (match_dup 1)) 9965 (const_int 1) 9966 (const_int 7))) 9967 (clobber (reg:CC REG_CC))])] 9968 { 9969 if (! MEM_P (operands[1])) 9970 { 9971 int msb = <SIZE> - 1; 9972 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, msb); 9973 } 9974 }) 9975 9976 (define_insn_and_split "*neg.ashiftrt<mode>.msb" 9977 [(set (match_operand:QI 0 "register_operand" "=r") 9978 (neg:QI (subreg:QI 9979 (ashiftrt:QISI (match_operand:QISI 1 "register_operand" "r") 9980 (match_operand:QI 2 "const<MSB>_operand" "n")) 9981 0)))] 9982 "! reload_completed" 9983 { gcc_unreachable(); } 9984 "&& 1" 9985 [; "*extzv<mode>_split" 9986 (set (match_dup 0) 9987 (zero_extract:QI (match_dup 1) 9988 (const_int 1) 9989 (match_dup 2)))]) 9990 9991 (define_insn_and_split "*extzv.io.lsr7" 9992 [(set (match_operand:QI 0 "register_operand") 9993 (lshiftrt:QI (match_operand:QI 1 "reg_or_low_io_operand") 9994 (const_int 7)))] 9995 "! reload_completed" 9996 { gcc_unreachable(); } 9997 "&& 1" 9998 [; "*extzv_split" 9999 (set (match_dup 0) 10000 (zero_extract:QI (match_dup 1) 10001 (const_int 1) 10002 (const_int 7)))]) 10003 10004 ;; This insn serves as a combine bridge because insn combine will only 10005 ;; combine so much (3) insns at most. It's not actually an open coded 10006 ;; bit-insertion but just a part of it. It may occur in other contexts 10007 ;; than INSV though, and in such a case the code may be worse than without 10008 ;; this pattern. We still have to emit code for it in that case because 10009 ;; we cannot roll back. 10010 (define_insn_and_split "*insv.any_shift.<mode>_split" 10011 [(set (match_operand:QISI 0 "register_operand" "=r") 10012 (and:QISI (any_shift:QISI (match_operand:QISI 1 "register_operand" "r") 10013 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n")) 10014 (match_operand:QISI 3 "single_one_operand" "n")))] 10015 "" 10016 "#" 10017 "&& reload_completed" 10018 [(parallel [(set (match_dup 0) 10019 (and:QISI (any_shift:QISI (match_dup 1) 10020 (match_dup 2)) 10021 (match_dup 3))) 10022 (clobber (reg:CC REG_CC))])]) 10023 10024 (define_insn "*insv.any_shift.<mode>" 10025 [(set (match_operand:QISI 0 "register_operand" "=r") 10026 (and:QISI (any_shift:QISI (match_operand:QISI 1 "register_operand" "r") 10027 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n")) 10028 (match_operand:QISI 3 "single_one_operand" "n"))) 10029 (clobber (reg:CC REG_CC))] 10030 "reload_completed" 10031 { 10032 return avr_out_insv (insn, operands, nullptr); 10033 } 10034 [(set_attr "adjust_len" "insv")]) 10035 10036 10037 (define_insn_and_split "*extzv.<mode>hi2" 10038 [(set (match_operand:HI 0 "register_operand" "=r") 10039 (zero_extend:HI 10040 (zero_extract:QI (match_operand:QISI 1 "register_operand" "r") 10041 (const_int 1) 10042 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n"))))] 10043 "! reload_completed" 10044 { gcc_unreachable(); } 10045 "&& 1" 10046 [; "*extzv<mode>_split" 10047 (set (match_dup 3) 10048 (zero_extract:QI (match_dup 1) 10049 (const_int 1) 10050 (match_dup 2))) 10051 (set (match_dup 4) 10052 (const_int 0))] 10053 { 10054 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 10055 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 10056 }) 10057 10058 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without 10059 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example. 10060 (define_insn_and_split "*extract.subreg.bit" 10061 [(set (match_operand:QI 0 "register_operand" "=r") 10062 (and:QI (subreg:QI 10063 (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r") 10064 (match_operand:QI 2 "const_0_to_<MSB>_operand" "n")) 10065 0) 10066 (const_int 1)))] 10067 "! reload_completed" 10068 { gcc_unreachable(); } 10069 "&& 1" 10070 [;; "*extzv<mode>_split" 10071 (set (match_dup 0) 10072 (zero_extract:QI (match_dup 1) 10073 (const_int 1) 10074 (match_dup 2)))]) 10075 10076 10077 ;; Work around PR115307: Early passes expand isinf/f/l to a bloat. 10078 ;; These passes do not consider costs, and there is no way to 10079 ;; hook in or otherwise disable the generated bloat. 10080 10081 ;; isinfsf2 isinfdf2 10082 (define_expand "isinf<mode>2" 10083 [(parallel [(match_operand:HI 0) 10084 (match_operand:SFDF 1)])] 10085 "" 10086 { 10087 FAIL; 10088 }) 10089 10090 10092 ;; Fixed-point instructions 10093 (include "avr-fixed.md") 10094 10095 ;; Operations on 64-bit registers 10096 (include "avr-dimode.md") 10097