1;; Machine description for GNU compiler, 2;; for ATMEL AVR micro controllers. 3;; Copyright (C) 1998-2018 Free Software Foundation, Inc. 4;; Contributed by Denis Chertykov (chertykov@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 quivalent 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 55(define_constants 56 [(REG_X 26) 57 (REG_Y 28) 58 (REG_Z 30) 59 (REG_W 24) 60 (REG_SP 32) 61 (LPM_REGNO 0) ; implicit target register of LPM 62 (TMP_REGNO 0) ; temporary register r0 63 (ZERO_REGNO 1) ; zero register r1 64 ]) 65 66(define_constants 67 [(TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY 68 (ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY 69 ]) 70 71(define_c_enum "unspec" 72 [UNSPEC_STRLEN 73 UNSPEC_MOVMEM 74 UNSPEC_INDEX_JMP 75 UNSPEC_FMUL 76 UNSPEC_FMULS 77 UNSPEC_FMULSU 78 UNSPEC_COPYSIGN 79 UNSPEC_IDENTITY 80 UNSPEC_INSERT_BITS 81 UNSPEC_ROUND 82 ]) 83 84(define_c_enum "unspecv" 85 [UNSPECV_PROLOGUE_SAVES 86 UNSPECV_EPILOGUE_RESTORES 87 UNSPECV_WRITE_SP 88 UNSPECV_GASISR 89 UNSPECV_GOTO_RECEIVER 90 UNSPECV_ENABLE_IRQS 91 UNSPECV_MEMORY_BARRIER 92 UNSPECV_NOP 93 UNSPECV_SLEEP 94 UNSPECV_WDR 95 UNSPECV_DELAY_CYCLES 96 ]) 97 98;; Chunk numbers for __gcc_isr are hard-coded in GAS. 99(define_constants 100 [(GASISR_Prologue 1) 101 (GASISR_Epilogue 2) 102 (GASISR_Done 0) 103 ]) 104 105(include "predicates.md") 106(include "constraints.md") 107 108;; Condition code settings. 109(define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber, 110 plus,ldi" 111 (const_string "none")) 112 113(define_attr "type" "branch,branch1,arith,xcall" 114 (const_string "arith")) 115 116;; The size of instructions in bytes. 117;; XXX may depend from "cc" 118 119(define_attr "length" "" 120 (cond [(eq_attr "type" "branch") 121 (if_then_else (and (ge (minus (pc) (match_dup 0)) 122 (const_int -62)) 123 (le (minus (pc) (match_dup 0)) 124 (const_int 62))) 125 (const_int 1) 126 (if_then_else (and (ge (minus (pc) (match_dup 0)) 127 (const_int -2044)) 128 (le (minus (pc) (match_dup 0)) 129 (const_int 2045))) 130 (const_int 2) 131 (const_int 3))) 132 (eq_attr "type" "branch1") 133 (if_then_else (and (ge (minus (pc) (match_dup 0)) 134 (const_int -62)) 135 (le (minus (pc) (match_dup 0)) 136 (const_int 61))) 137 (const_int 2) 138 (if_then_else (and (ge (minus (pc) (match_dup 0)) 139 (const_int -2044)) 140 (le (minus (pc) (match_dup 0)) 141 (const_int 2043))) 142 (const_int 3) 143 (const_int 4))) 144 (eq_attr "type" "xcall") 145 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 146 (const_int 1) 147 (const_int 2))] 148 (const_int 2))) 149 150;; Lengths of several insns are adjusted in avr.c:adjust_insn_length(). 151;; Following insn attribute tells if and how the adjustment has to be 152;; done: 153;; no No adjustment needed; attribute "length" is fine. 154;; Otherwise do special processing depending on the attribute. 155 156(define_attr "adjust_len" 157 "out_bitop, plus, addto_sp, sext, 158 tsthi, tstpsi, tstsi, compare, compare64, call, 159 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32, 160 ufract, sfract, round, 161 xload, movmem, 162 ashlqi, ashrqi, lshrqi, 163 ashlhi, ashrhi, lshrhi, 164 ashlsi, ashrsi, lshrsi, 165 ashlpsi, ashrpsi, lshrpsi, 166 insert_bits, insv_notbit, insv_notbit_0, insv_notbit_7, 167 no" 168 (const_string "no")) 169 170;; Flavours of instruction set architecture (ISA), used in enabled attribute 171 172;; mov : ISA has no MOVW movw : ISA has MOVW 173;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP 174;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP 175;; lpm : ISA has no LPMX lpmx : ISA has LPMX 176;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX 177;; no_xmega: non-XMEGA core xmega : XMEGA core 178;; no_tiny: non-TINY core tiny : TINY core 179 180(define_attr "isa" 181 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny, 182 standard" 183 (const_string "standard")) 184 185(define_attr "enabled" "" 186 (cond [(eq_attr "isa" "standard") 187 (const_int 1) 188 189 (and (eq_attr "isa" "mov") 190 (match_test "!AVR_HAVE_MOVW")) 191 (const_int 1) 192 193 (and (eq_attr "isa" "movw") 194 (match_test "AVR_HAVE_MOVW")) 195 (const_int 1) 196 197 (and (eq_attr "isa" "rjmp") 198 (match_test "!AVR_HAVE_JMP_CALL")) 199 (const_int 1) 200 201 (and (eq_attr "isa" "jmp") 202 (match_test "AVR_HAVE_JMP_CALL")) 203 (const_int 1) 204 205 (and (eq_attr "isa" "ijmp") 206 (match_test "!AVR_HAVE_EIJMP_EICALL")) 207 (const_int 1) 208 209 (and (eq_attr "isa" "eijmp") 210 (match_test "AVR_HAVE_EIJMP_EICALL")) 211 (const_int 1) 212 213 (and (eq_attr "isa" "lpm") 214 (match_test "!AVR_HAVE_LPMX")) 215 (const_int 1) 216 217 (and (eq_attr "isa" "lpmx") 218 (match_test "AVR_HAVE_LPMX")) 219 (const_int 1) 220 221 (and (eq_attr "isa" "elpm") 222 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX")) 223 (const_int 1) 224 225 (and (eq_attr "isa" "elpmx") 226 (match_test "AVR_HAVE_ELPMX")) 227 (const_int 1) 228 229 (and (eq_attr "isa" "xmega") 230 (match_test "AVR_XMEGA")) 231 (const_int 1) 232 233 (and (eq_attr "isa" "tiny") 234 (match_test "AVR_TINY")) 235 (const_int 1) 236 237 (and (eq_attr "isa" "no_xmega") 238 (match_test "!AVR_XMEGA")) 239 (const_int 1) 240 241 (and (eq_attr "isa" "no_tiny") 242 (match_test "!AVR_TINY")) 243 (const_int 1) 244 245 ] (const_int 0))) 246 247 248;; Define mode iterators 249(define_mode_iterator QIHI [QI HI]) 250(define_mode_iterator QIHI2 [QI HI]) 251(define_mode_iterator QISI [QI HI PSI SI]) 252(define_mode_iterator QIDI [QI HI PSI SI DI]) 253(define_mode_iterator HISI [HI PSI SI]) 254 255(define_mode_iterator ALL1 [QI QQ UQQ]) 256(define_mode_iterator ALL2 [HI HQ UHQ HA UHA]) 257(define_mode_iterator ALL4 [SI SQ USQ SA USA]) 258 259;; All supported move-modes 260(define_mode_iterator MOVMODE [QI QQ UQQ 261 HI HQ UHQ HA UHA 262 SI SQ USQ SA USA 263 SF PSI]) 264 265;; Supported ordered modes that are 2, 3, 4 bytes wide 266(define_mode_iterator ORDERED234 [HI SI PSI 267 HQ UHQ HA UHA 268 SQ USQ SA USA]) 269 270;; Post-reload split of 3, 4 bytes wide moves. 271(define_mode_iterator SPLIT34 [SI SF PSI 272 SQ USQ SA USA]) 273 274;; Define code iterators 275;; Define two incarnations so that we can build the cross product. 276(define_code_iterator any_extend [sign_extend zero_extend]) 277(define_code_iterator any_extend2 [sign_extend zero_extend]) 278(define_code_iterator any_extract [sign_extract zero_extract]) 279(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 280 281(define_code_iterator bitop [xor ior and]) 282(define_code_iterator xior [xor ior]) 283(define_code_iterator eqne [eq ne]) 284 285(define_code_iterator ss_addsub [ss_plus ss_minus]) 286(define_code_iterator us_addsub [us_plus us_minus]) 287(define_code_iterator ss_abs_neg [ss_abs ss_neg]) 288 289;; Define code attributes 290(define_code_attr extend_su 291 [(sign_extend "s") 292 (zero_extend "u")]) 293 294(define_code_attr extend_u 295 [(sign_extend "") 296 (zero_extend "u")]) 297 298(define_code_attr extend_s 299 [(sign_extend "s") 300 (zero_extend "")]) 301 302;; Constrain input operand of widening multiply, i.e. MUL resp. MULS. 303(define_code_attr mul_r_d 304 [(zero_extend "r") 305 (sign_extend "d")]) 306 307(define_code_attr abelian 308 [(ss_minus "") (us_minus "") 309 (ss_plus "%") (us_plus "%")]) 310 311;; Map RTX code to its standard insn name 312(define_code_attr code_stdname 313 [(ashift "ashl") 314 (ashiftrt "ashr") 315 (lshiftrt "lshr") 316 (ior "ior") 317 (xor "xor") 318 (rotate "rotl") 319 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs") 320 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg") 321 ]) 322 323;;======================================================================== 324;; The following is used by nonlocal_goto and setjmp. 325;; The receiver pattern will create no instructions since internally 326;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28 327;; This avoids creating add/sub offsets in frame_pointer save/resore. 328;; The 'null' receiver also avoids problems with optimisation 329;; not recognising incoming jmp and removing code that resets frame_pointer. 330;; The code derived from builtins.c. 331 332(define_expand "nonlocal_goto_receiver" 333 [(set (reg:HI REG_Y) 334 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))] 335 "" 336 { 337 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode); 338 emit_move_insn (virtual_stack_vars_rtx, 339 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset)); 340 /* ; This might change the hard frame pointer in ways that aren't 341 ; apparent to early optimization passes, so force a clobber. */ 342 emit_clobber (hard_frame_pointer_rtx); 343 DONE; 344 }) 345 346 347;; Defining nonlocal_goto_receiver means we must also define this. 348;; even though its function is identical to that in builtins.c 349 350(define_expand "nonlocal_goto" 351 [(use (match_operand 0 "general_operand")) 352 (use (match_operand 1 "general_operand")) 353 (use (match_operand 2 "general_operand")) 354 (use (match_operand 3 "general_operand"))] 355 "" 356 { 357 rtx r_label = copy_to_reg (operands[1]); 358 rtx r_fp = operands[3]; 359 rtx r_sp = operands[2]; 360 361 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 362 363 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 364 365 emit_move_insn (hard_frame_pointer_rtx, r_fp); 366 emit_stack_restore (SAVE_NONLOCAL, r_sp); 367 368 emit_use (hard_frame_pointer_rtx); 369 emit_use (stack_pointer_rtx); 370 371 emit_indirect_jump (r_label); 372 373 DONE; 374 }) 375 376;; "pushqi1" 377;; "pushqq1" "pushuqq1" 378(define_insn "push<mode>1" 379 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP))) 380 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))] 381 "" 382 "@ 383 push %0 384 push __zero_reg__" 385 [(set_attr "length" "1,1")]) 386 387(define_insn "pushhi1_insn" 388 [(set (mem:HI (post_dec:HI (reg:HI REG_SP))) 389 (match_operand:HI 0 "register_operand" "r"))] 390 "" 391 "push %B0\;push %A0" 392 [(set_attr "length" "2")]) 393 394;; All modes for a multi-byte push. We must include complex modes here too, 395;; lest emit_single_push_insn "helpfully" create the auto-inc itself. 396(define_mode_iterator MPUSH 397 [CQI 398 HI CHI HA UHA HQ UHQ 399 SI CSI SA USA SQ USQ 400 DI CDI DA UDA DQ UDQ 401 TA UTA 402 SF SC 403 PSI]) 404 405(define_expand "push<mode>1" 406 [(match_operand:MPUSH 0 "" "")] 407 "" 408 { 409 if (MEM_P (operands[0]) 410 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0]))) 411 { 412 // Avoid (subreg (mem)) for non-generic address spaces. Because 413 // of the poor addressing capabilities of these spaces it's better to 414 // load them in one chunk. And it avoids PR61443. 415 416 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]); 417 } 418 else if (REG_P (operands[0]) 419 && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER, 420 LAST_VIRTUAL_REGISTER)) 421 { 422 // Byte-wise pushing of virtual regs might result in something like 423 // 424 // (set (mem:QI (post_dec:HI (reg:HI 32 SP))) 425 // (subreg:QI (plus:HI (reg:HI 28) 426 // (const_int 17)) 0)) 427 // 428 // after elimination. This cannot be handled by reload, cf. PR64452. 429 // Reload virtuals in one chunk. That way it's possible to reload 430 // above situation and finally 431 // 432 // (set (reg:HI **) 433 // (const_int 17)) 434 // (set (reg:HI **) 435 // (plus:HI (reg:HI **) 436 // (reg:HI 28))) 437 // (set (mem:HI (post_dec:HI (reg:HI 32 SP)) 438 // (reg:HI **))) 439 440 emit_insn (gen_pushhi1_insn (operands[0])); 441 DONE; 442 } 443 444 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i) 445 { 446 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); 447 if (part != const0_rtx) 448 part = force_reg (QImode, part); 449 emit_insn (gen_pushqi1 (part)); 450 } 451 DONE; 452 }) 453 454;; Notice a special-case when adding N to SP where N results in a 455;; zero REG_ARGS_SIZE. This is equivalent to a move from FP. 456(define_split 457 [(set (reg:HI REG_SP) 458 (match_operand:HI 0 "register_operand" ""))] 459 "reload_completed 460 && frame_pointer_needed 461 && !cfun->calls_alloca 462 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)" 463 [(set (reg:HI REG_SP) 464 (reg:HI REG_Y))]) 465 466;;======================================================================== 467;; Move stuff around 468 469;; "loadqi_libgcc" 470;; "loadhi_libgcc" 471;; "loadpsi_libgcc" 472;; "loadsi_libgcc" 473;; "loadsf_libgcc" 474(define_expand "load<mode>_libgcc" 475 [(set (match_dup 3) 476 (match_dup 2)) 477 (set (reg:MOVMODE 22) 478 (match_operand:MOVMODE 1 "memory_operand" "")) 479 (set (match_operand:MOVMODE 0 "register_operand" "") 480 (reg:MOVMODE 22))] 481 "avr_load_libgcc_p (operands[1])" 482 { 483 operands[3] = gen_rtx_REG (HImode, REG_Z); 484 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX); 485 operands[1] = replace_equiv_address (operands[1], operands[3]); 486 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH); 487 }) 488 489;; "load_qi_libgcc" 490;; "load_hi_libgcc" 491;; "load_psi_libgcc" 492;; "load_si_libgcc" 493;; "load_sf_libgcc" 494(define_insn "load_<mode>_libgcc" 495 [(set (reg:MOVMODE 22) 496 (match_operand:MOVMODE 0 "memory_operand" "m,m"))] 497 "avr_load_libgcc_p (operands[0]) 498 && REG_P (XEXP (operands[0], 0)) 499 && REG_Z == REGNO (XEXP (operands[0], 0))" 500 { 501 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode)); 502 return "%~call __load_%0"; 503 } 504 [(set_attr "length" "1,2") 505 (set_attr "isa" "rjmp,jmp") 506 (set_attr "cc" "clobber")]) 507 508 509;; "xload8qi_A" 510;; "xload8qq_A" "xload8uqq_A" 511(define_insn_and_split "xload8<mode>_A" 512 [(set (match_operand:ALL1 0 "register_operand" "=r") 513 (match_operand:ALL1 1 "memory_operand" "m")) 514 (clobber (reg:HI REG_Z))] 515 "can_create_pseudo_p() 516 && !avr_xload_libgcc_p (<MODE>mode) 517 && avr_mem_memx_p (operands[1]) 518 && REG_P (XEXP (operands[1], 0))" 519 { gcc_unreachable(); } 520 "&& 1" 521 [(clobber (const_int 0))] 522 { 523 /* ; Split away the high part of the address. GCC's register allocator 524 ; in not able to allocate segment registers and reload the resulting 525 ; expressions. Notice that no address register can hold a PSImode. */ 526 527 rtx_insn *insn; 528 rtx addr = XEXP (operands[1], 0); 529 rtx hi8 = gen_reg_rtx (QImode); 530 rtx reg_z = gen_rtx_REG (HImode, REG_Z); 531 532 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); 533 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2)); 534 535 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8)); 536 set_mem_addr_space (SET_SRC (single_set (insn)), 537 MEM_ADDR_SPACE (operands[1])); 538 DONE; 539 }) 540 541;; "xloadqi_A" "xloadqq_A" "xloaduqq_A" 542;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A" 543;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A" 544;; "xloadpsi_A" 545;; "xloadsf_A" 546(define_insn_and_split "xload<mode>_A" 547 [(set (match_operand:MOVMODE 0 "register_operand" "=r") 548 (match_operand:MOVMODE 1 "memory_operand" "m")) 549 (clobber (reg:MOVMODE 22)) 550 (clobber (reg:QI 21)) 551 (clobber (reg:HI REG_Z))] 552 "can_create_pseudo_p() 553 && avr_mem_memx_p (operands[1]) 554 && REG_P (XEXP (operands[1], 0))" 555 { gcc_unreachable(); } 556 "&& 1" 557 [(clobber (const_int 0))] 558 { 559 rtx addr = XEXP (operands[1], 0); 560 rtx reg_z = gen_rtx_REG (HImode, REG_Z); 561 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2); 562 addr_space_t as = MEM_ADDR_SPACE (operands[1]); 563 rtx_insn *insn; 564 565 /* Split the address to R21:Z */ 566 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); 567 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8); 568 569 /* Load with code from libgcc */ 570 insn = emit_insn (gen_xload_<mode>_libgcc ()); 571 set_mem_addr_space (SET_SRC (single_set (insn)), as); 572 573 /* Move to destination */ 574 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22)); 575 576 DONE; 577 }) 578 579;; Move value from address space memx to a register 580;; These insns must be prior to respective generic move insn. 581 582;; "xloadqi_8" 583;; "xloadqq_8" "xloaduqq_8" 584(define_insn "xload<mode>_8" 585 [(set (match_operand:ALL1 0 "register_operand" "=&r,r") 586 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r") 587 (reg:HI REG_Z))))] 588 "!avr_xload_libgcc_p (<MODE>mode)" 589 { 590 return avr_out_xload (insn, operands, NULL); 591 } 592 [(set_attr "length" "4,4") 593 (set_attr "adjust_len" "*,xload") 594 (set_attr "isa" "lpmx,lpm") 595 (set_attr "cc" "none")]) 596 597;; R21:Z : 24-bit source address 598;; R22 : 1-4 byte output 599 600;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc" 601;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc" 602;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc" 603;; "xload_sf_libgcc" 604;; "xload_psi_libgcc" 605(define_insn "xload_<mode>_libgcc" 606 [(set (reg:MOVMODE 22) 607 (mem:MOVMODE (lo_sum:PSI (reg:QI 21) 608 (reg:HI REG_Z)))) 609 (clobber (reg:QI 21)) 610 (clobber (reg:HI REG_Z))] 611 "avr_xload_libgcc_p (<MODE>mode)" 612 { 613 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode)); 614 615 output_asm_insn ("%~call __xload_%0", &x_bytes); 616 return ""; 617 } 618 [(set_attr "type" "xcall") 619 (set_attr "cc" "clobber")]) 620 621 622;; General move expanders 623 624;; "movqi" "movqq" "movuqq" 625;; "movhi" "movhq" "movuhq" "movha" "movuha" 626;; "movsi" "movsq" "movusq" "movsa" "movusa" 627;; "movsf" 628;; "movpsi" 629(define_expand "mov<mode>" 630 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") 631 (match_operand:MOVMODE 1 "general_operand" ""))] 632 "" 633 { 634 rtx dest = operands[0]; 635 rtx src = avr_eval_addr_attrib (operands[1]); 636 637 if (avr_mem_flash_p (dest)) 638 DONE; 639 640 if (QImode == <MODE>mode 641 && SUBREG_P (src) 642 && CONSTANT_ADDRESS_P (SUBREG_REG (src)) 643 && can_create_pseudo_p()) 644 { 645 // store_bitfield may want to store a SYMBOL_REF or CONST in a 646 // structure that's represented as PSImode. As the upper 16 bits 647 // of PSImode cannot be expressed as an HImode subreg, the rhs is 648 // decomposed into QImode (word_mode) subregs of SYMBOL_REF, 649 // CONST or LABEL_REF; cf. PR71103. 650 651 rtx const_addr = SUBREG_REG (src); 652 operands[1] = src = copy_rtx (src); 653 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr); 654 } 655 656 /* One of the operands has to be in a register. */ 657 if (!register_operand (dest, <MODE>mode) 658 && !reg_or_0_operand (src, <MODE>mode)) 659 { 660 operands[1] = src = copy_to_mode_reg (<MODE>mode, src); 661 } 662 663 if (avr_mem_memx_p (src)) 664 { 665 rtx addr = XEXP (src, 0); 666 667 if (!REG_P (addr)) 668 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr)); 669 670 if (!avr_xload_libgcc_p (<MODE>mode)) 671 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1. 672 ; insn-emit does not depend on the mode, it's all about operands. */ 673 emit_insn (gen_xload8qi_A (dest, src)); 674 else 675 emit_insn (gen_xload<mode>_A (dest, src)); 676 677 DONE; 678 } 679 680 if (avr_load_libgcc_p (src)) 681 { 682 /* For the small devices, do loads per libgcc call. */ 683 emit_insn (gen_load<mode>_libgcc (dest, src)); 684 DONE; 685 } 686 }) 687 688;;======================================================================== 689;; move byte 690;; The last alternative (any immediate constant to any register) is 691;; very expensive. It should be optimized by peephole2 if a scratch 692;; register is available, but then that register could just as well be 693;; allocated for the variable we are loading. But, most of NO_LD_REGS 694;; are call-saved registers, and most of LD_REGS are call-used registers, 695;; so this may still be a win for registers live across function calls. 696 697;; "movqi_insn" 698;; "movqq_insn" "movuqq_insn" 699(define_insn "mov<mode>_insn" 700 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") 701 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] 702 "register_operand (operands[0], <MODE>mode) 703 || reg_or_0_operand (operands[1], <MODE>mode)" 704 { 705 return output_movqi (insn, operands, NULL); 706 } 707 [(set_attr "length" "1,1,5,5,1,1,4") 708 (set_attr "adjust_len" "mov8") 709 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) 710 711;; This is used in peephole2 to optimize loading immediate constants 712;; if a scratch register from LD_REGS happens to be available. 713 714;; "*reload_inqi" 715;; "*reload_inqq" "*reload_inuqq" 716(define_insn "*reload_in<mode>" 717 [(set (match_operand:ALL1 0 "register_operand" "=l") 718 (match_operand:ALL1 1 "const_operand" "i")) 719 (clobber (match_operand:QI 2 "register_operand" "=&d"))] 720 "reload_completed" 721 "ldi %2,lo8(%1) 722 mov %0,%2" 723 [(set_attr "length" "2") 724 (set_attr "cc" "none")]) 725 726(define_peephole2 727 [(match_scratch:QI 2 "d") 728 (set (match_operand:ALL1 0 "l_register_operand" "") 729 (match_operand:ALL1 1 "const_operand" ""))] 730 ; No need for a clobber reg for 0x0, 0x01 or 0xff 731 "!satisfies_constraint_Y00 (operands[1]) 732 && !satisfies_constraint_Y01 (operands[1]) 733 && !satisfies_constraint_Ym1 (operands[1])" 734 [(parallel [(set (match_dup 0) 735 (match_dup 1)) 736 (clobber (match_dup 2))])]) 737 738;;============================================================================ 739;; move word (16 bit) 740 741;; Move register $1 to the Stack Pointer register SP. 742;; This insn is emit during function prologue/epilogue generation. 743;; $2 = 0: We know that IRQs are off 744;; $2 = 1: We know that IRQs are on 745;; $2 = 2: SP has 8 bits only, IRQ state does not matter 746;; $2 = -1: We don't know anything about IRQ on/off 747;; Always write SP via unspec, see PR50063 748 749(define_insn "movhi_sp_r" 750 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q") 751 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r") 752 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")] 753 UNSPECV_WRITE_SP))] 754 "" 755 "@ 756 out %B0,%B1\;out %A0,%A1 757 cli\;out %B0,%B1\;sei\;out %A0,%A1 758 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1 759 out %A0,%A1 760 out %A0,%A1\;out %B0,%B1" 761 [(set_attr "length" "2,4,5,1,2") 762 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega") 763 (set_attr "cc" "none")]) 764 765(define_peephole2 766 [(match_scratch:QI 2 "d") 767 (set (match_operand:ALL2 0 "l_register_operand" "") 768 (match_operand:ALL2 1 "const_or_immediate_operand" ""))] 769 "operands[1] != CONST0_RTX (<MODE>mode)" 770 [(parallel [(set (match_dup 0) 771 (match_dup 1)) 772 (clobber (match_dup 2))])]) 773 774;; '*' because it is not used in rtl generation, only in above peephole 775;; "*reload_inhi" 776;; "*reload_inhq" "*reload_inuhq" 777;; "*reload_inha" "*reload_inuha" 778(define_insn "*reload_in<mode>" 779 [(set (match_operand:ALL2 0 "l_register_operand" "=l") 780 (match_operand:ALL2 1 "immediate_operand" "i")) 781 (clobber (match_operand:QI 2 "register_operand" "=&d"))] 782 "reload_completed" 783 { 784 return output_reload_inhi (operands, operands[2], NULL); 785 } 786 [(set_attr "length" "4") 787 (set_attr "adjust_len" "reload_in16") 788 (set_attr "cc" "clobber")]) 789 790;; "*movhi" 791;; "*movhq" "*movuhq" 792;; "*movha" "*movuha" 793(define_insn "*mov<mode>" 794 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r") 795 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))] 796 "register_operand (operands[0], <MODE>mode) 797 || reg_or_0_operand (operands[1], <MODE>mode)" 798 { 799 return output_movhi (insn, operands, NULL); 800 } 801 [(set_attr "length" "2,2,6,7,2,6,5,2") 802 (set_attr "adjust_len" "mov16") 803 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")]) 804 805(define_peephole2 ; movw 806 [(set (match_operand:ALL1 0 "even_register_operand" "") 807 (match_operand:ALL1 1 "even_register_operand" "")) 808 (set (match_operand:ALL1 2 "odd_register_operand" "") 809 (match_operand:ALL1 3 "odd_register_operand" ""))] 810 "AVR_HAVE_MOVW 811 && REGNO (operands[0]) == REGNO (operands[2]) - 1 812 && REGNO (operands[1]) == REGNO (operands[3]) - 1" 813 [(set (match_dup 4) 814 (match_dup 5))] 815 { 816 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0])); 817 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1])); 818 }) 819 820(define_peephole2 ; movw_r 821 [(set (match_operand:ALL1 0 "odd_register_operand" "") 822 (match_operand:ALL1 1 "odd_register_operand" "")) 823 (set (match_operand:ALL1 2 "even_register_operand" "") 824 (match_operand:ALL1 3 "even_register_operand" ""))] 825 "AVR_HAVE_MOVW 826 && REGNO (operands[2]) == REGNO (operands[0]) - 1 827 && REGNO (operands[3]) == REGNO (operands[1]) - 1" 828 [(set (match_dup 4) 829 (match_dup 5))] 830 { 831 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2])); 832 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3])); 833 }) 834 835;; For LPM loads from AS1 we split 836;; R = *Z 837;; to 838;; R = *Z++ 839;; Z = Z - sizeof (R) 840;; 841;; so that the second instruction can be optimized out. 842 843(define_split ; "split-lpmx" 844 [(set (match_operand:HISI 0 "register_operand" "") 845 (match_operand:HISI 1 "memory_operand" ""))] 846 "reload_completed 847 && AVR_HAVE_LPMX" 848 [(set (match_dup 0) 849 (match_dup 2)) 850 (set (match_dup 3) 851 (plus:HI (match_dup 3) 852 (match_dup 4)))] 853 { 854 rtx addr = XEXP (operands[1], 0); 855 856 if (!avr_mem_flash_p (operands[1]) 857 || !REG_P (addr) 858 || reg_overlap_mentioned_p (addr, operands[0])) 859 { 860 FAIL; 861 } 862 863 operands[2] = replace_equiv_address (operands[1], 864 gen_rtx_POST_INC (Pmode, addr)); 865 operands[3] = addr; 866 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode); 867 }) 868 869;;========================================================================== 870;; xpointer move (24 bit) 871 872(define_peephole2 ; *reload_inpsi 873 [(match_scratch:QI 2 "d") 874 (set (match_operand:PSI 0 "l_register_operand" "") 875 (match_operand:PSI 1 "immediate_operand" "")) 876 (match_dup 2)] 877 "operands[1] != const0_rtx 878 && operands[1] != constm1_rtx" 879 [(parallel [(set (match_dup 0) 880 (match_dup 1)) 881 (clobber (match_dup 2))])]) 882 883;; '*' because it is not used in rtl generation. 884(define_insn "*reload_inpsi" 885 [(set (match_operand:PSI 0 "register_operand" "=r") 886 (match_operand:PSI 1 "immediate_operand" "i")) 887 (clobber (match_operand:QI 2 "register_operand" "=&d"))] 888 "reload_completed" 889 { 890 return avr_out_reload_inpsi (operands, operands[2], NULL); 891 } 892 [(set_attr "length" "6") 893 (set_attr "adjust_len" "reload_in24") 894 (set_attr "cc" "clobber")]) 895 896(define_insn "*movpsi" 897 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 898 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))] 899 "register_operand (operands[0], PSImode) 900 || register_operand (operands[1], PSImode) 901 || const0_rtx == operands[1]" 902 { 903 return avr_out_movpsi (insn, operands, NULL); 904 } 905 [(set_attr "length" "3,3,8,9,4,10") 906 (set_attr "adjust_len" "mov24") 907 (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) 908 909;;========================================================================== 910;; move double word (32 bit) 911 912(define_peephole2 ; *reload_insi 913 [(match_scratch:QI 2 "d") 914 (set (match_operand:ALL4 0 "l_register_operand" "") 915 (match_operand:ALL4 1 "immediate_operand" "")) 916 (match_dup 2)] 917 "operands[1] != CONST0_RTX (<MODE>mode)" 918 [(parallel [(set (match_dup 0) 919 (match_dup 1)) 920 (clobber (match_dup 2))])]) 921 922;; '*' because it is not used in rtl generation. 923;; "*reload_insi" 924;; "*reload_insq" "*reload_inusq" 925;; "*reload_insa" "*reload_inusa" 926(define_insn "*reload_insi" 927 [(set (match_operand:ALL4 0 "register_operand" "=r") 928 (match_operand:ALL4 1 "immediate_operand" "n Ynn")) 929 (clobber (match_operand:QI 2 "register_operand" "=&d"))] 930 "reload_completed" 931 { 932 return output_reload_insisf (operands, operands[2], NULL); 933 } 934 [(set_attr "length" "8") 935 (set_attr "adjust_len" "reload_in32") 936 (set_attr "cc" "clobber")]) 937 938 939;; "*movsi" 940;; "*movsq" "*movusq" 941;; "*movsa" "*movusa" 942(define_insn "*mov<mode>" 943 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r") 944 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))] 945 "register_operand (operands[0], <MODE>mode) 946 || reg_or_0_operand (operands[1], <MODE>mode)" 947 { 948 return output_movsisf (insn, operands, NULL); 949 } 950 [(set_attr "length" "4,4,8,9,4,10") 951 (set_attr "adjust_len" "mov32") 952 (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) 953 954;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 955;; move floating point numbers (32 bit) 956 957(define_insn "*movsf" 958 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") 959 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))] 960 "register_operand (operands[0], SFmode) 961 || reg_or_0_operand (operands[1], SFmode)" 962 { 963 return output_movsisf (insn, operands, NULL); 964 } 965 [(set_attr "length" "4,4,8,9,4,10") 966 (set_attr "adjust_len" "mov32") 967 (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) 968 969(define_peephole2 ; *reload_insf 970 [(match_scratch:QI 2 "d") 971 (set (match_operand:SF 0 "l_register_operand" "") 972 (match_operand:SF 1 "const_double_operand" "")) 973 (match_dup 2)] 974 "operands[1] != CONST0_RTX (SFmode)" 975 [(parallel [(set (match_dup 0) 976 (match_dup 1)) 977 (clobber (match_dup 2))])]) 978 979;; '*' because it is not used in rtl generation. 980(define_insn "*reload_insf" 981 [(set (match_operand:SF 0 "register_operand" "=r") 982 (match_operand:SF 1 "const_double_operand" "F")) 983 (clobber (match_operand:QI 2 "register_operand" "=&d"))] 984 "reload_completed" 985 { 986 return output_reload_insisf (operands, operands[2], NULL); 987 } 988 [(set_attr "length" "8") 989 (set_attr "adjust_len" "reload_in32") 990 (set_attr "cc" "clobber")]) 991 992;;========================================================================= 993;; move string (like memcpy) 994 995(define_expand "movmemhi" 996 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 997 (match_operand:BLK 1 "memory_operand" "")) 998 (use (match_operand:HI 2 "const_int_operand" "")) 999 (use (match_operand:HI 3 "const_int_operand" ""))])] 1000 "" 1001 { 1002 if (avr_emit_movmemhi (operands)) 1003 DONE; 1004 1005 FAIL; 1006 }) 1007 1008(define_mode_attr MOVMEM_r_d [(QI "r") 1009 (HI "wd")]) 1010 1011;; $0 : Address Space 1012;; $1, $2 : Loop register 1013;; R30 : source address 1014;; R26 : destination address 1015 1016;; "movmem_qi" 1017;; "movmem_hi" 1018(define_insn "movmem_<mode>" 1019 [(set (mem:BLK (reg:HI REG_X)) 1020 (mem:BLK (reg:HI REG_Z))) 1021 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1022 UNSPEC_MOVMEM) 1023 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>")) 1024 (clobber (reg:HI REG_X)) 1025 (clobber (reg:HI REG_Z)) 1026 (clobber (reg:QI LPM_REGNO)) 1027 (clobber (match_operand:QIHI 2 "register_operand" "=1"))] 1028 "" 1029 { 1030 return avr_out_movmem (insn, operands, NULL); 1031 } 1032 [(set_attr "adjust_len" "movmem") 1033 (set_attr "cc" "clobber")]) 1034 1035 1036;; $0 : Address Space 1037;; $1 : RAMPZ RAM address 1038;; R24 : #bytes and loop register 1039;; R23:Z : 24-bit source address 1040;; R26 : 16-bit destination address 1041 1042;; "movmemx_qi" 1043;; "movmemx_hi" 1044(define_insn "movmemx_<mode>" 1045 [(set (mem:BLK (reg:HI REG_X)) 1046 (mem:BLK (lo_sum:PSI (reg:QI 23) 1047 (reg:HI REG_Z)))) 1048 (unspec [(match_operand:QI 0 "const_int_operand" "n")] 1049 UNSPEC_MOVMEM) 1050 (use (reg:QIHI 24)) 1051 (clobber (reg:HI REG_X)) 1052 (clobber (reg:HI REG_Z)) 1053 (clobber (reg:QI LPM_REGNO)) 1054 (clobber (reg:HI 24)) 1055 (clobber (reg:QI 23)) 1056 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))] 1057 "" 1058 "%~call __movmemx_<mode>" 1059 [(set_attr "type" "xcall") 1060 (set_attr "cc" "clobber")]) 1061 1062 1063;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 1064;; memset (%0, %2, %1) 1065 1066(define_expand "setmemhi" 1067 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 1068 (match_operand 2 "const_int_operand" "")) 1069 (use (match_operand:HI 1 "const_int_operand" "")) 1070 (use (match_operand:HI 3 "const_int_operand" "")) 1071 (clobber (match_scratch:HI 5 "")) 1072 (clobber (match_dup 4))])] 1073 "" 1074 { 1075 rtx addr0; 1076 machine_mode mode; 1077 1078 /* If value to set is not zero, use the library routine. */ 1079 if (operands[2] != const0_rtx) 1080 FAIL; 1081 1082 if (!CONST_INT_P (operands[1])) 1083 FAIL; 1084 1085 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode; 1086 operands[4] = gen_rtx_SCRATCH (mode); 1087 operands[1] = copy_to_mode_reg (mode, 1088 gen_int_mode (INTVAL (operands[1]), mode)); 1089 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 1090 operands[0] = gen_rtx_MEM (BLKmode, addr0); 1091 }) 1092 1093 1094(define_insn "*clrmemqi" 1095 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) 1096 (const_int 0)) 1097 (use (match_operand:QI 1 "register_operand" "r")) 1098 (use (match_operand:QI 2 "const_int_operand" "n")) 1099 (clobber (match_scratch:HI 3 "=0")) 1100 (clobber (match_scratch:QI 4 "=&1"))] 1101 "" 1102 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b" 1103 [(set_attr "length" "3") 1104 (set_attr "cc" "clobber")]) 1105 1106 1107(define_insn "*clrmemhi" 1108 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e")) 1109 (const_int 0)) 1110 (use (match_operand:HI 1 "register_operand" "!w,d")) 1111 (use (match_operand:HI 2 "const_int_operand" "n,n")) 1112 (clobber (match_scratch:HI 3 "=0,0")) 1113 (clobber (match_scratch:HI 4 "=&1,&1"))] 1114 "" 1115 "@ 1116 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b 1117 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b" 1118 [(set_attr "length" "3,4") 1119 (set_attr "cc" "clobber,clobber")]) 1120 1121(define_expand "strlenhi" 1122 [(set (match_dup 4) 1123 (unspec:HI [(match_operand:BLK 1 "memory_operand" "") 1124 (match_operand:QI 2 "const_int_operand" "") 1125 (match_operand:HI 3 "immediate_operand" "")] 1126 UNSPEC_STRLEN)) 1127 (set (match_dup 4) 1128 (plus:HI (match_dup 4) 1129 (const_int -1))) 1130 (parallel [(set (match_operand:HI 0 "register_operand" "") 1131 (minus:HI (match_dup 4) 1132 (match_dup 5))) 1133 (clobber (scratch:QI))])] 1134 "" 1135 { 1136 rtx addr; 1137 if (operands[2] != const0_rtx) 1138 FAIL; 1139 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 1140 operands[1] = gen_rtx_MEM (BLKmode, addr); 1141 operands[5] = addr; 1142 operands[4] = gen_reg_rtx (HImode); 1143 }) 1144 1145(define_insn "*strlenhi" 1146 [(set (match_operand:HI 0 "register_operand" "=e") 1147 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0")) 1148 (const_int 0) 1149 (match_operand:HI 2 "immediate_operand" "i")] 1150 UNSPEC_STRLEN))] 1151 "" 1152 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b" 1153 [(set_attr "length" "3") 1154 (set_attr "cc" "clobber")]) 1155 1156;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1157; add bytes 1158 1159;; "addqi3" 1160;; "addqq3" "adduqq3" 1161(define_insn "add<mode>3" 1162 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r") 1163 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0") 1164 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))] 1165 "" 1166 "@ 1167 add %0,%2 1168 subi %0,lo8(-(%2)) 1169 inc %0 1170 dec %0 1171 inc %0\;inc %0 1172 dec %0\;dec %0" 1173 [(set_attr "length" "1,1,1,1,2,2") 1174 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")]) 1175 1176;; "addhi3" 1177;; "addhq3" "adduhq3" 1178;; "addha3" "adduha3" 1179(define_expand "add<mode>3" 1180 [(set (match_operand:ALL2 0 "register_operand" "") 1181 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "") 1182 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))] 1183 "" 1184 { 1185 if (CONST_INT_P (operands[2])) 1186 { 1187 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode); 1188 1189 if (can_create_pseudo_p() 1190 && !stack_register_operand (operands[0], HImode) 1191 && !stack_register_operand (operands[1], HImode) 1192 && !d_register_operand (operands[0], HImode) 1193 && !d_register_operand (operands[1], HImode)) 1194 { 1195 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2])); 1196 DONE; 1197 } 1198 } 1199 1200 if (CONST_FIXED_P (operands[2])) 1201 { 1202 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2])); 1203 DONE; 1204 } 1205 }) 1206 1207 1208(define_insn "*addhi3_zero_extend" 1209 [(set (match_operand:HI 0 "register_operand" "=r,*?r") 1210 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0")) 1211 (match_operand:HI 2 "register_operand" "0 ,r")))] 1212 "" 1213 "@ 1214 add %A0,%1\;adc %B0,__zero_reg__ 1215 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__" 1216 [(set_attr "length" "2,3") 1217 (set_attr "cc" "set_n")]) 1218 1219(define_insn "*addhi3_zero_extend1" 1220 [(set (match_operand:HI 0 "register_operand" "=r") 1221 (plus:HI (match_operand:HI 1 "register_operand" "0") 1222 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1223 "" 1224 "add %A0,%2\;adc %B0,__zero_reg__" 1225 [(set_attr "length" "2") 1226 (set_attr "cc" "set_n")]) 1227 1228(define_insn "*addhi3.sign_extend1" 1229 [(set (match_operand:HI 0 "register_operand" "=r") 1230 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r")) 1231 (match_operand:HI 2 "register_operand" "0")))] 1232 "" 1233 { 1234 return reg_overlap_mentioned_p (operands[0], operands[1]) 1235 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0" 1236 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0"; 1237 } 1238 [(set_attr "length" "5") 1239 (set_attr "cc" "clobber")]) 1240 1241(define_insn "*addhi3_zero_extend.const" 1242 [(set (match_operand:HI 0 "register_operand" "=d") 1243 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1244 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))] 1245 "" 1246 "subi %A0,%n2\;sbc %B0,%B0" 1247 [(set_attr "length" "2") 1248 (set_attr "cc" "set_czn")]) 1249 1250(define_insn "*usum_widenqihi3" 1251 [(set (match_operand:HI 0 "register_operand" "=r") 1252 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1253 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1254 "" 1255 "add %A0,%2\;clr %B0\;rol %B0" 1256 [(set_attr "length" "3") 1257 (set_attr "cc" "clobber")]) 1258 1259(define_insn "*udiff_widenqihi3" 1260 [(set (match_operand:HI 0 "register_operand" "=r") 1261 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) 1262 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1263 "" 1264 "sub %A0,%2\;sbc %B0,%B0" 1265 [(set_attr "length" "2") 1266 (set_attr "cc" "set_czn")]) 1267 1268(define_insn "*addhi3_sp" 1269 [(set (match_operand:HI 1 "stack_register_operand" "=q") 1270 (plus:HI (match_operand:HI 2 "stack_register_operand" "q") 1271 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))] 1272 "" 1273 { 1274 return avr_out_addto_sp (operands, NULL); 1275 } 1276 [(set_attr "length" "6") 1277 (set_attr "adjust_len" "addto_sp")]) 1278 1279;; "*addhi3" 1280;; "*addhq3" "*adduhq3" 1281;; "*addha3" "*adduha3" 1282(define_insn "*add<mode>3" 1283 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d") 1284 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0") 1285 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))] 1286 "" 1287 { 1288 return avr_out_plus (insn, operands); 1289 } 1290 [(set_attr "length" "2") 1291 (set_attr "adjust_len" "plus") 1292 (set_attr "cc" "plus")]) 1293 1294;; Adding a constant to NO_LD_REGS might have lead to a reload of 1295;; that constant to LD_REGS. We don't add a scratch to *addhi3 1296;; itself because that insn is special to reload. 1297 1298(define_peephole2 ; addhi3_clobber 1299 [(set (match_operand:ALL2 0 "d_register_operand" "") 1300 (match_operand:ALL2 1 "const_operand" "")) 1301 (set (match_operand:ALL2 2 "l_register_operand" "") 1302 (plus:ALL2 (match_dup 2) 1303 (match_dup 0)))] 1304 "peep2_reg_dead_p (2, operands[0])" 1305 [(parallel [(set (match_dup 2) 1306 (plus:ALL2 (match_dup 2) 1307 (match_dup 1))) 1308 (clobber (match_dup 3))])] 1309 { 1310 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0); 1311 }) 1312 1313;; Same, but with reload to NO_LD_REGS 1314;; Combine *reload_inhi with *addhi3 1315 1316(define_peephole2 ; addhi3_clobber 1317 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "") 1318 (match_operand:ALL2 1 "const_operand" "")) 1319 (clobber (match_operand:QI 2 "d_register_operand" ""))]) 1320 (set (match_operand:ALL2 3 "l_register_operand" "") 1321 (plus:ALL2 (match_dup 3) 1322 (match_dup 0)))] 1323 "peep2_reg_dead_p (2, operands[0])" 1324 [(parallel [(set (match_dup 3) 1325 (plus:ALL2 (match_dup 3) 1326 (match_dup 1))) 1327 (clobber (match_dup 2))])]) 1328 1329;; "addhi3_clobber" 1330;; "addhq3_clobber" "adduhq3_clobber" 1331;; "addha3_clobber" "adduha3_clobber" 1332(define_insn "add<mode>3_clobber" 1333 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r") 1334 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0") 1335 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn"))) 1336 (clobber (match_scratch:QI 3 "=X ,X ,&d"))] 1337 "" 1338 { 1339 return avr_out_plus (insn, operands); 1340 } 1341 [(set_attr "length" "4") 1342 (set_attr "adjust_len" "plus") 1343 (set_attr "cc" "plus")]) 1344 1345 1346;; "addsi3" 1347;; "addsq3" "addusq3" 1348;; "addsa3" "addusa3" 1349(define_insn "add<mode>3" 1350 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 1351 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0") 1352 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn"))) 1353 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 1354 "" 1355 { 1356 return avr_out_plus (insn, operands); 1357 } 1358 [(set_attr "length" "4") 1359 (set_attr "adjust_len" "plus") 1360 (set_attr "cc" "plus")]) 1361 1362(define_insn "*addpsi3_zero_extend.qi" 1363 [(set (match_operand:PSI 0 "register_operand" "=r") 1364 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 1365 (match_operand:PSI 2 "register_operand" "0")))] 1366 "" 1367 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__" 1368 [(set_attr "length" "3") 1369 (set_attr "cc" "set_n")]) 1370 1371(define_insn "*addpsi3_zero_extend.hi" 1372 [(set (match_operand:PSI 0 "register_operand" "=r") 1373 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1374 (match_operand:PSI 2 "register_operand" "0")))] 1375 "" 1376 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__" 1377 [(set_attr "length" "3") 1378 (set_attr "cc" "set_n")]) 1379 1380(define_insn "*addpsi3_sign_extend.hi" 1381 [(set (match_operand:PSI 0 "register_operand" "=r") 1382 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r")) 1383 (match_operand:PSI 2 "register_operand" "0")))] 1384 "" 1385 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0" 1386 [(set_attr "length" "5") 1387 (set_attr "cc" "set_n")]) 1388 1389(define_insn "*addsi3_zero_extend" 1390 [(set (match_operand:SI 0 "register_operand" "=r") 1391 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 1392 (match_operand:SI 2 "register_operand" "0")))] 1393 "" 1394 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 1395 [(set_attr "length" "4") 1396 (set_attr "cc" "set_n")]) 1397 1398(define_insn "*addsi3_zero_extend.hi" 1399 [(set (match_operand:SI 0 "register_operand" "=r") 1400 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) 1401 (match_operand:SI 2 "register_operand" "0")))] 1402 "" 1403 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 1404 [(set_attr "length" "4") 1405 (set_attr "cc" "set_n")]) 1406 1407(define_insn "addpsi3" 1408 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r") 1409 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0") 1410 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n"))) 1411 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))] 1412 "" 1413 { 1414 return avr_out_plus (insn, operands); 1415 } 1416 [(set_attr "length" "3") 1417 (set_attr "adjust_len" "plus") 1418 (set_attr "cc" "plus")]) 1419 1420(define_insn "subpsi3" 1421 [(set (match_operand:PSI 0 "register_operand" "=r") 1422 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 1423 (match_operand:PSI 2 "register_operand" "r")))] 1424 "" 1425 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2" 1426 [(set_attr "length" "3") 1427 (set_attr "cc" "set_czn")]) 1428 1429(define_insn "*subpsi3_zero_extend.qi" 1430 [(set (match_operand:PSI 0 "register_operand" "=r") 1431 (minus:PSI (match_operand:SI 1 "register_operand" "0") 1432 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))] 1433 "" 1434 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__" 1435 [(set_attr "length" "3") 1436 (set_attr "cc" "set_czn")]) 1437 1438(define_insn "*subpsi3_zero_extend.hi" 1439 [(set (match_operand:PSI 0 "register_operand" "=r") 1440 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 1441 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 1442 "" 1443 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__" 1444 [(set_attr "length" "3") 1445 (set_attr "cc" "set_czn")]) 1446 1447(define_insn "*subpsi3_sign_extend.hi" 1448 [(set (match_operand:PSI 0 "register_operand" "=r") 1449 (minus:PSI (match_operand:PSI 1 "register_operand" "0") 1450 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 1451 "" 1452 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0" 1453 [(set_attr "length" "5") 1454 (set_attr "cc" "set_czn")]) 1455 1456;----------------------------------------------------------------------------- 1457; sub bytes 1458 1459;; "subqi3" 1460;; "subqq3" "subuqq3" 1461(define_insn "sub<mode>3" 1462 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r") 1463 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0") 1464 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))] 1465 "" 1466 "@ 1467 sub %0,%2 1468 subi %0,lo8(%2) 1469 dec %0 1470 inc %0 1471 dec %0\;dec %0 1472 inc %0\;inc %0" 1473 [(set_attr "length" "1,1,1,1,2,2") 1474 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")]) 1475 1476;; "subhi3" 1477;; "subhq3" "subuhq3" 1478;; "subha3" "subuha3" 1479(define_insn "sub<mode>3" 1480 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r") 1481 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0") 1482 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn"))) 1483 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 1484 "" 1485 { 1486 return avr_out_plus (insn, operands); 1487 } 1488 [(set_attr "adjust_len" "plus") 1489 (set_attr "cc" "plus")]) 1490 1491(define_insn "*subhi3_zero_extend1" 1492 [(set (match_operand:HI 0 "register_operand" "=r") 1493 (minus:HI (match_operand:HI 1 "register_operand" "0") 1494 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1495 "" 1496 "sub %A0,%2\;sbc %B0,__zero_reg__" 1497 [(set_attr "length" "2") 1498 (set_attr "cc" "set_czn")]) 1499 1500(define_insn "*subhi3.sign_extend2" 1501 [(set (match_operand:HI 0 "register_operand" "=r") 1502 (minus:HI (match_operand:HI 1 "register_operand" "0") 1503 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1504 "" 1505 { 1506 return reg_overlap_mentioned_p (operands[0], operands[2]) 1507 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0" 1508 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0"; 1509 } 1510 [(set_attr "length" "5") 1511 (set_attr "cc" "clobber")]) 1512 1513;; "subsi3" 1514;; "subsq3" "subusq3" 1515;; "subsa3" "subusa3" 1516(define_insn "sub<mode>3" 1517 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r") 1518 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0") 1519 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn"))) 1520 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 1521 "" 1522 { 1523 return avr_out_plus (insn, operands); 1524 } 1525 [(set_attr "adjust_len" "plus") 1526 (set_attr "cc" "plus")]) 1527 1528(define_insn "*subsi3_zero_extend" 1529 [(set (match_operand:SI 0 "register_operand" "=r") 1530 (minus:SI (match_operand:SI 1 "register_operand" "0") 1531 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))] 1532 "" 1533 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__" 1534 [(set_attr "length" "4") 1535 (set_attr "cc" "set_czn")]) 1536 1537(define_insn "*subsi3_zero_extend.hi" 1538 [(set (match_operand:SI 0 "register_operand" "=r") 1539 (minus:SI (match_operand:SI 1 "register_operand" "0") 1540 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 1541 "" 1542 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__" 1543 [(set_attr "length" "4") 1544 (set_attr "cc" "set_czn")]) 1545 1546;****************************************************************************** 1547; mul 1548 1549(define_expand "mulqi3" 1550 [(set (match_operand:QI 0 "register_operand" "") 1551 (mult:QI (match_operand:QI 1 "register_operand" "") 1552 (match_operand:QI 2 "register_operand" "")))] 1553 "" 1554 { 1555 if (!AVR_HAVE_MUL) 1556 { 1557 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2])); 1558 DONE; 1559 } 1560 }) 1561 1562(define_insn "*mulqi3_enh" 1563 [(set (match_operand:QI 0 "register_operand" "=r") 1564 (mult:QI (match_operand:QI 1 "register_operand" "r") 1565 (match_operand:QI 2 "register_operand" "r")))] 1566 "AVR_HAVE_MUL" 1567 "mul %1,%2 1568 mov %0,r0 1569 clr r1" 1570 [(set_attr "length" "3") 1571 (set_attr "cc" "clobber")]) 1572 1573(define_expand "mulqi3_call" 1574 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" "")) 1575 (set (reg:QI 22) (match_operand:QI 2 "register_operand" "")) 1576 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22))) 1577 (clobber (reg:QI 22))]) 1578 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))] 1579 "" 1580 { 1581 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 1582 }) 1583 1584(define_insn "*mulqi3_call" 1585 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22))) 1586 (clobber (reg:QI 22))] 1587 "!AVR_HAVE_MUL" 1588 "%~call __mulqi3" 1589 [(set_attr "type" "xcall") 1590 (set_attr "cc" "clobber")]) 1591 1592;; "umulqi3_highpart" 1593;; "smulqi3_highpart" 1594(define_insn "<extend_su>mulqi3_highpart" 1595 [(set (match_operand:QI 0 "register_operand" "=r") 1596 (truncate:QI 1597 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1598 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 1599 (const_int 8))))] 1600 "AVR_HAVE_MUL" 1601 "mul<extend_s> %1,%2 1602 mov %0,r1 1603 clr __zero_reg__" 1604 [(set_attr "length" "3") 1605 (set_attr "cc" "clobber")]) 1606 1607 1608;; Used when expanding div or mod inline for some special values 1609(define_insn "*subqi3.ashiftrt7" 1610 [(set (match_operand:QI 0 "register_operand" "=r") 1611 (minus:QI (match_operand:QI 1 "register_operand" "0") 1612 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r") 1613 (const_int 7))))] 1614 "" 1615 "sbrc %2,7\;inc %0" 1616 [(set_attr "length" "2") 1617 (set_attr "cc" "clobber")]) 1618 1619(define_insn "*addqi3.lt0" 1620 [(set (match_operand:QI 0 "register_operand" "=r") 1621 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r") 1622 (const_int 0)) 1623 (match_operand:QI 2 "register_operand" "0")))] 1624 "" 1625 "sbrc %1,7\;inc %0" 1626 [(set_attr "length" "2") 1627 (set_attr "cc" "clobber")]) 1628 1629(define_insn "*addhi3.lt0" 1630 [(set (match_operand:HI 0 "register_operand" "=w,r") 1631 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r") 1632 (const_int 0)) 1633 (match_operand:HI 2 "register_operand" "0,0"))) 1634 (clobber (match_scratch:QI 3 "=X,&1"))] 1635 "" 1636 "@ 1637 sbrc %1,7\;adiw %0,1 1638 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__" 1639 [(set_attr "length" "2,3") 1640 (set_attr "cc" "clobber")]) 1641 1642(define_insn "*addpsi3.lt0" 1643 [(set (match_operand:PSI 0 "register_operand" "=r") 1644 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r") 1645 (const_int 23)) 1646 (match_operand:PSI 2 "register_operand" "0")))] 1647 "" 1648 "mov __tmp_reg__,%C1\;lsl __tmp_reg__ 1649 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__" 1650 [(set_attr "length" "5") 1651 (set_attr "cc" "clobber")]) 1652 1653(define_insn "*addsi3.lt0" 1654 [(set (match_operand:SI 0 "register_operand" "=r") 1655 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 1656 (const_int 31)) 1657 (match_operand:SI 2 "register_operand" "0")))] 1658 "" 1659 "mov __tmp_reg__,%D1\;lsl __tmp_reg__ 1660 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" 1661 [(set_attr "length" "6") 1662 (set_attr "cc" "clobber")]) 1663 1664(define_insn "*umulqihi3.call" 1665 [(set (reg:HI 24) 1666 (mult:HI (zero_extend:HI (reg:QI 22)) 1667 (zero_extend:HI (reg:QI 24)))) 1668 (clobber (reg:QI 21)) 1669 (clobber (reg:HI 22))] 1670 "!AVR_HAVE_MUL" 1671 "%~call __umulqihi3" 1672 [(set_attr "type" "xcall") 1673 (set_attr "cc" "clobber")]) 1674 1675;; "umulqihi3" 1676;; "mulqihi3" 1677(define_insn "<extend_u>mulqihi3" 1678 [(set (match_operand:HI 0 "register_operand" "=r") 1679 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1680 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))] 1681 "AVR_HAVE_MUL" 1682 "mul<extend_s> %1,%2 1683 movw %0,r0 1684 clr __zero_reg__" 1685 [(set_attr "length" "3") 1686 (set_attr "cc" "clobber")]) 1687 1688(define_insn "usmulqihi3" 1689 [(set (match_operand:HI 0 "register_operand" "=r") 1690 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a")) 1691 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 1692 "AVR_HAVE_MUL" 1693 "mulsu %2,%1 1694 movw %0,r0 1695 clr __zero_reg__" 1696 [(set_attr "length" "3") 1697 (set_attr "cc" "clobber")]) 1698 1699;; Above insn is not canonicalized by insn combine, so here is a version with 1700;; operands swapped. 1701 1702(define_insn "*sumulqihi3" 1703 [(set (match_operand:HI 0 "register_operand" "=r") 1704 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 1705 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 1706 "AVR_HAVE_MUL" 1707 "mulsu %1,%2 1708 movw %0,r0 1709 clr __zero_reg__" 1710 [(set_attr "length" "3") 1711 (set_attr "cc" "clobber")]) 1712 1713;; One-extend operand 1 1714 1715(define_insn "*osmulqihi3" 1716 [(set (match_operand:HI 0 "register_operand" "=&r") 1717 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a")))) 1718 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))] 1719 "AVR_HAVE_MUL" 1720 "mulsu %2,%1 1721 movw %0,r0 1722 sub %B0,%2 1723 clr __zero_reg__" 1724 [(set_attr "length" "4") 1725 (set_attr "cc" "clobber")]) 1726 1727(define_insn "*oumulqihi3" 1728 [(set (match_operand:HI 0 "register_operand" "=&r") 1729 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 1730 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] 1731 "AVR_HAVE_MUL" 1732 "mul %2,%1 1733 movw %0,r0 1734 sub %B0,%2 1735 clr __zero_reg__" 1736 [(set_attr "length" "4") 1737 (set_attr "cc" "clobber")]) 1738 1739;****************************************************************************** 1740; multiply-add/sub QI: $0 = $3 +/- $1*$2 1741;****************************************************************************** 1742 1743(define_insn "*maddqi4" 1744 [(set (match_operand:QI 0 "register_operand" "=r") 1745 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r") 1746 (match_operand:QI 2 "register_operand" "r")) 1747 (match_operand:QI 3 "register_operand" "0")))] 1748 1749 "AVR_HAVE_MUL" 1750 "mul %1,%2 1751 add %A0,r0 1752 clr __zero_reg__" 1753 [(set_attr "length" "4") 1754 (set_attr "cc" "clobber")]) 1755 1756(define_insn "*msubqi4" 1757 [(set (match_operand:QI 0 "register_operand" "=r") 1758 (minus:QI (match_operand:QI 3 "register_operand" "0") 1759 (mult:QI (match_operand:QI 1 "register_operand" "r") 1760 (match_operand:QI 2 "register_operand" "r"))))] 1761 "AVR_HAVE_MUL" 1762 "mul %1,%2 1763 sub %A0,r0 1764 clr __zero_reg__" 1765 [(set_attr "length" "4") 1766 (set_attr "cc" "clobber")]) 1767 1768(define_insn_and_split "*maddqi4.const" 1769 [(set (match_operand:QI 0 "register_operand" "=r") 1770 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r") 1771 (match_operand:QI 2 "const_int_operand" "n")) 1772 (match_operand:QI 3 "register_operand" "0"))) 1773 (clobber (match_scratch:QI 4 "=&d"))] 1774 "AVR_HAVE_MUL" 1775 "#" 1776 "&& reload_completed" 1777 [(set (match_dup 4) 1778 (match_dup 2)) 1779 ; *maddqi4 1780 (set (match_dup 0) 1781 (plus:QI (mult:QI (match_dup 1) 1782 (match_dup 4)) 1783 (match_dup 3)))]) 1784 1785(define_insn_and_split "*msubqi4.const" 1786 [(set (match_operand:QI 0 "register_operand" "=r") 1787 (minus:QI (match_operand:QI 3 "register_operand" "0") 1788 (mult:QI (match_operand:QI 1 "register_operand" "r") 1789 (match_operand:QI 2 "const_int_operand" "n")))) 1790 (clobber (match_scratch:QI 4 "=&d"))] 1791 "AVR_HAVE_MUL" 1792 "#" 1793 "&& reload_completed" 1794 [(set (match_dup 4) 1795 (match_dup 2)) 1796 ; *msubqi4 1797 (set (match_dup 0) 1798 (minus:QI (match_dup 3) 1799 (mult:QI (match_dup 1) 1800 (match_dup 4))))]) 1801 1802 1803;****************************************************************************** 1804; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2 1805;****************************************************************************** 1806 1807;; We don't use standard insns/expanders as they lead to cumbersome code for, 1808;; e.g, 1809;; 1810;; int foo (unsigned char z) 1811;; { 1812;; extern int aInt[]; 1813;; return aInt[3*z+2]; 1814;; } 1815;; 1816;; because the constant +4 then is added explicitely instead of consuming it 1817;; with the aInt symbol. Therefore, we rely on insn combine which takes costs 1818;; into account more accurately and doesn't do burte-force multiply-add/sub. 1819;; The implementational effort is the same so we are fine with that approach. 1820 1821 1822;; "*maddqihi4" 1823;; "*umaddqihi4" 1824(define_insn "*<extend_u>maddqihi4" 1825 [(set (match_operand:HI 0 "register_operand" "=r") 1826 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1827 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))) 1828 (match_operand:HI 3 "register_operand" "0")))] 1829 1830 "AVR_HAVE_MUL" 1831 "mul<extend_s> %1,%2 1832 add %A0,r0 1833 adc %B0,r1 1834 clr __zero_reg__" 1835 [(set_attr "length" "4") 1836 (set_attr "cc" "clobber")]) 1837 1838;; "*msubqihi4" 1839;; "*umsubqihi4" 1840(define_insn "*<extend_u>msubqihi4" 1841 [(set (match_operand:HI 0 "register_operand" "=r") 1842 (minus:HI (match_operand:HI 3 "register_operand" "0") 1843 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1844 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))] 1845 "AVR_HAVE_MUL" 1846 "mul<extend_s> %1,%2 1847 sub %A0,r0 1848 sbc %B0,r1 1849 clr __zero_reg__" 1850 [(set_attr "length" "4") 1851 (set_attr "cc" "clobber")]) 1852 1853;; "*usmaddqihi4" 1854;; "*sumaddqihi4" 1855(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" 1856 [(set (match_operand:HI 0 "register_operand" "=r") 1857 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 1858 (any_extend2:HI (match_operand:QI 2 "register_operand" "a"))) 1859 (match_operand:HI 3 "register_operand" "0")))] 1860 "AVR_HAVE_MUL 1861 && reload_completed 1862 && <any_extend:CODE> != <any_extend2:CODE>" 1863 { 1864 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND 1865 ? "mulsu %1,%2" : "mulsu %2,%1", operands); 1866 1867 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__"; 1868 } 1869 [(set_attr "length" "4") 1870 (set_attr "cc" "clobber")]) 1871 1872;; "*usmsubqihi4" 1873;; "*sumsubqihi4" 1874(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4" 1875 [(set (match_operand:HI 0 "register_operand" "=r") 1876 (minus:HI (match_operand:HI 3 "register_operand" "0") 1877 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a")) 1878 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))] 1879 "AVR_HAVE_MUL 1880 && reload_completed 1881 && <any_extend:CODE> != <any_extend2:CODE>" 1882 { 1883 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND 1884 ? "mulsu %1,%2" : "mulsu %2,%1", operands); 1885 1886 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__"; 1887 } 1888 [(set_attr "length" "4") 1889 (set_attr "cc" "clobber")]) 1890 1891;; Handle small constants 1892 1893;; Special case of a += 2*b as frequently seen with accesses to int arrays. 1894;; This is shorter, faster than MUL and has lower register pressure. 1895 1896(define_insn_and_split "*umaddqihi4.2" 1897 [(set (match_operand:HI 0 "register_operand" "=r") 1898 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 1899 (const_int 2)) 1900 (match_operand:HI 2 "register_operand" "r")))] 1901 "!reload_completed 1902 && !reg_overlap_mentioned_p (operands[0], operands[1])" 1903 { gcc_unreachable(); } 1904 "&& 1" 1905 [(set (match_dup 0) 1906 (match_dup 2)) 1907 ; *addhi3_zero_extend 1908 (set (match_dup 0) 1909 (plus:HI (zero_extend:HI (match_dup 1)) 1910 (match_dup 0))) 1911 ; *addhi3_zero_extend 1912 (set (match_dup 0) 1913 (plus:HI (zero_extend:HI (match_dup 1)) 1914 (match_dup 0)))]) 1915 1916;; "umaddqihi4.uconst" 1917;; "maddqihi4.sconst" 1918(define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const" 1919 [(set (match_operand:HI 0 "register_operand" "=r") 1920 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1921 (match_operand:HI 2 "<extend_su>8_operand" "n")) 1922 (match_operand:HI 3 "register_operand" "0"))) 1923 (clobber (match_scratch:QI 4 "=&d"))] 1924 "AVR_HAVE_MUL" 1925 "#" 1926 "&& reload_completed" 1927 [(set (match_dup 4) 1928 (match_dup 2)) 1929 ; *umaddqihi4 resp. *maddqihi4 1930 (set (match_dup 0) 1931 (plus:HI (mult:HI (any_extend:HI (match_dup 1)) 1932 (any_extend:HI (match_dup 4))) 1933 (match_dup 3)))] 1934 { 1935 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 1936 }) 1937 1938;; "*umsubqihi4.uconst" 1939;; "*msubqihi4.sconst" 1940(define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const" 1941 [(set (match_operand:HI 0 "register_operand" "=r") 1942 (minus:HI (match_operand:HI 3 "register_operand" "0") 1943 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 1944 (match_operand:HI 2 "<extend_su>8_operand" "n")))) 1945 (clobber (match_scratch:QI 4 "=&d"))] 1946 "AVR_HAVE_MUL" 1947 "#" 1948 "&& reload_completed" 1949 [(set (match_dup 4) 1950 (match_dup 2)) 1951 ; *umsubqihi4 resp. *msubqihi4 1952 (set (match_dup 0) 1953 (minus:HI (match_dup 3) 1954 (mult:HI (any_extend:HI (match_dup 1)) 1955 (any_extend:HI (match_dup 4)))))] 1956 { 1957 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 1958 }) 1959 1960;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT 1961;; for MULT with power of 2 and skips trying MULT insn above. 1962 1963(define_insn_and_split "*umsubqihi4.uconst.ashift" 1964 [(set (match_operand:HI 0 "register_operand" "=r") 1965 (minus:HI (match_operand:HI 3 "register_operand" "0") 1966 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 1967 (match_operand:HI 2 "const_2_to_7_operand" "n")))) 1968 (clobber (match_scratch:QI 4 "=&d"))] 1969 "AVR_HAVE_MUL" 1970 "#" 1971 "&& reload_completed" 1972 [(set (match_dup 4) 1973 (match_dup 2)) 1974 ; *umsubqihi4 1975 (set (match_dup 0) 1976 (minus:HI (match_dup 3) 1977 (mult:HI (zero_extend:HI (match_dup 1)) 1978 (zero_extend:HI (match_dup 4)))))] 1979 { 1980 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 1981 }) 1982 1983;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT 1984;; for MULT with power of 2 and skips trying MULT insn above. We omit 128 1985;; because this would require an extra pattern for just one value. 1986 1987(define_insn_and_split "*msubqihi4.sconst.ashift" 1988 [(set (match_operand:HI 0 "register_operand" "=r") 1989 (minus:HI (match_operand:HI 3 "register_operand" "0") 1990 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d")) 1991 (match_operand:HI 2 "const_1_to_6_operand" "M")))) 1992 (clobber (match_scratch:QI 4 "=&d"))] 1993 "AVR_HAVE_MUL" 1994 "#" 1995 "&& reload_completed" 1996 [(set (match_dup 4) 1997 (match_dup 2)) 1998 ; *smsubqihi4 1999 (set (match_dup 0) 2000 (minus:HI (match_dup 3) 2001 (mult:HI (sign_extend:HI (match_dup 1)) 2002 (sign_extend:HI (match_dup 4)))))] 2003 { 2004 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 2005 }) 2006 2007;; For signed/unsigned combinations that require narrow constraint "a" 2008;; just provide a pattern if signed/unsigned combination is actually needed. 2009 2010(define_insn_and_split "*sumaddqihi4.uconst" 2011 [(set (match_operand:HI 0 "register_operand" "=r") 2012 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2013 (match_operand:HI 2 "u8_operand" "M")) 2014 (match_operand:HI 3 "register_operand" "0"))) 2015 (clobber (match_scratch:QI 4 "=&a"))] 2016 "AVR_HAVE_MUL 2017 && !s8_operand (operands[2], VOIDmode)" 2018 "#" 2019 "&& reload_completed" 2020 [(set (match_dup 4) 2021 (match_dup 2)) 2022 ; *sumaddqihi4 2023 (set (match_dup 0) 2024 (plus:HI (mult:HI (sign_extend:HI (match_dup 1)) 2025 (zero_extend:HI (match_dup 4))) 2026 (match_dup 3)))] 2027 { 2028 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2029 }) 2030 2031(define_insn_and_split "*sumsubqihi4.uconst" 2032 [(set (match_operand:HI 0 "register_operand" "=r") 2033 (minus:HI (match_operand:HI 3 "register_operand" "0") 2034 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2035 (match_operand:HI 2 "u8_operand" "M")))) 2036 (clobber (match_scratch:QI 4 "=&a"))] 2037 "AVR_HAVE_MUL 2038 && !s8_operand (operands[2], VOIDmode)" 2039 "#" 2040 "&& reload_completed" 2041 [(set (match_dup 4) 2042 (match_dup 2)) 2043 ; *sumsubqihi4 2044 (set (match_dup 0) 2045 (minus:HI (match_dup 3) 2046 (mult:HI (sign_extend:HI (match_dup 1)) 2047 (zero_extend:HI (match_dup 4)))))] 2048 { 2049 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2050 }) 2051 2052;****************************************************************************** 2053; mul HI: $1 = sign/zero-extend, $2 = small constant 2054;****************************************************************************** 2055 2056;; "*muluqihi3.uconst" 2057;; "*mulsqihi3.sconst" 2058(define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const" 2059 [(set (match_operand:HI 0 "register_operand" "=r") 2060 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>")) 2061 (match_operand:HI 2 "<extend_su>8_operand" "n"))) 2062 (clobber (match_scratch:QI 3 "=&d"))] 2063 "AVR_HAVE_MUL" 2064 "#" 2065 "&& reload_completed" 2066 [(set (match_dup 3) 2067 (match_dup 2)) 2068 ; umulqihi3 resp. mulqihi3 2069 (set (match_dup 0) 2070 (mult:HI (any_extend:HI (match_dup 1)) 2071 (any_extend:HI (match_dup 3))))] 2072 { 2073 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2074 }) 2075 2076(define_insn_and_split "*muluqihi3.sconst" 2077 [(set (match_operand:HI 0 "register_operand" "=r") 2078 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a")) 2079 (match_operand:HI 2 "s8_operand" "n"))) 2080 (clobber (match_scratch:QI 3 "=&a"))] 2081 "AVR_HAVE_MUL" 2082 "#" 2083 "&& reload_completed" 2084 [(set (match_dup 3) 2085 (match_dup 2)) 2086 ; usmulqihi3 2087 (set (match_dup 0) 2088 (mult:HI (zero_extend:HI (match_dup 1)) 2089 (sign_extend:HI (match_dup 3))))] 2090 { 2091 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2092 }) 2093 2094(define_insn_and_split "*mulsqihi3.uconst" 2095 [(set (match_operand:HI 0 "register_operand" "=r") 2096 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2097 (match_operand:HI 2 "u8_operand" "M"))) 2098 (clobber (match_scratch:QI 3 "=&a"))] 2099 "AVR_HAVE_MUL" 2100 "#" 2101 "&& reload_completed" 2102 [(set (match_dup 3) 2103 (match_dup 2)) 2104 ; usmulqihi3 2105 (set (match_dup 0) 2106 (mult:HI (zero_extend:HI (match_dup 3)) 2107 (sign_extend:HI (match_dup 1))))] 2108 { 2109 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2110 }) 2111 2112(define_insn_and_split "*mulsqihi3.oconst" 2113 [(set (match_operand:HI 0 "register_operand" "=&r") 2114 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2115 (match_operand:HI 2 "o8_operand" "n"))) 2116 (clobber (match_scratch:QI 3 "=&a"))] 2117 "AVR_HAVE_MUL" 2118 "#" 2119 "&& reload_completed" 2120 [(set (match_dup 3) 2121 (match_dup 2)) 2122 ; *osmulqihi3 2123 (set (match_dup 0) 2124 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3)))) 2125 (sign_extend:HI (match_dup 1))))] 2126 { 2127 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 2128 }) 2129 2130;; The EXTEND of $1 only appears in combine, we don't see it in expand so that 2131;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper 2132;; at that time. Fix that. 2133 2134(define_insn "*ashiftqihi2.signx.1" 2135 [(set (match_operand:HI 0 "register_operand" "=r,*r") 2136 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r")) 2137 (const_int 1)))] 2138 "" 2139 "@ 2140 lsl %A0\;sbc %B0,%B0 2141 mov %A0,%1\;lsl %A0\;sbc %B0,%B0" 2142 [(set_attr "length" "2,3") 2143 (set_attr "cc" "clobber")]) 2144 2145(define_insn_and_split "*ashifthi3.signx.const" 2146 [(set (match_operand:HI 0 "register_operand" "=r") 2147 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d")) 2148 (match_operand:HI 2 "const_2_to_6_operand" "I"))) 2149 (clobber (match_scratch:QI 3 "=&d"))] 2150 "AVR_HAVE_MUL" 2151 "#" 2152 "&& reload_completed" 2153 [(set (match_dup 3) 2154 (match_dup 2)) 2155 ; mulqihi3 2156 (set (match_dup 0) 2157 (mult:HI (sign_extend:HI (match_dup 1)) 2158 (sign_extend:HI (match_dup 3))))] 2159 { 2160 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 2161 }) 2162 2163(define_insn_and_split "*ashifthi3.signx.const7" 2164 [(set (match_operand:HI 0 "register_operand" "=r") 2165 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2166 (const_int 7))) 2167 (clobber (match_scratch:QI 2 "=&a"))] 2168 "AVR_HAVE_MUL" 2169 "#" 2170 "&& reload_completed" 2171 [(set (match_dup 2) 2172 (match_dup 3)) 2173 ; usmulqihi3 2174 (set (match_dup 0) 2175 (mult:HI (zero_extend:HI (match_dup 2)) 2176 (sign_extend:HI (match_dup 1))))] 2177 { 2178 operands[3] = gen_int_mode (1 << 7, QImode); 2179 }) 2180 2181(define_insn_and_split "*ashifthi3.zerox.const" 2182 [(set (match_operand:HI 0 "register_operand" "=r") 2183 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 2184 (match_operand:HI 2 "const_2_to_7_operand" "I"))) 2185 (clobber (match_scratch:QI 3 "=&d"))] 2186 "AVR_HAVE_MUL" 2187 "#" 2188 "&& reload_completed" 2189 [(set (match_dup 3) 2190 (match_dup 2)) 2191 ; umulqihi3 2192 (set (match_dup 0) 2193 (mult:HI (zero_extend:HI (match_dup 1)) 2194 (zero_extend:HI (match_dup 3))))] 2195 { 2196 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode); 2197 }) 2198 2199;****************************************************************************** 2200; mul HI: $1 = sign-/zero-/one-extend, $2 = reg 2201;****************************************************************************** 2202 2203(define_insn "mulsqihi3" 2204 [(set (match_operand:HI 0 "register_operand" "=&r") 2205 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a")) 2206 (match_operand:HI 2 "register_operand" "a")))] 2207 "AVR_HAVE_MUL" 2208 "mulsu %1,%A2 2209 movw %0,r0 2210 mul %1,%B2 2211 add %B0,r0 2212 clr __zero_reg__" 2213 [(set_attr "length" "5") 2214 (set_attr "cc" "clobber")]) 2215 2216(define_insn "muluqihi3" 2217 [(set (match_operand:HI 0 "register_operand" "=&r") 2218 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) 2219 (match_operand:HI 2 "register_operand" "r")))] 2220 "AVR_HAVE_MUL" 2221 "mul %1,%A2 2222 movw %0,r0 2223 mul %1,%B2 2224 add %B0,r0 2225 clr __zero_reg__" 2226 [(set_attr "length" "5") 2227 (set_attr "cc" "clobber")]) 2228 2229;; one-extend operand 1 2230 2231(define_insn "muloqihi3" 2232 [(set (match_operand:HI 0 "register_operand" "=&r") 2233 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r")))) 2234 (match_operand:HI 2 "register_operand" "r")))] 2235 "AVR_HAVE_MUL" 2236 "mul %1,%A2 2237 movw %0,r0 2238 mul %1,%B2 2239 add %B0,r0 2240 sub %B0,%A2 2241 clr __zero_reg__" 2242 [(set_attr "length" "6") 2243 (set_attr "cc" "clobber")]) 2244 2245;****************************************************************************** 2246 2247(define_expand "mulhi3" 2248 [(set (match_operand:HI 0 "register_operand" "") 2249 (mult:HI (match_operand:HI 1 "register_operand" "") 2250 (match_operand:HI 2 "register_or_s9_operand" "")))] 2251 "" 2252 { 2253 if (!AVR_HAVE_MUL) 2254 { 2255 if (!register_operand (operands[2], HImode)) 2256 operands[2] = force_reg (HImode, operands[2]); 2257 2258 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2])); 2259 DONE; 2260 } 2261 2262 /* ; For small constants we can do better by extending them on the fly. 2263 ; The constant can be loaded in one instruction and the widening 2264 ; multiplication is shorter. First try the unsigned variant because it 2265 ; allows constraint "d" instead of "a" for the signed version. */ 2266 2267 if (s9_operand (operands[2], HImode)) 2268 { 2269 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 2270 2271 if (u8_operand (operands[2], HImode)) 2272 { 2273 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1])); 2274 } 2275 else if (s8_operand (operands[2], HImode)) 2276 { 2277 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1])); 2278 } 2279 else 2280 { 2281 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1])); 2282 } 2283 2284 DONE; 2285 } 2286 2287 if (!register_operand (operands[2], HImode)) 2288 operands[2] = force_reg (HImode, operands[2]); 2289 }) 2290 2291(define_insn "*mulhi3_enh" 2292 [(set (match_operand:HI 0 "register_operand" "=&r") 2293 (mult:HI (match_operand:HI 1 "register_operand" "r") 2294 (match_operand:HI 2 "register_operand" "r")))] 2295 "AVR_HAVE_MUL" 2296 { 2297 return REGNO (operands[1]) == REGNO (operands[2]) 2298 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1" 2299 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1"; 2300 } 2301 [(set_attr "length" "7") 2302 (set_attr "cc" "clobber")]) 2303 2304(define_expand "mulhi3_call" 2305 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" "")) 2306 (set (reg:HI 22) (match_operand:HI 2 "register_operand" "")) 2307 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22))) 2308 (clobber (reg:HI 22)) 2309 (clobber (reg:QI 21))]) 2310 (set (match_operand:HI 0 "register_operand" "") 2311 (reg:HI 24))] 2312 "" 2313 { 2314 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24)); 2315 }) 2316 2317 2318(define_insn "*mulhi3_call" 2319 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22))) 2320 (clobber (reg:HI 22)) 2321 (clobber (reg:QI 21))] 2322 "!AVR_HAVE_MUL" 2323 "%~call __mulhi3" 2324 [(set_attr "type" "xcall") 2325 (set_attr "cc" "clobber")]) 2326 2327;; To support widening multiplication with constant we postpone 2328;; expanding to the implicit library call until post combine and 2329;; prior to register allocation. Clobber all hard registers that 2330;; might be used by the (widening) multiply until it is split and 2331;; it's final register footprint is worked out. 2332 2333(define_expand "mulsi3" 2334 [(parallel [(set (match_operand:SI 0 "register_operand" "") 2335 (mult:SI (match_operand:SI 1 "register_operand" "") 2336 (match_operand:SI 2 "nonmemory_operand" ""))) 2337 (clobber (reg:HI 26)) 2338 (clobber (reg:DI 18))])] 2339 "AVR_HAVE_MUL" 2340 { 2341 if (u16_operand (operands[2], SImode)) 2342 { 2343 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2344 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1])); 2345 DONE; 2346 } 2347 2348 if (o16_operand (operands[2], SImode)) 2349 { 2350 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2351 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1])); 2352 DONE; 2353 } 2354 2355 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0, 2356 regmask (DImode, 18) | regmask (HImode, 26))) 2357 DONE; 2358 }) 2359 2360(define_insn_and_split "*mulsi3" 2361 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 2362 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r") 2363 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 2364 (clobber (reg:HI 26)) 2365 (clobber (reg:DI 18))] 2366 "AVR_HAVE_MUL && !reload_completed" 2367 { gcc_unreachable(); } 2368 "&& 1" 2369 [(set (reg:SI 18) 2370 (match_dup 1)) 2371 (set (reg:SI 22) 2372 (match_dup 2)) 2373 (parallel [(set (reg:SI 22) 2374 (mult:SI (reg:SI 22) 2375 (reg:SI 18))) 2376 (clobber (reg:HI 26))]) 2377 (set (match_dup 0) 2378 (reg:SI 22))] 2379 { 2380 if (u16_operand (operands[2], SImode)) 2381 { 2382 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2383 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1])); 2384 DONE; 2385 } 2386 2387 if (o16_operand (operands[2], SImode)) 2388 { 2389 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2390 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1])); 2391 DONE; 2392 } 2393 }) 2394 2395;; "muluqisi3" 2396;; "muluhisi3" 2397(define_expand "mulu<mode>si3" 2398 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 2399 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "")) 2400 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 2401 (clobber (reg:HI 26)) 2402 (clobber (reg:DI 18))])] 2403 "AVR_HAVE_MUL" 2404 { 2405 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 2406 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0, 2407 regmask (DImode, 18) | regmask (HImode, 26))) 2408 DONE; 2409 }) 2410 2411;; "*muluqisi3" 2412;; "*muluhisi3" 2413(define_insn_and_split "*mulu<mode>si3" 2414 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 2415 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 2416 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 2417 (clobber (reg:HI 26)) 2418 (clobber (reg:DI 18))] 2419 "AVR_HAVE_MUL && !reload_completed" 2420 { gcc_unreachable(); } 2421 "&& 1" 2422 [(set (reg:HI 26) 2423 (match_dup 1)) 2424 (set (reg:SI 18) 2425 (match_dup 2)) 2426 (set (reg:SI 22) 2427 (mult:SI (zero_extend:SI (reg:HI 26)) 2428 (reg:SI 18))) 2429 (set (match_dup 0) 2430 (reg:SI 22))] 2431 { 2432 /* Do the QI -> HI extension explicitely before the multiplication. */ 2433 /* Do the HI -> SI extension implicitely and after the multiplication. */ 2434 2435 if (QImode == <MODE>mode) 2436 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]); 2437 2438 if (u16_operand (operands[2], SImode)) 2439 { 2440 operands[1] = force_reg (HImode, operands[1]); 2441 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2442 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2])); 2443 DONE; 2444 } 2445 }) 2446 2447;; "mulsqisi3" 2448;; "mulshisi3" 2449(define_expand "muls<mode>si3" 2450 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 2451 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "")) 2452 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 2453 (clobber (reg:HI 26)) 2454 (clobber (reg:DI 18))])] 2455 "AVR_HAVE_MUL" 2456 { 2457 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 2458 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0, 2459 regmask (DImode, 18) | regmask (HImode, 26))) 2460 DONE; 2461 }) 2462 2463;; "*mulsqisi3" 2464;; "*mulshisi3" 2465(define_insn_and_split "*muls<mode>si3" 2466 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 2467 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 2468 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 2469 (clobber (reg:HI 26)) 2470 (clobber (reg:DI 18))] 2471 "AVR_HAVE_MUL && !reload_completed" 2472 { gcc_unreachable(); } 2473 "&& 1" 2474 [(set (reg:HI 26) 2475 (match_dup 1)) 2476 (set (reg:SI 18) 2477 (match_dup 2)) 2478 (set (reg:SI 22) 2479 (mult:SI (sign_extend:SI (reg:HI 26)) 2480 (reg:SI 18))) 2481 (set (match_dup 0) 2482 (reg:SI 22))] 2483 { 2484 /* Do the QI -> HI extension explicitely before the multiplication. */ 2485 /* Do the HI -> SI extension implicitely and after the multiplication. */ 2486 2487 if (QImode == <MODE>mode) 2488 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]); 2489 2490 if (u16_operand (operands[2], SImode) 2491 || s16_operand (operands[2], SImode)) 2492 { 2493 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode)); 2494 2495 operands[1] = force_reg (HImode, operands[1]); 2496 2497 if (u16_operand (operands[2], SImode)) 2498 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1])); 2499 else 2500 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2)); 2501 2502 DONE; 2503 } 2504 }) 2505 2506;; One-extend operand 1 2507 2508(define_expand "mulohisi3" 2509 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 2510 (mult:SI (not:SI (zero_extend:SI 2511 (not:HI (match_operand:HI 1 "pseudo_register_operand" "")))) 2512 (match_operand:SI 2 "pseudo_register_or_const_int_operand" ""))) 2513 (clobber (reg:HI 26)) 2514 (clobber (reg:DI 18))])] 2515 "AVR_HAVE_MUL" 2516 { 2517 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 2518 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0, 2519 regmask (DImode, 18) | regmask (HImode, 26))) 2520 DONE; 2521 }) 2522 2523(define_insn_and_split "*mulohisi3" 2524 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 2525 (mult:SI (not:SI (zero_extend:SI 2526 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r")))) 2527 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn"))) 2528 (clobber (reg:HI 26)) 2529 (clobber (reg:DI 18))] 2530 "AVR_HAVE_MUL && !reload_completed" 2531 { gcc_unreachable(); } 2532 "&& 1" 2533 [(set (reg:HI 26) 2534 (match_dup 1)) 2535 (set (reg:SI 18) 2536 (match_dup 2)) 2537 (set (reg:SI 22) 2538 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 2539 (reg:SI 18))) 2540 (set (match_dup 0) 2541 (reg:SI 22))]) 2542 2543;; "mulhisi3" 2544;; "umulhisi3" 2545(define_expand "<extend_u>mulhisi3" 2546 [(parallel [(set (match_operand:SI 0 "register_operand" "") 2547 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" "")) 2548 (any_extend:SI (match_operand:HI 2 "register_operand" "")))) 2549 (clobber (reg:HI 26)) 2550 (clobber (reg:DI 18))])] 2551 "AVR_HAVE_MUL" 2552 { 2553 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0, 2554 regmask (DImode, 18) | regmask (HImode, 26))) 2555 DONE; 2556 }) 2557 2558(define_expand "usmulhisi3" 2559 [(parallel [(set (match_operand:SI 0 "register_operand" "") 2560 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) 2561 (sign_extend:SI (match_operand:HI 2 "register_operand" "")))) 2562 (clobber (reg:HI 26)) 2563 (clobber (reg:DI 18))])] 2564 "AVR_HAVE_MUL" 2565 { 2566 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0, 2567 regmask (DImode, 18) | regmask (HImode, 26))) 2568 DONE; 2569 }) 2570 2571;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3" 2572;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3" 2573;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3" 2574;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3" 2575(define_insn_and_split 2576 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3" 2577 [(set (match_operand:SI 0 "pseudo_register_operand" "=r") 2578 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r")) 2579 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r")))) 2580 (clobber (reg:HI 26)) 2581 (clobber (reg:DI 18))] 2582 "AVR_HAVE_MUL && !reload_completed" 2583 { gcc_unreachable(); } 2584 "&& 1" 2585 [(set (reg:HI 18) 2586 (match_dup 1)) 2587 (set (reg:HI 26) 2588 (match_dup 2)) 2589 (set (reg:SI 22) 2590 (mult:SI (match_dup 3) 2591 (match_dup 4))) 2592 (set (match_dup 0) 2593 (reg:SI 22))] 2594 { 2595 rtx xop1 = operands[1]; 2596 rtx xop2 = operands[2]; 2597 2598 /* Do the QI -> HI extension explicitely before the multiplication. */ 2599 /* Do the HI -> SI extension implicitely and after the multiplication. */ 2600 2601 if (QImode == <QIHI:MODE>mode) 2602 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1); 2603 2604 if (QImode == <QIHI2:MODE>mode) 2605 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2); 2606 2607 if (<any_extend:CODE> == <any_extend2:CODE> 2608 || <any_extend:CODE> == ZERO_EXTEND) 2609 { 2610 operands[1] = xop1; 2611 operands[2] = xop2; 2612 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18)); 2613 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26)); 2614 } 2615 else 2616 { 2617 /* <any_extend:CODE> = SIGN_EXTEND */ 2618 /* <any_extend2:CODE> = ZERO_EXTEND */ 2619 2620 operands[1] = xop2; 2621 operands[2] = xop1; 2622 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18)); 2623 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26)); 2624 } 2625 }) 2626 2627;; "smulhi3_highpart" 2628;; "umulhi3_highpart" 2629(define_expand "<extend_su>mulhi3_highpart" 2630 [(set (reg:HI 18) 2631 (match_operand:HI 1 "nonmemory_operand" "")) 2632 (set (reg:HI 26) 2633 (match_operand:HI 2 "nonmemory_operand" "")) 2634 (parallel [(set (reg:HI 24) 2635 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 2636 (any_extend:SI (reg:HI 26))) 2637 (const_int 16)))) 2638 (clobber (reg:HI 22))]) 2639 (set (match_operand:HI 0 "register_operand" "") 2640 (reg:HI 24))] 2641 "AVR_HAVE_MUL" 2642 { 2643 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18)); 2644 }) 2645 2646 2647(define_insn "*mulsi3_call" 2648 [(set (reg:SI 22) 2649 (mult:SI (reg:SI 22) 2650 (reg:SI 18))) 2651 (clobber (reg:HI 26))] 2652 "AVR_HAVE_MUL" 2653 "%~call __mulsi3" 2654 [(set_attr "type" "xcall") 2655 (set_attr "cc" "clobber")]) 2656 2657;; "*mulhisi3_call" 2658;; "*umulhisi3_call" 2659(define_insn "*<extend_u>mulhisi3_call" 2660 [(set (reg:SI 22) 2661 (mult:SI (any_extend:SI (reg:HI 18)) 2662 (any_extend:SI (reg:HI 26))))] 2663 "AVR_HAVE_MUL" 2664 "%~call __<extend_u>mulhisi3" 2665 [(set_attr "type" "xcall") 2666 (set_attr "cc" "clobber")]) 2667 2668;; "*umulhi3_highpart_call" 2669;; "*smulhi3_highpart_call" 2670(define_insn "*<extend_su>mulhi3_highpart_call" 2671 [(set (reg:HI 24) 2672 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18)) 2673 (any_extend:SI (reg:HI 26))) 2674 (const_int 16)))) 2675 (clobber (reg:HI 22))] 2676 "AVR_HAVE_MUL" 2677 "%~call __<extend_u>mulhisi3" 2678 [(set_attr "type" "xcall") 2679 (set_attr "cc" "clobber")]) 2680 2681(define_insn "*usmulhisi3_call" 2682 [(set (reg:SI 22) 2683 (mult:SI (zero_extend:SI (reg:HI 18)) 2684 (sign_extend:SI (reg:HI 26))))] 2685 "AVR_HAVE_MUL" 2686 "%~call __usmulhisi3" 2687 [(set_attr "type" "xcall") 2688 (set_attr "cc" "clobber")]) 2689 2690(define_insn "*mul<extend_su>hisi3_call" 2691 [(set (reg:SI 22) 2692 (mult:SI (any_extend:SI (reg:HI 26)) 2693 (reg:SI 18)))] 2694 "AVR_HAVE_MUL" 2695 "%~call __mul<extend_su>hisi3" 2696 [(set_attr "type" "xcall") 2697 (set_attr "cc" "clobber")]) 2698 2699(define_insn "*mulohisi3_call" 2700 [(set (reg:SI 22) 2701 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26)))) 2702 (reg:SI 18)))] 2703 "AVR_HAVE_MUL" 2704 "%~call __mulohisi3" 2705 [(set_attr "type" "xcall") 2706 (set_attr "cc" "clobber")]) 2707 2708; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % 2709; divmod 2710 2711;; Generate lib1funcs.S calls ourselves, because: 2712;; - we know exactly which registers are clobbered (for QI and HI 2713;; modes, some of the call-used registers are preserved) 2714;; - we get both the quotient and the remainder at no extra cost 2715;; - we split the patterns only after the first CSE passes because 2716;; CSE has problems to operate on hard regs. 2717;; 2718(define_insn_and_split "divmodqi4" 2719 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 2720 (div:QI (match_operand:QI 1 "pseudo_register_operand" "") 2721 (match_operand:QI 2 "pseudo_register_operand" ""))) 2722 (set (match_operand:QI 3 "pseudo_register_operand" "") 2723 (mod:QI (match_dup 1) (match_dup 2))) 2724 (clobber (reg:QI 22)) 2725 (clobber (reg:QI 23)) 2726 (clobber (reg:QI 24)) 2727 (clobber (reg:QI 25))])] 2728 "" 2729 "this divmodqi4 pattern should have been splitted;" 2730 "" 2731 [(set (reg:QI 24) (match_dup 1)) 2732 (set (reg:QI 22) (match_dup 2)) 2733 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 2734 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 2735 (clobber (reg:QI 22)) 2736 (clobber (reg:QI 23))]) 2737 (set (match_dup 0) (reg:QI 24)) 2738 (set (match_dup 3) (reg:QI 25))]) 2739 2740(define_insn "*divmodqi4_call" 2741 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22))) 2742 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22))) 2743 (clobber (reg:QI 22)) 2744 (clobber (reg:QI 23))] 2745 "" 2746 "%~call __divmodqi4" 2747 [(set_attr "type" "xcall") 2748 (set_attr "cc" "clobber")]) 2749 2750(define_insn_and_split "udivmodqi4" 2751 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 2752 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "") 2753 (match_operand:QI 2 "pseudo_register_operand" ""))) 2754 (set (match_operand:QI 3 "pseudo_register_operand" "") 2755 (umod:QI (match_dup 1) (match_dup 2))) 2756 (clobber (reg:QI 22)) 2757 (clobber (reg:QI 23)) 2758 (clobber (reg:QI 24)) 2759 (clobber (reg:QI 25))])] 2760 "" 2761 "this udivmodqi4 pattern should have been splitted;" 2762 "" 2763 [(set (reg:QI 24) (match_dup 1)) 2764 (set (reg:QI 22) (match_dup 2)) 2765 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 2766 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 2767 (clobber (reg:QI 23))]) 2768 (set (match_dup 0) (reg:QI 24)) 2769 (set (match_dup 3) (reg:QI 25))]) 2770 2771(define_insn "*udivmodqi4_call" 2772 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22))) 2773 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22))) 2774 (clobber (reg:QI 23))] 2775 "" 2776 "%~call __udivmodqi4" 2777 [(set_attr "type" "xcall") 2778 (set_attr "cc" "clobber")]) 2779 2780(define_insn_and_split "divmodhi4" 2781 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 2782 (div:HI (match_operand:HI 1 "pseudo_register_operand" "") 2783 (match_operand:HI 2 "pseudo_register_operand" ""))) 2784 (set (match_operand:HI 3 "pseudo_register_operand" "") 2785 (mod:HI (match_dup 1) (match_dup 2))) 2786 (clobber (reg:QI 21)) 2787 (clobber (reg:HI 22)) 2788 (clobber (reg:HI 24)) 2789 (clobber (reg:HI 26))])] 2790 "" 2791 "this should have been splitted;" 2792 "" 2793 [(set (reg:HI 24) (match_dup 1)) 2794 (set (reg:HI 22) (match_dup 2)) 2795 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 2796 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 2797 (clobber (reg:HI 26)) 2798 (clobber (reg:QI 21))]) 2799 (set (match_dup 0) (reg:HI 22)) 2800 (set (match_dup 3) (reg:HI 24))]) 2801 2802(define_insn "*divmodhi4_call" 2803 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22))) 2804 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22))) 2805 (clobber (reg:HI 26)) 2806 (clobber (reg:QI 21))] 2807 "" 2808 "%~call __divmodhi4" 2809 [(set_attr "type" "xcall") 2810 (set_attr "cc" "clobber")]) 2811 2812(define_insn_and_split "udivmodhi4" 2813 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 2814 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "") 2815 (match_operand:HI 2 "pseudo_register_operand" ""))) 2816 (set (match_operand:HI 3 "pseudo_register_operand" "") 2817 (umod:HI (match_dup 1) (match_dup 2))) 2818 (clobber (reg:QI 21)) 2819 (clobber (reg:HI 22)) 2820 (clobber (reg:HI 24)) 2821 (clobber (reg:HI 26))])] 2822 "" 2823 "this udivmodhi4 pattern should have been splitted.;" 2824 "" 2825 [(set (reg:HI 24) (match_dup 1)) 2826 (set (reg:HI 22) (match_dup 2)) 2827 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 2828 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 2829 (clobber (reg:HI 26)) 2830 (clobber (reg:QI 21))]) 2831 (set (match_dup 0) (reg:HI 22)) 2832 (set (match_dup 3) (reg:HI 24))]) 2833 2834(define_insn "*udivmodhi4_call" 2835 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22))) 2836 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22))) 2837 (clobber (reg:HI 26)) 2838 (clobber (reg:QI 21))] 2839 "" 2840 "%~call __udivmodhi4" 2841 [(set_attr "type" "xcall") 2842 (set_attr "cc" "clobber")]) 2843 2844;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2845;; 24-bit multiply 2846 2847;; To support widening multiplication with constant we postpone 2848;; expanding to the implicit library call until post combine and 2849;; prior to register allocation. Clobber all hard registers that 2850;; might be used by the (widening) multiply until it is split and 2851;; it's final register footprint is worked out. 2852 2853(define_expand "mulpsi3" 2854 [(parallel [(set (match_operand:PSI 0 "register_operand" "") 2855 (mult:PSI (match_operand:PSI 1 "register_operand" "") 2856 (match_operand:PSI 2 "nonmemory_operand" ""))) 2857 (clobber (reg:HI 26)) 2858 (clobber (reg:DI 18))])] 2859 "AVR_HAVE_MUL" 2860 { 2861 if (s8_operand (operands[2], PSImode)) 2862 { 2863 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 2864 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1])); 2865 DONE; 2866 } 2867 2868 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0, 2869 regmask (DImode, 18) | regmask (HImode, 26))) 2870 DONE; 2871 }) 2872 2873(define_insn "*umulqihipsi3" 2874 [(set (match_operand:PSI 0 "register_operand" "=&r") 2875 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r")) 2876 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))] 2877 "AVR_HAVE_MUL" 2878 "mul %1,%A2 2879 movw %A0,r0 2880 mul %1,%B2 2881 clr %C0 2882 add %B0,r0 2883 adc %C0,r1 2884 clr __zero_reg__" 2885 [(set_attr "length" "7") 2886 (set_attr "cc" "clobber")]) 2887 2888(define_insn "*umulhiqipsi3" 2889 [(set (match_operand:PSI 0 "register_operand" "=&r") 2890 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r")) 2891 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))] 2892 "AVR_HAVE_MUL" 2893 "mul %1,%A2 2894 movw %A0,r0 2895 mul %1,%B2 2896 add %B0,r0 2897 mov %C0,r1 2898 clr __zero_reg__ 2899 adc %C0,__zero_reg__" 2900 [(set_attr "length" "7") 2901 (set_attr "cc" "clobber")]) 2902 2903(define_expand "mulsqipsi3" 2904 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "") 2905 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "")) 2906 (match_operand:PSI 2 "pseudo_register_or_const_int_operand"""))) 2907 (clobber (reg:HI 26)) 2908 (clobber (reg:DI 18))])] 2909 "AVR_HAVE_MUL" 2910 { 2911 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u); 2912 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0, 2913 regmask (DImode, 18) | regmask (HImode, 26))) 2914 DONE; 2915 }) 2916 2917(define_insn_and_split "*mulsqipsi3" 2918 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r") 2919 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r")) 2920 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn"))) 2921 (clobber (reg:HI 26)) 2922 (clobber (reg:DI 18))] 2923 "AVR_HAVE_MUL && !reload_completed" 2924 { gcc_unreachable(); } 2925 "&& 1" 2926 [(set (reg:QI 25) 2927 (match_dup 1)) 2928 (set (reg:PSI 22) 2929 (match_dup 2)) 2930 (set (reg:PSI 18) 2931 (mult:PSI (sign_extend:PSI (reg:QI 25)) 2932 (reg:PSI 22))) 2933 (set (match_dup 0) 2934 (reg:PSI 18))]) 2935 2936(define_insn_and_split "*mulpsi3" 2937 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r") 2938 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r") 2939 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn"))) 2940 (clobber (reg:HI 26)) 2941 (clobber (reg:DI 18))] 2942 "AVR_HAVE_MUL && !reload_completed" 2943 { gcc_unreachable(); } 2944 "&& 1" 2945 [(set (reg:PSI 18) 2946 (match_dup 1)) 2947 (set (reg:PSI 22) 2948 (match_dup 2)) 2949 (parallel [(set (reg:PSI 22) 2950 (mult:PSI (reg:PSI 22) 2951 (reg:PSI 18))) 2952 (clobber (reg:QI 21)) 2953 (clobber (reg:QI 25)) 2954 (clobber (reg:HI 26))]) 2955 (set (match_dup 0) 2956 (reg:PSI 22))] 2957 { 2958 if (s8_operand (operands[2], PSImode)) 2959 { 2960 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode)); 2961 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1])); 2962 DONE; 2963 } 2964 }) 2965 2966(define_insn "*mulsqipsi3.libgcc" 2967 [(set (reg:PSI 18) 2968 (mult:PSI (sign_extend:PSI (reg:QI 25)) 2969 (reg:PSI 22)))] 2970 "AVR_HAVE_MUL" 2971 "%~call __mulsqipsi3" 2972 [(set_attr "type" "xcall") 2973 (set_attr "cc" "clobber")]) 2974 2975(define_insn "*mulpsi3.libgcc" 2976 [(set (reg:PSI 22) 2977 (mult:PSI (reg:PSI 22) 2978 (reg:PSI 18))) 2979 (clobber (reg:QI 21)) 2980 (clobber (reg:QI 25)) 2981 (clobber (reg:HI 26))] 2982 "AVR_HAVE_MUL" 2983 "%~call __mulpsi3" 2984 [(set_attr "type" "xcall") 2985 (set_attr "cc" "clobber")]) 2986 2987 2988;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2989;; 24-bit signed/unsigned division and modulo. 2990;; Notice that the libgcc implementation return the quotient in R22 2991;; and the remainder in R18 whereas the 32-bit [u]divmodsi4 2992;; implementation works the other way round. 2993 2994(define_insn_and_split "divmodpsi4" 2995 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "") 2996 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "") 2997 (match_operand:PSI 2 "pseudo_register_operand" ""))) 2998 (set (match_operand:PSI 3 "pseudo_register_operand" "") 2999 (mod:PSI (match_dup 1) 3000 (match_dup 2))) 3001 (clobber (reg:DI 18)) 3002 (clobber (reg:QI 26))])] 3003 "" 3004 { gcc_unreachable(); } 3005 "" 3006 [(set (reg:PSI 22) (match_dup 1)) 3007 (set (reg:PSI 18) (match_dup 2)) 3008 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 3009 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 3010 (clobber (reg:QI 21)) 3011 (clobber (reg:QI 25)) 3012 (clobber (reg:QI 26))]) 3013 (set (match_dup 0) (reg:PSI 22)) 3014 (set (match_dup 3) (reg:PSI 18))]) 3015 3016(define_insn "*divmodpsi4_call" 3017 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18))) 3018 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18))) 3019 (clobber (reg:QI 21)) 3020 (clobber (reg:QI 25)) 3021 (clobber (reg:QI 26))] 3022 "" 3023 "%~call __divmodpsi4" 3024 [(set_attr "type" "xcall") 3025 (set_attr "cc" "clobber")]) 3026 3027(define_insn_and_split "udivmodpsi4" 3028 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "") 3029 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "") 3030 (match_operand:PSI 2 "pseudo_register_operand" ""))) 3031 (set (match_operand:PSI 3 "pseudo_register_operand" "") 3032 (umod:PSI (match_dup 1) 3033 (match_dup 2))) 3034 (clobber (reg:DI 18)) 3035 (clobber (reg:QI 26))])] 3036 "" 3037 { gcc_unreachable(); } 3038 "" 3039 [(set (reg:PSI 22) (match_dup 1)) 3040 (set (reg:PSI 18) (match_dup 2)) 3041 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 3042 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 3043 (clobber (reg:QI 21)) 3044 (clobber (reg:QI 25)) 3045 (clobber (reg:QI 26))]) 3046 (set (match_dup 0) (reg:PSI 22)) 3047 (set (match_dup 3) (reg:PSI 18))]) 3048 3049(define_insn "*udivmodpsi4_call" 3050 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18))) 3051 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18))) 3052 (clobber (reg:QI 21)) 3053 (clobber (reg:QI 25)) 3054 (clobber (reg:QI 26))] 3055 "" 3056 "%~call __udivmodpsi4" 3057 [(set_attr "type" "xcall") 3058 (set_attr "cc" "clobber")]) 3059 3060;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3061 3062(define_insn_and_split "divmodsi4" 3063 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 3064 (div:SI (match_operand:SI 1 "pseudo_register_operand" "") 3065 (match_operand:SI 2 "pseudo_register_operand" ""))) 3066 (set (match_operand:SI 3 "pseudo_register_operand" "") 3067 (mod:SI (match_dup 1) (match_dup 2))) 3068 (clobber (reg:SI 18)) 3069 (clobber (reg:SI 22)) 3070 (clobber (reg:HI 26)) 3071 (clobber (reg:HI 30))])] 3072 "" 3073 "this divmodsi4 pattern should have been splitted;" 3074 "" 3075 [(set (reg:SI 22) (match_dup 1)) 3076 (set (reg:SI 18) (match_dup 2)) 3077 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 3078 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 3079 (clobber (reg:HI 26)) 3080 (clobber (reg:HI 30))]) 3081 (set (match_dup 0) (reg:SI 18)) 3082 (set (match_dup 3) (reg:SI 22))]) 3083 3084(define_insn "*divmodsi4_call" 3085 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18))) 3086 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18))) 3087 (clobber (reg:HI 26)) 3088 (clobber (reg:HI 30))] 3089 "" 3090 "%~call __divmodsi4" 3091 [(set_attr "type" "xcall") 3092 (set_attr "cc" "clobber")]) 3093 3094(define_insn_and_split "udivmodsi4" 3095 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 3096 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "") 3097 (match_operand:SI 2 "pseudo_register_operand" ""))) 3098 (set (match_operand:SI 3 "pseudo_register_operand" "") 3099 (umod:SI (match_dup 1) (match_dup 2))) 3100 (clobber (reg:SI 18)) 3101 (clobber (reg:SI 22)) 3102 (clobber (reg:HI 26)) 3103 (clobber (reg:HI 30))])] 3104 "" 3105 "this udivmodsi4 pattern should have been splitted;" 3106 "" 3107 [(set (reg:SI 22) (match_dup 1)) 3108 (set (reg:SI 18) (match_dup 2)) 3109 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 3110 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 3111 (clobber (reg:HI 26)) 3112 (clobber (reg:HI 30))]) 3113 (set (match_dup 0) (reg:SI 18)) 3114 (set (match_dup 3) (reg:SI 22))]) 3115 3116(define_insn "*udivmodsi4_call" 3117 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18))) 3118 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18))) 3119 (clobber (reg:HI 26)) 3120 (clobber (reg:HI 30))] 3121 "" 3122 "%~call __udivmodsi4" 3123 [(set_attr "type" "xcall") 3124 (set_attr "cc" "clobber")]) 3125 3126;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 3127; and 3128 3129(define_insn "andqi3" 3130 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 3131 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0") 3132 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))] 3133 "" 3134 "@ 3135 and %0,%2 3136 andi %0,lo8(%2) 3137 * return avr_out_bitop (insn, operands, NULL);" 3138 [(set_attr "length" "1,1,2") 3139 (set_attr "cc" "set_zn,set_zn,none")]) 3140 3141(define_insn "andhi3" 3142 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") 3143 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0") 3144 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n"))) 3145 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))] 3146 "" 3147 { 3148 if (which_alternative == 0) 3149 return "and %A0,%A2\;and %B0,%B2"; 3150 else if (which_alternative == 1) 3151 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)"; 3152 3153 return avr_out_bitop (insn, operands, NULL); 3154 } 3155 [(set_attr "length" "2,2,2,4,4") 3156 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop") 3157 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")]) 3158 3159(define_insn "andpsi3" 3160 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r") 3161 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0") 3162 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n"))) 3163 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 3164 "" 3165 { 3166 if (which_alternative == 0) 3167 return "and %A0,%A2" CR_TAB 3168 "and %B0,%B2" CR_TAB 3169 "and %C0,%C2"; 3170 3171 return avr_out_bitop (insn, operands, NULL); 3172 } 3173 [(set_attr "length" "3,3,6,6") 3174 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") 3175 (set_attr "cc" "set_n,clobber,clobber,clobber")]) 3176 3177(define_insn "andsi3" 3178 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r") 3179 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0") 3180 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n"))) 3181 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 3182 "" 3183 { 3184 if (which_alternative == 0) 3185 return "and %0,%2" CR_TAB 3186 "and %B0,%B2" CR_TAB 3187 "and %C0,%C2" CR_TAB 3188 "and %D0,%D2"; 3189 3190 return avr_out_bitop (insn, operands, NULL); 3191 } 3192 [(set_attr "length" "4,4,8,8") 3193 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") 3194 (set_attr "cc" "set_n,clobber,clobber,clobber")]) 3195 3196(define_peephole2 ; andi 3197 [(set (match_operand:QI 0 "d_register_operand" "") 3198 (and:QI (match_dup 0) 3199 (match_operand:QI 1 "const_int_operand" ""))) 3200 (set (match_dup 0) 3201 (and:QI (match_dup 0) 3202 (match_operand:QI 2 "const_int_operand" "")))] 3203 "" 3204 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] 3205 { 3206 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2])); 3207 }) 3208 3209;;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 3210;; ior 3211 3212(define_insn "iorqi3" 3213 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l") 3214 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0") 3215 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))] 3216 "" 3217 "@ 3218 or %0,%2 3219 ori %0,lo8(%2) 3220 * return avr_out_bitop (insn, operands, NULL);" 3221 [(set_attr "length" "1,1,2") 3222 (set_attr "cc" "set_zn,set_zn,none")]) 3223 3224(define_insn "iorhi3" 3225 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r") 3226 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0") 3227 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n"))) 3228 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))] 3229 "" 3230 { 3231 if (which_alternative == 0) 3232 return "or %A0,%A2\;or %B0,%B2"; 3233 else if (which_alternative == 1) 3234 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)"; 3235 3236 return avr_out_bitop (insn, operands, NULL); 3237 } 3238 [(set_attr "length" "2,2,2,4,4") 3239 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop") 3240 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")]) 3241 3242(define_insn "iorpsi3" 3243 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r") 3244 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0") 3245 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n"))) 3246 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 3247 "" 3248 { 3249 if (which_alternative == 0) 3250 return "or %A0,%A2" CR_TAB 3251 "or %B0,%B2" CR_TAB 3252 "or %C0,%C2"; 3253 3254 return avr_out_bitop (insn, operands, NULL); 3255 } 3256 [(set_attr "length" "3,3,6,6") 3257 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") 3258 (set_attr "cc" "set_n,clobber,clobber,clobber")]) 3259 3260(define_insn "iorsi3" 3261 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r") 3262 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0") 3263 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n"))) 3264 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))] 3265 "" 3266 { 3267 if (which_alternative == 0) 3268 return "or %0,%2" CR_TAB 3269 "or %B0,%B2" CR_TAB 3270 "or %C0,%C2" CR_TAB 3271 "or %D0,%D2"; 3272 3273 return avr_out_bitop (insn, operands, NULL); 3274 } 3275 [(set_attr "length" "4,4,8,8") 3276 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") 3277 (set_attr "cc" "set_n,clobber,clobber,clobber")]) 3278 3279;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 3280;; xor 3281 3282(define_insn "xorqi3" 3283 [(set (match_operand:QI 0 "register_operand" "=r") 3284 (xor:QI (match_operand:QI 1 "register_operand" "%0") 3285 (match_operand:QI 2 "register_operand" "r")))] 3286 "" 3287 "eor %0,%2" 3288 [(set_attr "length" "1") 3289 (set_attr "cc" "set_zn")]) 3290 3291(define_insn "xorhi3" 3292 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r") 3293 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0") 3294 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n"))) 3295 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 3296 "" 3297 { 3298 if (which_alternative == 0) 3299 return "eor %A0,%A2\;eor %B0,%B2"; 3300 3301 return avr_out_bitop (insn, operands, NULL); 3302 } 3303 [(set_attr "length" "2,2,4") 3304 (set_attr "adjust_len" "*,out_bitop,out_bitop") 3305 (set_attr "cc" "set_n,clobber,clobber")]) 3306 3307(define_insn "xorpsi3" 3308 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r") 3309 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0") 3310 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n"))) 3311 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 3312 "" 3313 { 3314 if (which_alternative == 0) 3315 return "eor %A0,%A2" CR_TAB 3316 "eor %B0,%B2" CR_TAB 3317 "eor %C0,%C2"; 3318 3319 return avr_out_bitop (insn, operands, NULL); 3320 } 3321 [(set_attr "length" "3,6,6") 3322 (set_attr "adjust_len" "*,out_bitop,out_bitop") 3323 (set_attr "cc" "set_n,clobber,clobber")]) 3324 3325(define_insn "xorsi3" 3326 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r") 3327 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0") 3328 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n"))) 3329 (clobber (match_scratch:QI 3 "=X,X ,&d"))] 3330 "" 3331 { 3332 if (which_alternative == 0) 3333 return "eor %0,%2" CR_TAB 3334 "eor %B0,%B2" CR_TAB 3335 "eor %C0,%C2" CR_TAB 3336 "eor %D0,%D2"; 3337 3338 return avr_out_bitop (insn, operands, NULL); 3339 } 3340 [(set_attr "length" "4,8,8") 3341 (set_attr "adjust_len" "*,out_bitop,out_bitop") 3342 (set_attr "cc" "set_n,clobber,clobber")]) 3343 3344 3345(define_split 3346 [(set (match_operand:SPLIT34 0 "register_operand") 3347 (match_operand:SPLIT34 1 "register_operand"))] 3348 "optimize 3349 && reload_completed" 3350 [(set (match_dup 2) (match_dup 3)) 3351 (set (match_dup 4) (match_dup 5))] 3352 { 3353 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode; 3354 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]); 3355 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0); 3356 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0); 3357 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2); 3358 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2); 3359 3360 operands[2] = lo_first ? dst_lo : dst_hi; 3361 operands[3] = lo_first ? src_lo : src_hi; 3362 operands[4] = lo_first ? dst_hi : dst_lo; 3363 operands[5] = lo_first ? src_hi : src_lo; 3364 }) 3365 3366(define_split 3367 [(set (match_operand:HI 0 "register_operand") 3368 (match_operand:HI 1 "reg_or_0_operand"))] 3369 "optimize 3370 && reload_completed 3371 && GENERAL_REG_P (operands[0]) 3372 && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1])) 3373 && (!AVR_HAVE_MOVW 3374 || const0_rtx == operands[1])" 3375 [(set (match_dup 2) (match_dup 3)) 3376 (set (match_dup 4) (match_dup 5))] 3377 { 3378 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 3379 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1); 3380 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 3381 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 3382 }) 3383 3384;; Split andhi3, andpsi3, andsi3. 3385;; Split iorhi3, iorpsi3, iorsi3. 3386;; Split xorhi3, xorpsi3, xorsi3. 3387(define_split 3388 [(parallel [(set (match_operand:HISI 0 "register_operand") 3389 (bitop:HISI (match_dup 0) 3390 (match_operand:HISI 1 "register_operand"))) 3391 (clobber (scratch:QI))])] 3392 "optimize 3393 && reload_completed" 3394 [(const_int 1)] 3395 { 3396 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++) 3397 { 3398 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); 3399 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i); 3400 emit_insn (gen_<code>qi3 (dst, dst, src)); 3401 } 3402 DONE; 3403 }) 3404 3405 3406;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap 3407;; swap 3408 3409(define_expand "rotlqi3" 3410 [(set (match_operand:QI 0 "register_operand" "") 3411 (rotate:QI (match_operand:QI 1 "register_operand" "") 3412 (match_operand:QI 2 "const_0_to_7_operand" "")))] 3413 "" 3414 { 3415 if (!CONST_INT_P (operands[2])) 3416 FAIL; 3417 3418 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode); 3419 }) 3420 3421;; Expander used by __builtin_avr_swap 3422(define_expand "rotlqi3_4" 3423 [(set (match_operand:QI 0 "register_operand" "") 3424 (rotate:QI (match_operand:QI 1 "register_operand" "") 3425 (const_int 4)))]) 3426 3427(define_insn "*rotlqi3" 3428 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r") 3429 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0") 3430 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))] 3431 "" 3432 "@ 3433 lsl %0\;adc %0,__zero_reg__ 3434 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__ 3435 swap %0\;bst %0,0\;ror %0\;bld %0,7 3436 swap %0 3437 swap %0\;lsl %0\;adc %0,__zero_reg__ 3438 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__ 3439 bst %0,0\;ror %0\;bld %0,7 3440 " ; empty 3441 [(set_attr "length" "2,4,4,1,3,5,3,0") 3442 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")]) 3443 3444;; Split all rotates of HI,SI and PSImode registers where rotation is by 3445;; a whole number of bytes. The split creates the appropriate moves and 3446;; considers all overlap situations. 3447 3448;; HImode does not need scratch. Use attribute for this constraint. 3449 3450(define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")]) 3451(define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")]) 3452 3453;; "rotlhi3" 3454;; "rotlpsi3" 3455;; "rotlsi3" 3456(define_expand "rotl<mode>3" 3457 [(parallel [(set (match_operand:HISI 0 "register_operand" "") 3458 (rotate:HISI (match_operand:HISI 1 "register_operand" "") 3459 (match_operand:HISI 2 "const_int_operand" ""))) 3460 (clobber (match_dup 3))])] 3461 "" 3462 { 3463 int offset; 3464 3465 if (!CONST_INT_P (operands[2])) 3466 FAIL; 3467 3468 offset = INTVAL (operands[2]); 3469 3470 if (0 == offset % 8) 3471 { 3472 if (AVR_HAVE_MOVW && 0 == offset % 16) 3473 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode); 3474 else 3475 operands[3] = gen_rtx_SCRATCH (QImode); 3476 } 3477 else if (offset == 1 3478 || offset == GET_MODE_BITSIZE (<MODE>mode) -1) 3479 { 3480 /*; Support rotate left/right by 1 */ 3481 3482 emit_move_insn (operands[0], 3483 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2])); 3484 DONE; 3485 } 3486 else 3487 FAIL; 3488 }) 3489 3490(define_insn "*rotlhi2.1" 3491 [(set (match_operand:HI 0 "register_operand" "=r") 3492 (rotate:HI (match_operand:HI 1 "register_operand" "0") 3493 (const_int 1)))] 3494 "" 3495 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__" 3496 [(set_attr "length" "3") 3497 (set_attr "cc" "clobber")]) 3498 3499(define_insn "*rotlhi2.15" 3500 [(set (match_operand:HI 0 "register_operand" "=r") 3501 (rotate:HI (match_operand:HI 1 "register_operand" "0") 3502 (const_int 15)))] 3503 "" 3504 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7" 3505 [(set_attr "length" "4") 3506 (set_attr "cc" "clobber")]) 3507 3508(define_insn "*rotlpsi2.1" 3509 [(set (match_operand:PSI 0 "register_operand" "=r") 3510 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 3511 (const_int 1)))] 3512 "" 3513 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__" 3514 [(set_attr "length" "4") 3515 (set_attr "cc" "clobber")]) 3516 3517(define_insn "*rotlpsi2.23" 3518 [(set (match_operand:PSI 0 "register_operand" "=r") 3519 (rotate:PSI (match_operand:PSI 1 "register_operand" "0") 3520 (const_int 23)))] 3521 "" 3522 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7" 3523 [(set_attr "length" "5") 3524 (set_attr "cc" "clobber")]) 3525 3526(define_insn "*rotlsi2.1" 3527 [(set (match_operand:SI 0 "register_operand" "=r") 3528 (rotate:SI (match_operand:SI 1 "register_operand" "0") 3529 (const_int 1)))] 3530 "" 3531 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__" 3532 [(set_attr "length" "5") 3533 (set_attr "cc" "clobber")]) 3534 3535(define_insn "*rotlsi2.31" 3536 [(set (match_operand:SI 0 "register_operand" "=r") 3537 (rotate:SI (match_operand:SI 1 "register_operand" "0") 3538 (const_int 31)))] 3539 "" 3540 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7" 3541 [(set_attr "length" "6") 3542 (set_attr "cc" "clobber")]) 3543 3544;; Overlapping non-HImode registers often (but not always) need a scratch. 3545;; The best we can do is use early clobber alternative "#&r" so that 3546;; completely non-overlapping operands dont get a scratch but # so register 3547;; allocation does not prefer non-overlapping. 3548 3549 3550;; Split word aligned rotates using scratch that is mode dependent. 3551 3552;; "*rotwhi" 3553;; "*rotwsi" 3554(define_insn_and_split "*rotw<mode>" 3555 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r") 3556 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r") 3557 (match_operand 2 "const_int_operand" "n,n,n"))) 3558 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))] 3559 "AVR_HAVE_MOVW 3560 && CONST_INT_P (operands[2]) 3561 && GET_MODE_SIZE (<MODE>mode) % 2 == 0 3562 && 0 == INTVAL (operands[2]) % 16" 3563 "#" 3564 "&& reload_completed" 3565 [(const_int 0)] 3566 { 3567 avr_rotate_bytes (operands); 3568 DONE; 3569 }) 3570 3571 3572;; Split byte aligned rotates using scratch that is always QI mode. 3573 3574;; "*rotbhi" 3575;; "*rotbpsi" 3576;; "*rotbsi" 3577(define_insn_and_split "*rotb<mode>" 3578 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r") 3579 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r") 3580 (match_operand 2 "const_int_operand" "n,n,n"))) 3581 (clobber (match_scratch:QI 3 "=<rotx>"))] 3582 "CONST_INT_P (operands[2]) 3583 && (8 == INTVAL (operands[2]) % 16 3584 || ((!AVR_HAVE_MOVW 3585 || GET_MODE_SIZE (<MODE>mode) % 2 != 0) 3586 && 0 == INTVAL (operands[2]) % 16))" 3587 "#" 3588 "&& reload_completed" 3589 [(const_int 0)] 3590 { 3591 avr_rotate_bytes (operands); 3592 DONE; 3593 }) 3594 3595 3596;;<< << << << << << << << << << << << << << << << << << << << << << << << << << 3597;; arithmetic shift left 3598 3599;; "ashlqi3" 3600;; "ashlqq3" "ashluqq3" 3601(define_expand "ashl<mode>3" 3602 [(set (match_operand:ALL1 0 "register_operand" "") 3603 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "") 3604 (match_operand:QI 2 "nop_general_operand" "")))]) 3605 3606(define_split ; ashlqi3_const4 3607 [(set (match_operand:ALL1 0 "d_register_operand" "") 3608 (ashift:ALL1 (match_dup 0) 3609 (const_int 4)))] 3610 "" 3611 [(set (match_dup 1) 3612 (rotate:QI (match_dup 1) 3613 (const_int 4))) 3614 (set (match_dup 1) 3615 (and:QI (match_dup 1) 3616 (const_int -16)))] 3617 { 3618 operands[1] = avr_to_int_mode (operands[0]); 3619 }) 3620 3621(define_split ; ashlqi3_const5 3622 [(set (match_operand:ALL1 0 "d_register_operand" "") 3623 (ashift:ALL1 (match_dup 0) 3624 (const_int 5)))] 3625 "" 3626 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 3627 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1))) 3628 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))] 3629 { 3630 operands[1] = avr_to_int_mode (operands[0]); 3631 }) 3632 3633(define_split ; ashlqi3_const6 3634 [(set (match_operand:ALL1 0 "d_register_operand" "") 3635 (ashift:ALL1 (match_dup 0) 3636 (const_int 6)))] 3637 "" 3638 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 3639 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2))) 3640 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))] 3641 { 3642 operands[1] = avr_to_int_mode (operands[0]); 3643 }) 3644 3645;; "*ashlqi3" 3646;; "*ashlqq3" "*ashluqq3" 3647(define_insn "*ashl<mode>3" 3648 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r") 3649 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0") 3650 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))] 3651 "" 3652 { 3653 return ashlqi3_out (insn, operands, NULL); 3654 } 3655 [(set_attr "length" "5,0,1,2,4,6,9") 3656 (set_attr "adjust_len" "ashlqi") 3657 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) 3658 3659(define_insn "ashl<mode>3" 3660 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 3661 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 3662 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 3663 "" 3664 { 3665 return ashlhi3_out (insn, operands, NULL); 3666 } 3667 [(set_attr "length" "6,0,2,2,4,10,10") 3668 (set_attr "adjust_len" "ashlhi") 3669 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) 3670 3671 3672;; Insns like the following are generated when (implicitly) extending 8-bit shifts 3673;; like char1 = char2 << char3. Only the low-byte is needed in that situation. 3674 3675;; "*ashluqihiqi3" 3676;; "*ashlsqihiqi3" 3677(define_insn_and_split "*ashl<extend_su>qihiqi3" 3678 [(set (match_operand:QI 0 "register_operand" "=r") 3679 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0")) 3680 (match_operand:QI 2 "register_operand" "r")) 3681 0))] 3682 "" 3683 "#" 3684 "" 3685 [(set (match_dup 0) 3686 (ashift:QI (match_dup 1) 3687 (match_dup 2)))]) 3688 3689;; ??? Combiner does not recognize that it could split the following insn; 3690;; presumably because he has no register handy? 3691 3692;; "*ashluqihiqi3.mem" 3693;; "*ashlsqihiqi3.mem" 3694(define_insn_and_split "*ashl<extend_su>qihiqi3.mem" 3695 [(set (match_operand:QI 0 "memory_operand" "=m") 3696 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r")) 3697 (match_operand:QI 2 "register_operand" "r")) 3698 0))] 3699 "!reload_completed" 3700 { gcc_unreachable(); } 3701 "&& 1" 3702 [(set (match_dup 3) 3703 (ashift:QI (match_dup 1) 3704 (match_dup 2))) 3705 (set (match_dup 0) 3706 (match_dup 3))] 3707 { 3708 operands[3] = gen_reg_rtx (QImode); 3709 }) 3710 3711;; Similar. 3712 3713(define_insn_and_split "*ashlhiqi3" 3714 [(set (match_operand:QI 0 "nonimmediate_operand" "=r") 3715 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0") 3716 (match_operand:QI 2 "register_operand" "r")) 0))] 3717 "!reload_completed" 3718 { gcc_unreachable(); } 3719 "&& 1" 3720 [(set (match_dup 4) 3721 (ashift:QI (match_dup 3) 3722 (match_dup 2))) 3723 (set (match_dup 0) 3724 (match_dup 4))] 3725 { 3726 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 3727 operands[4] = gen_reg_rtx (QImode); 3728 }) 3729 3730;; High part of 16-bit shift is unused after the instruction: 3731;; No need to compute it, map to 8-bit shift. 3732 3733(define_peephole2 3734 [(set (match_operand:HI 0 "register_operand" "") 3735 (ashift:HI (match_dup 0) 3736 (match_operand:QI 1 "register_operand" "")))] 3737 "" 3738 [(set (match_dup 2) 3739 (ashift:QI (match_dup 2) 3740 (match_dup 1))) 3741 (clobber (match_dup 3))] 3742 { 3743 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 3744 3745 if (!peep2_reg_dead_p (1, operands[3])) 3746 FAIL; 3747 3748 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 3749 }) 3750 3751 3752;; "ashlsi3" 3753;; "ashlsq3" "ashlusq3" 3754;; "ashlsa3" "ashlusa3" 3755(define_insn "ashl<mode>3" 3756 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 3757 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 3758 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 3759 "" 3760 { 3761 return ashlsi3_out (insn, operands, NULL); 3762 } 3763 [(set_attr "length" "8,0,4,4,8,10,12") 3764 (set_attr "adjust_len" "ashlsi") 3765 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) 3766 3767;; Optimize if a scratch register from LD_REGS happens to be available. 3768 3769(define_peephole2 ; ashlqi3_l_const4 3770 [(set (match_operand:ALL1 0 "l_register_operand" "") 3771 (ashift:ALL1 (match_dup 0) 3772 (const_int 4))) 3773 (match_scratch:QI 1 "d")] 3774 "" 3775 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 3776 (set (match_dup 1) (const_int -16)) 3777 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 3778 { 3779 operands[2] = avr_to_int_mode (operands[0]); 3780 }) 3781 3782(define_peephole2 ; ashlqi3_l_const5 3783 [(set (match_operand:ALL1 0 "l_register_operand" "") 3784 (ashift:ALL1 (match_dup 0) 3785 (const_int 5))) 3786 (match_scratch:QI 1 "d")] 3787 "" 3788 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 3789 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1))) 3790 (set (match_dup 1) (const_int -32)) 3791 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 3792 { 3793 operands[2] = avr_to_int_mode (operands[0]); 3794 }) 3795 3796(define_peephole2 ; ashlqi3_l_const6 3797 [(set (match_operand:ALL1 0 "l_register_operand" "") 3798 (ashift:ALL1 (match_dup 0) 3799 (const_int 6))) 3800 (match_scratch:QI 1 "d")] 3801 "" 3802 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 3803 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2))) 3804 (set (match_dup 1) (const_int -64)) 3805 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 3806 { 3807 operands[2] = avr_to_int_mode (operands[0]); 3808 }) 3809 3810(define_peephole2 3811 [(match_scratch:QI 3 "d") 3812 (set (match_operand:ALL2 0 "register_operand" "") 3813 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "") 3814 (match_operand:QI 2 "const_int_operand" "")))] 3815 "" 3816 [(parallel [(set (match_dup 0) 3817 (ashift:ALL2 (match_dup 1) 3818 (match_dup 2))) 3819 (clobber (match_dup 3))])]) 3820 3821;; "*ashlhi3_const" 3822;; "*ashlhq3_const" "*ashluhq3_const" 3823;; "*ashlha3_const" "*ashluha3_const" 3824(define_insn "*ashl<mode>3_const" 3825 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 3826 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 3827 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 3828 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 3829 "reload_completed" 3830 { 3831 return ashlhi3_out (insn, operands, NULL); 3832 } 3833 [(set_attr "length" "0,2,2,4,10") 3834 (set_attr "adjust_len" "ashlhi") 3835 (set_attr "cc" "none,set_n,clobber,set_n,clobber")]) 3836 3837(define_peephole2 3838 [(match_scratch:QI 3 "d") 3839 (set (match_operand:ALL4 0 "register_operand" "") 3840 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "") 3841 (match_operand:QI 2 "const_int_operand" "")))] 3842 "" 3843 [(parallel [(set (match_dup 0) 3844 (ashift:ALL4 (match_dup 1) 3845 (match_dup 2))) 3846 (clobber (match_dup 3))])]) 3847 3848;; "*ashlsi3_const" 3849;; "*ashlsq3_const" "*ashlusq3_const" 3850;; "*ashlsa3_const" "*ashlusa3_const" 3851(define_insn "*ashl<mode>3_const" 3852 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 3853 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 3854 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 3855 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 3856 "reload_completed" 3857 { 3858 return ashlsi3_out (insn, operands, NULL); 3859 } 3860 [(set_attr "length" "0,4,4,10") 3861 (set_attr "adjust_len" "ashlsi") 3862 (set_attr "cc" "none,set_n,clobber,clobber")]) 3863 3864(define_expand "ashlpsi3" 3865 [(parallel [(set (match_operand:PSI 0 "register_operand" "") 3866 (ashift:PSI (match_operand:PSI 1 "register_operand" "") 3867 (match_operand:QI 2 "nonmemory_operand" ""))) 3868 (clobber (scratch:QI))])] 3869 "" 3870 { 3871 if (AVR_HAVE_MUL 3872 && CONST_INT_P (operands[2])) 3873 { 3874 if (IN_RANGE (INTVAL (operands[2]), 3, 6)) 3875 { 3876 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode)); 3877 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1])); 3878 DONE; 3879 } 3880 else if (optimize_insn_for_speed_p () 3881 && INTVAL (operands[2]) != 16 3882 && IN_RANGE (INTVAL (operands[2]), 9, 22)) 3883 { 3884 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode)); 3885 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset)); 3886 DONE; 3887 } 3888 } 3889 }) 3890 3891(define_insn "*ashlpsi3" 3892 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r") 3893 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0") 3894 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n"))) 3895 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 3896 "" 3897 { 3898 return avr_out_ashlpsi3 (insn, operands, NULL); 3899 } 3900 [(set_attr "adjust_len" "ashlpsi") 3901 (set_attr "cc" "clobber")]) 3902 3903;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> 3904;; arithmetic shift right 3905 3906;; "ashrqi3" 3907;; "ashrqq3" "ashruqq3" 3908(define_insn "ashr<mode>3" 3909 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r") 3910 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0") 3911 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))] 3912 "" 3913 { 3914 return ashrqi3_out (insn, operands, NULL); 3915 } 3916 [(set_attr "length" "5,0,1,2,5,4,9") 3917 (set_attr "adjust_len" "ashrqi") 3918 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")]) 3919 3920;; "ashrhi3" 3921;; "ashrhq3" "ashruhq3" 3922;; "ashrha3" "ashruha3" 3923(define_insn "ashr<mode>3" 3924 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 3925 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 3926 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 3927 "" 3928 { 3929 return ashrhi3_out (insn, operands, NULL); 3930 } 3931 [(set_attr "length" "6,0,2,4,4,10,10") 3932 (set_attr "adjust_len" "ashrhi") 3933 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) 3934 3935(define_insn "ashrpsi3" 3936 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r") 3937 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0") 3938 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n"))) 3939 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 3940 "" 3941 { 3942 return avr_out_ashrpsi3 (insn, operands, NULL); 3943 } 3944 [(set_attr "adjust_len" "ashrpsi") 3945 (set_attr "cc" "clobber")]) 3946 3947;; "ashrsi3" 3948;; "ashrsq3" "ashrusq3" 3949;; "ashrsa3" "ashrusa3" 3950(define_insn "ashr<mode>3" 3951 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 3952 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 3953 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 3954 "" 3955 { 3956 return ashrsi3_out (insn, operands, NULL); 3957 } 3958 [(set_attr "length" "8,0,4,6,8,10,12") 3959 (set_attr "adjust_len" "ashrsi") 3960 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) 3961 3962;; Optimize if a scratch register from LD_REGS happens to be available. 3963 3964(define_peephole2 3965 [(match_scratch:QI 3 "d") 3966 (set (match_operand:ALL2 0 "register_operand" "") 3967 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "") 3968 (match_operand:QI 2 "const_int_operand" "")))] 3969 "" 3970 [(parallel [(set (match_dup 0) 3971 (ashiftrt:ALL2 (match_dup 1) 3972 (match_dup 2))) 3973 (clobber (match_dup 3))])]) 3974 3975;; "*ashrhi3_const" 3976;; "*ashrhq3_const" "*ashruhq3_const" 3977;; "*ashrha3_const" "*ashruha3_const" 3978(define_insn "*ashr<mode>3_const" 3979 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 3980 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 3981 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 3982 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 3983 "reload_completed" 3984 { 3985 return ashrhi3_out (insn, operands, NULL); 3986 } 3987 [(set_attr "length" "0,2,4,4,10") 3988 (set_attr "adjust_len" "ashrhi") 3989 (set_attr "cc" "none,clobber,set_n,clobber,clobber")]) 3990 3991(define_peephole2 3992 [(match_scratch:QI 3 "d") 3993 (set (match_operand:ALL4 0 "register_operand" "") 3994 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "") 3995 (match_operand:QI 2 "const_int_operand" "")))] 3996 "" 3997 [(parallel [(set (match_dup 0) 3998 (ashiftrt:ALL4 (match_dup 1) 3999 (match_dup 2))) 4000 (clobber (match_dup 3))])]) 4001 4002;; "*ashrsi3_const" 4003;; "*ashrsq3_const" "*ashrusq3_const" 4004;; "*ashrsa3_const" "*ashrusa3_const" 4005(define_insn "*ashr<mode>3_const" 4006 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 4007 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 4008 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 4009 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 4010 "reload_completed" 4011 { 4012 return ashrsi3_out (insn, operands, NULL); 4013 } 4014 [(set_attr "length" "0,4,4,10") 4015 (set_attr "adjust_len" "ashrsi") 4016 (set_attr "cc" "none,clobber,set_n,clobber")]) 4017 4018;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> 4019;; logical shift right 4020 4021;; "lshrqi3" 4022;; "lshrqq3" "lshruqq3" 4023(define_expand "lshr<mode>3" 4024 [(set (match_operand:ALL1 0 "register_operand" "") 4025 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "") 4026 (match_operand:QI 2 "nop_general_operand" "")))]) 4027 4028(define_split ; lshrqi3_const4 4029 [(set (match_operand:ALL1 0 "d_register_operand" "") 4030 (lshiftrt:ALL1 (match_dup 0) 4031 (const_int 4)))] 4032 "" 4033 [(set (match_dup 1) 4034 (rotate:QI (match_dup 1) 4035 (const_int 4))) 4036 (set (match_dup 1) 4037 (and:QI (match_dup 1) 4038 (const_int 15)))] 4039 { 4040 operands[1] = avr_to_int_mode (operands[0]); 4041 }) 4042 4043(define_split ; lshrqi3_const5 4044 [(set (match_operand:ALL1 0 "d_register_operand" "") 4045 (lshiftrt:ALL1 (match_dup 0) 4046 (const_int 5)))] 4047 "" 4048 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 4049 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1))) 4050 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))] 4051 { 4052 operands[1] = avr_to_int_mode (operands[0]); 4053 }) 4054 4055(define_split ; lshrqi3_const6 4056 [(set (match_operand:QI 0 "d_register_operand" "") 4057 (lshiftrt:QI (match_dup 0) 4058 (const_int 6)))] 4059 "" 4060 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4))) 4061 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2))) 4062 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))] 4063 { 4064 operands[1] = avr_to_int_mode (operands[0]); 4065 }) 4066 4067;; "*lshrqi3" 4068;; "*lshrqq3" 4069;; "*lshruqq3" 4070(define_insn "*lshr<mode>3" 4071 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r") 4072 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0") 4073 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))] 4074 "" 4075 { 4076 return lshrqi3_out (insn, operands, NULL); 4077 } 4078 [(set_attr "length" "5,0,1,2,4,6,9") 4079 (set_attr "adjust_len" "lshrqi") 4080 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) 4081 4082;; "lshrhi3" 4083;; "lshrhq3" "lshruhq3" 4084;; "lshrha3" "lshruha3" 4085(define_insn "lshr<mode>3" 4086 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r") 4087 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0") 4088 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 4089 "" 4090 { 4091 return lshrhi3_out (insn, operands, NULL); 4092 } 4093 [(set_attr "length" "6,0,2,2,4,10,10") 4094 (set_attr "adjust_len" "lshrhi") 4095 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) 4096 4097(define_insn "lshrpsi3" 4098 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r") 4099 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0") 4100 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n"))) 4101 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 4102 "" 4103 { 4104 return avr_out_lshrpsi3 (insn, operands, NULL); 4105 } 4106 [(set_attr "adjust_len" "lshrpsi") 4107 (set_attr "cc" "clobber")]) 4108 4109;; "lshrsi3" 4110;; "lshrsq3" "lshrusq3" 4111;; "lshrsa3" "lshrusa3" 4112(define_insn "lshr<mode>3" 4113 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r") 4114 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0") 4115 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] 4116 "" 4117 { 4118 return lshrsi3_out (insn, operands, NULL); 4119 } 4120 [(set_attr "length" "8,0,4,4,8,10,12") 4121 (set_attr "adjust_len" "lshrsi") 4122 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) 4123 4124;; Optimize if a scratch register from LD_REGS happens to be available. 4125 4126(define_peephole2 ; lshrqi3_l_const4 4127 [(set (match_operand:ALL1 0 "l_register_operand" "") 4128 (lshiftrt:ALL1 (match_dup 0) 4129 (const_int 4))) 4130 (match_scratch:QI 1 "d")] 4131 "" 4132 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 4133 (set (match_dup 1) (const_int 15)) 4134 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 4135 { 4136 operands[2] = avr_to_int_mode (operands[0]); 4137 }) 4138 4139(define_peephole2 ; lshrqi3_l_const5 4140 [(set (match_operand:ALL1 0 "l_register_operand" "") 4141 (lshiftrt:ALL1 (match_dup 0) 4142 (const_int 5))) 4143 (match_scratch:QI 1 "d")] 4144 "" 4145 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 4146 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1))) 4147 (set (match_dup 1) (const_int 7)) 4148 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 4149 { 4150 operands[2] = avr_to_int_mode (operands[0]); 4151 }) 4152 4153(define_peephole2 ; lshrqi3_l_const6 4154 [(set (match_operand:ALL1 0 "l_register_operand" "") 4155 (lshiftrt:ALL1 (match_dup 0) 4156 (const_int 6))) 4157 (match_scratch:QI 1 "d")] 4158 "" 4159 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4))) 4160 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2))) 4161 (set (match_dup 1) (const_int 3)) 4162 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))] 4163 { 4164 operands[2] = avr_to_int_mode (operands[0]); 4165 }) 4166 4167(define_peephole2 4168 [(match_scratch:QI 3 "d") 4169 (set (match_operand:ALL2 0 "register_operand" "") 4170 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "") 4171 (match_operand:QI 2 "const_int_operand" "")))] 4172 "" 4173 [(parallel [(set (match_dup 0) 4174 (lshiftrt:ALL2 (match_dup 1) 4175 (match_dup 2))) 4176 (clobber (match_dup 3))])]) 4177 4178;; "*lshrhi3_const" 4179;; "*lshrhq3_const" "*lshruhq3_const" 4180;; "*lshrha3_const" "*lshruha3_const" 4181(define_insn "*lshr<mode>3_const" 4182 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r") 4183 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0") 4184 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) 4185 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] 4186 "reload_completed" 4187 { 4188 return lshrhi3_out (insn, operands, NULL); 4189 } 4190 [(set_attr "length" "0,2,2,4,10") 4191 (set_attr "adjust_len" "lshrhi") 4192 (set_attr "cc" "none,clobber,clobber,clobber,clobber")]) 4193 4194(define_peephole2 4195 [(match_scratch:QI 3 "d") 4196 (set (match_operand:ALL4 0 "register_operand" "") 4197 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "") 4198 (match_operand:QI 2 "const_int_operand" "")))] 4199 "" 4200 [(parallel [(set (match_dup 0) 4201 (lshiftrt:ALL4 (match_dup 1) 4202 (match_dup 2))) 4203 (clobber (match_dup 3))])]) 4204 4205;; "*lshrsi3_const" 4206;; "*lshrsq3_const" "*lshrusq3_const" 4207;; "*lshrsa3_const" "*lshrusa3_const" 4208(define_insn "*lshr<mode>3_const" 4209 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r") 4210 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0") 4211 (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) 4212 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 4213 "reload_completed" 4214 { 4215 return lshrsi3_out (insn, operands, NULL); 4216 } 4217 [(set_attr "length" "0,4,4,10") 4218 (set_attr "adjust_len" "lshrsi") 4219 (set_attr "cc" "none,clobber,clobber,clobber")]) 4220 4221;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) 4222;; abs 4223 4224(define_insn "absqi2" 4225 [(set (match_operand:QI 0 "register_operand" "=r") 4226 (abs:QI (match_operand:QI 1 "register_operand" "0")))] 4227 "" 4228 "sbrc %0,7 4229 neg %0" 4230 [(set_attr "length" "2") 4231 (set_attr "cc" "clobber")]) 4232 4233 4234(define_insn "abssf2" 4235 [(set (match_operand:SF 0 "register_operand" "=d,r") 4236 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))] 4237 "" 4238 "@ 4239 andi %D0,0x7f 4240 clt\;bld %D0,7" 4241 [(set_attr "length" "1,2") 4242 (set_attr "cc" "set_n,clobber")]) 4243 4244;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 4245;; neg 4246 4247(define_insn "negqi2" 4248 [(set (match_operand:QI 0 "register_operand" "=r") 4249 (neg:QI (match_operand:QI 1 "register_operand" "0")))] 4250 "" 4251 "neg %0" 4252 [(set_attr "length" "1") 4253 (set_attr "cc" "set_vzn")]) 4254 4255(define_insn "*negqihi2" 4256 [(set (match_operand:HI 0 "register_operand" "=r") 4257 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))] 4258 "" 4259 "clr %B0\;neg %A0\;brge .+2\;com %B0" 4260 [(set_attr "length" "4") 4261 (set_attr "cc" "set_n")]) 4262 4263(define_insn "neghi2" 4264 [(set (match_operand:HI 0 "register_operand" "=r,&r") 4265 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))] 4266 "" 4267 "@ 4268 neg %B0\;neg %A0\;sbc %B0,__zero_reg__ 4269 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1" 4270 [(set_attr "length" "3,4") 4271 (set_attr "cc" "set_czn")]) 4272 4273(define_insn "negpsi2" 4274 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r") 4275 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))] 4276 "" 4277 "@ 4278 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1 4279 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__ 4280 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1" 4281 [(set_attr "length" "5,6,6") 4282 (set_attr "cc" "set_czn,set_n,set_czn")]) 4283 4284(define_insn "negsi2" 4285 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r") 4286 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))] 4287 "" 4288 "@ 4289 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1) 4290 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__ 4291 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1 4292 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1" 4293 [(set_attr "length" "7,8,8,7") 4294 (set_attr "isa" "*,*,mov,movw") 4295 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")]) 4296 4297(define_insn "negsf2" 4298 [(set (match_operand:SF 0 "register_operand" "=d,r") 4299 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))] 4300 "" 4301 "@ 4302 subi %D0,0x80 4303 bst %D0,7\;com %D0\;bld %D0,7\;com %D0" 4304 [(set_attr "length" "1,4") 4305 (set_attr "cc" "set_n,set_n")]) 4306 4307;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 4308;; not 4309 4310(define_insn "one_cmplqi2" 4311 [(set (match_operand:QI 0 "register_operand" "=r") 4312 (not:QI (match_operand:QI 1 "register_operand" "0")))] 4313 "" 4314 "com %0" 4315 [(set_attr "length" "1") 4316 (set_attr "cc" "set_czn")]) 4317 4318(define_insn "one_cmplhi2" 4319 [(set (match_operand:HI 0 "register_operand" "=r") 4320 (not:HI (match_operand:HI 1 "register_operand" "0")))] 4321 "" 4322 "com %0 4323 com %B0" 4324 [(set_attr "length" "2") 4325 (set_attr "cc" "set_n")]) 4326 4327(define_insn "one_cmplpsi2" 4328 [(set (match_operand:PSI 0 "register_operand" "=r") 4329 (not:PSI (match_operand:PSI 1 "register_operand" "0")))] 4330 "" 4331 "com %0\;com %B0\;com %C0" 4332 [(set_attr "length" "3") 4333 (set_attr "cc" "set_n")]) 4334 4335(define_insn "one_cmplsi2" 4336 [(set (match_operand:SI 0 "register_operand" "=r") 4337 (not:SI (match_operand:SI 1 "register_operand" "0")))] 4338 "" 4339 "com %0 4340 com %B0 4341 com %C0 4342 com %D0" 4343 [(set_attr "length" "4") 4344 (set_attr "cc" "set_n")]) 4345 4346;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x 4347;; sign extend 4348 4349;; We keep combiner from inserting hard registers into the input of sign- and 4350;; zero-extends. A hard register in the input operand is not wanted because 4351;; 32-bit multiply patterns clobber some hard registers and extends with a 4352;; hard register that overlaps these clobbers won't be combined to a widening 4353;; multiplication. There is no need for combine to propagate hard registers, 4354;; register allocation can do it just as well. 4355 4356(define_insn "extendqihi2" 4357 [(set (match_operand:HI 0 "register_operand" "=r,r") 4358 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 4359 "" 4360 { 4361 return avr_out_sign_extend (insn, operands, NULL); 4362 } 4363 [(set_attr "length" "3,4") 4364 (set_attr "adjust_len" "sext") 4365 (set_attr "cc" "set_n")]) 4366 4367(define_insn "extendqipsi2" 4368 [(set (match_operand:PSI 0 "register_operand" "=r,r") 4369 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 4370 "" 4371 { 4372 return avr_out_sign_extend (insn, operands, NULL); 4373 } 4374 [(set_attr "length" "4,5") 4375 (set_attr "adjust_len" "sext") 4376 (set_attr "cc" "set_n")]) 4377 4378(define_insn "extendqisi2" 4379 [(set (match_operand:SI 0 "register_operand" "=r,r") 4380 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))] 4381 "" 4382 { 4383 return avr_out_sign_extend (insn, operands, NULL); 4384 } 4385 [(set_attr "length" "5,6") 4386 (set_attr "adjust_len" "sext") 4387 (set_attr "cc" "set_n")]) 4388 4389(define_insn "extendhipsi2" 4390 [(set (match_operand:PSI 0 "register_operand" "=r,r") 4391 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))] 4392 "" 4393 { 4394 return avr_out_sign_extend (insn, operands, NULL); 4395 } 4396 [(set_attr "length" "3,5") 4397 (set_attr "adjust_len" "sext") 4398 (set_attr "cc" "set_n")]) 4399 4400(define_insn "extendhisi2" 4401 [(set (match_operand:SI 0 "register_operand" "=r,r") 4402 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))] 4403 "" 4404 { 4405 return avr_out_sign_extend (insn, operands, NULL); 4406 } 4407 [(set_attr "length" "4,6") 4408 (set_attr "adjust_len" "sext") 4409 (set_attr "cc" "set_n")]) 4410 4411(define_insn "extendpsisi2" 4412 [(set (match_operand:SI 0 "register_operand" "=r") 4413 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))] 4414 "" 4415 { 4416 return avr_out_sign_extend (insn, operands, NULL); 4417 } 4418 [(set_attr "length" "3") 4419 (set_attr "adjust_len" "sext") 4420 (set_attr "cc" "set_n")]) 4421 4422;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x 4423;; zero extend 4424 4425(define_insn_and_split "zero_extendqihi2" 4426 [(set (match_operand:HI 0 "register_operand" "=r") 4427 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 4428 "" 4429 "#" 4430 "reload_completed" 4431 [(set (match_dup 2) (match_dup 1)) 4432 (set (match_dup 3) (const_int 0))] 4433 { 4434 unsigned int low_off = subreg_lowpart_offset (QImode, HImode); 4435 unsigned int high_off = subreg_highpart_offset (QImode, HImode); 4436 4437 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off); 4438 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off); 4439 }) 4440 4441(define_insn_and_split "zero_extendqipsi2" 4442 [(set (match_operand:PSI 0 "register_operand" "=r") 4443 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 4444 "" 4445 "#" 4446 "reload_completed" 4447 [(set (match_dup 2) (match_dup 1)) 4448 (set (match_dup 3) (const_int 0)) 4449 (set (match_dup 4) (const_int 0))] 4450 { 4451 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0); 4452 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1); 4453 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 4454 }) 4455 4456(define_insn_and_split "zero_extendqisi2" 4457 [(set (match_operand:SI 0 "register_operand" "=r") 4458 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))] 4459 "" 4460 "#" 4461 "reload_completed" 4462 [(set (match_dup 2) (zero_extend:HI (match_dup 1))) 4463 (set (match_dup 3) (const_int 0))] 4464 { 4465 unsigned int low_off = subreg_lowpart_offset (HImode, SImode); 4466 unsigned int high_off = subreg_highpart_offset (HImode, SImode); 4467 4468 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); 4469 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); 4470 }) 4471 4472(define_insn_and_split "zero_extendhipsi2" 4473 [(set (match_operand:PSI 0 "register_operand" "=r") 4474 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))] 4475 "" 4476 "#" 4477 "reload_completed" 4478 [(set (match_dup 2) (match_dup 1)) 4479 (set (match_dup 3) (const_int 0))] 4480 { 4481 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0); 4482 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 4483 }) 4484 4485(define_insn_and_split "n_extendhipsi2" 4486 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r") 4487 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n") 4488 (match_operand:HI 2 "register_operand" "r,r,r,r"))) 4489 (clobber (match_scratch:QI 3 "=X,X,X,&d"))] 4490 "" 4491 "#" 4492 "reload_completed" 4493 [(set (match_dup 4) (match_dup 2)) 4494 (set (match_dup 3) (match_dup 6)) 4495 ; no-op move in the case where no scratch is needed 4496 (set (match_dup 5) (match_dup 3))] 4497 { 4498 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0); 4499 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); 4500 operands[6] = operands[1]; 4501 4502 if (GET_CODE (operands[3]) == SCRATCH) 4503 operands[3] = operands[5]; 4504 }) 4505 4506(define_insn_and_split "zero_extendhisi2" 4507 [(set (match_operand:SI 0 "register_operand" "=r") 4508 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))] 4509 "" 4510 "#" 4511 "reload_completed" 4512 [(set (match_dup 2) (match_dup 1)) 4513 (set (match_dup 3) (const_int 0))] 4514 { 4515 unsigned int low_off = subreg_lowpart_offset (HImode, SImode); 4516 unsigned int high_off = subreg_highpart_offset (HImode, SImode); 4517 4518 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off); 4519 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off); 4520 }) 4521 4522(define_insn_and_split "zero_extendpsisi2" 4523 [(set (match_operand:SI 0 "register_operand" "=r") 4524 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))] 4525 "" 4526 "#" 4527 "reload_completed" 4528 [(set (match_dup 2) (match_dup 1)) 4529 (set (match_dup 3) (const_int 0))] 4530 { 4531 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0); 4532 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3); 4533 }) 4534 4535(define_insn_and_split "zero_extendqidi2" 4536 [(set (match_operand:DI 0 "register_operand" "=r") 4537 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] 4538 "" 4539 "#" 4540 "reload_completed" 4541 [(set (match_dup 2) (zero_extend:SI (match_dup 1))) 4542 (set (match_dup 3) (const_int 0))] 4543 { 4544 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 4545 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 4546 4547 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 4548 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 4549 }) 4550 4551(define_insn_and_split "zero_extendhidi2" 4552 [(set (match_operand:DI 0 "register_operand" "=r") 4553 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))] 4554 "" 4555 "#" 4556 "reload_completed" 4557 [(set (match_dup 2) (zero_extend:SI (match_dup 1))) 4558 (set (match_dup 3) (const_int 0))] 4559 { 4560 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 4561 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 4562 4563 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 4564 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 4565 }) 4566 4567(define_insn_and_split "zero_extendsidi2" 4568 [(set (match_operand:DI 0 "register_operand" "=r") 4569 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] 4570 "" 4571 "#" 4572 "reload_completed" 4573 [(set (match_dup 2) (match_dup 1)) 4574 (set (match_dup 3) (const_int 0))] 4575 { 4576 unsigned int low_off = subreg_lowpart_offset (SImode, DImode); 4577 unsigned int high_off = subreg_highpart_offset (SImode, DImode); 4578 4579 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off); 4580 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off); 4581 }) 4582 4583;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=> 4584;; compare 4585 4586; Optimize negated tests into reverse compare if overflow is undefined. 4587(define_insn "*negated_tstqi" 4588 [(set (cc0) 4589 (compare (neg:QI (match_operand:QI 0 "register_operand" "r")) 4590 (const_int 0)))] 4591 "!flag_wrapv && !flag_trapv" 4592 "cp __zero_reg__,%0" 4593 [(set_attr "cc" "compare") 4594 (set_attr "length" "1")]) 4595 4596(define_insn "*reversed_tstqi" 4597 [(set (cc0) 4598 (compare (const_int 0) 4599 (match_operand:QI 0 "register_operand" "r")))] 4600 "" 4601 "cp __zero_reg__,%0" 4602[(set_attr "cc" "compare") 4603 (set_attr "length" "2")]) 4604 4605(define_insn "*negated_tsthi" 4606 [(set (cc0) 4607 (compare (neg:HI (match_operand:HI 0 "register_operand" "r")) 4608 (const_int 0)))] 4609 "!flag_wrapv && !flag_trapv" 4610 "cp __zero_reg__,%A0 4611 cpc __zero_reg__,%B0" 4612[(set_attr "cc" "compare") 4613 (set_attr "length" "2")]) 4614 4615;; Leave here the clobber used by the cmphi pattern for simplicity, even 4616;; though it is unused, because this pattern is synthesized by avr_reorg. 4617(define_insn "*reversed_tsthi" 4618 [(set (cc0) 4619 (compare (const_int 0) 4620 (match_operand:HI 0 "register_operand" "r"))) 4621 (clobber (match_scratch:QI 1 "=X"))] 4622 "" 4623 "cp __zero_reg__,%A0 4624 cpc __zero_reg__,%B0" 4625[(set_attr "cc" "compare") 4626 (set_attr "length" "2")]) 4627 4628(define_insn "*negated_tstpsi" 4629 [(set (cc0) 4630 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r")) 4631 (const_int 0)))] 4632 "!flag_wrapv && !flag_trapv" 4633 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0" 4634 [(set_attr "cc" "compare") 4635 (set_attr "length" "3")]) 4636 4637(define_insn "*reversed_tstpsi" 4638 [(set (cc0) 4639 (compare (const_int 0) 4640 (match_operand:PSI 0 "register_operand" "r"))) 4641 (clobber (match_scratch:QI 1 "=X"))] 4642 "" 4643 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0" 4644 [(set_attr "cc" "compare") 4645 (set_attr "length" "3")]) 4646 4647(define_insn "*negated_tstsi" 4648 [(set (cc0) 4649 (compare (neg:SI (match_operand:SI 0 "register_operand" "r")) 4650 (const_int 0)))] 4651 "!flag_wrapv && !flag_trapv" 4652 "cp __zero_reg__,%A0 4653 cpc __zero_reg__,%B0 4654 cpc __zero_reg__,%C0 4655 cpc __zero_reg__,%D0" 4656 [(set_attr "cc" "compare") 4657 (set_attr "length" "4")]) 4658 4659;; "*reversed_tstsi" 4660;; "*reversed_tstsq" "*reversed_tstusq" 4661;; "*reversed_tstsa" "*reversed_tstusa" 4662(define_insn "*reversed_tst<mode>" 4663 [(set (cc0) 4664 (compare (match_operand:ALL4 0 "const0_operand" "Y00") 4665 (match_operand:ALL4 1 "register_operand" "r"))) 4666 (clobber (match_scratch:QI 2 "=X"))] 4667 "" 4668 "cp __zero_reg__,%A1 4669 cpc __zero_reg__,%B1 4670 cpc __zero_reg__,%C1 4671 cpc __zero_reg__,%D1" 4672 [(set_attr "cc" "compare") 4673 (set_attr "length" "4")]) 4674 4675 4676;; "cmpqi3" 4677;; "cmpqq3" "cmpuqq3" 4678(define_insn "cmp<mode>3" 4679 [(set (cc0) 4680 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d") 4681 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))] 4682 "" 4683 "@ 4684 tst %0 4685 cp %0,%1 4686 cpi %0,lo8(%1)" 4687 [(set_attr "cc" "compare,compare,compare") 4688 (set_attr "length" "1,1,1")]) 4689 4690(define_insn "*cmpqi_sign_extend" 4691 [(set (cc0) 4692 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d")) 4693 (match_operand:HI 1 "s8_operand" "n")))] 4694 "" 4695 "cpi %0,lo8(%1)" 4696 [(set_attr "cc" "compare") 4697 (set_attr "length" "1")]) 4698 4699 4700(define_insn "*cmphi.zero-extend.0" 4701 [(set (cc0) 4702 (compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r")) 4703 (match_operand:HI 1 "register_operand" "r")))] 4704 "" 4705 "cp %0,%A1\;cpc __zero_reg__,%B1" 4706 [(set_attr "cc" "compare") 4707 (set_attr "length" "2")]) 4708 4709(define_insn "*cmphi.zero-extend.1" 4710 [(set (cc0) 4711 (compare (match_operand:HI 0 "register_operand" "r") 4712 (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))] 4713 "" 4714 "cp %A0,%1\;cpc %B0,__zero_reg__" 4715 [(set_attr "cc" "compare") 4716 (set_attr "length" "2")]) 4717 4718;; "cmphi3" 4719;; "cmphq3" "cmpuhq3" 4720;; "cmpha3" "cmpuha3" 4721(define_insn "cmp<mode>3" 4722 [(set (cc0) 4723 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r") 4724 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn"))) 4725 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))] 4726 "" 4727 { 4728 switch (which_alternative) 4729 { 4730 case 0: 4731 case 1: 4732 return avr_out_tsthi (insn, operands, NULL); 4733 4734 case 2: 4735 return "cp %A0,%A1\;cpc %B0,%B1"; 4736 4737 case 3: 4738 if (<MODE>mode != HImode) 4739 break; 4740 return reg_unused_after (insn, operands[0]) 4741 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)" 4742 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2"; 4743 4744 case 4: 4745 if (<MODE>mode != HImode) 4746 break; 4747 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2"; 4748 } 4749 4750 return avr_out_compare (insn, operands, NULL); 4751 } 4752 [(set_attr "cc" "compare") 4753 (set_attr "length" "1,2,2,3,4,2,4") 4754 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")]) 4755 4756(define_insn "*cmppsi" 4757 [(set (cc0) 4758 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r") 4759 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n"))) 4760 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))] 4761 "" 4762 { 4763 switch (which_alternative) 4764 { 4765 case 0: 4766 return avr_out_tstpsi (insn, operands, NULL); 4767 4768 case 1: 4769 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1"; 4770 4771 case 2: 4772 return reg_unused_after (insn, operands[0]) 4773 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)" 4774 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2"; 4775 4776 case 3: 4777 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2"; 4778 } 4779 4780 return avr_out_compare (insn, operands, NULL); 4781 } 4782 [(set_attr "cc" "compare") 4783 (set_attr "length" "3,3,5,6,3,7") 4784 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")]) 4785 4786;; "*cmpsi" 4787;; "*cmpsq" "*cmpusq" 4788;; "*cmpsa" "*cmpusa" 4789(define_insn "*cmp<mode>" 4790 [(set (cc0) 4791 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r") 4792 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn"))) 4793 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))] 4794 "" 4795 { 4796 if (0 == which_alternative) 4797 return avr_out_tstsi (insn, operands, NULL); 4798 else if (1 == which_alternative) 4799 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1"; 4800 4801 return avr_out_compare (insn, operands, NULL); 4802 } 4803 [(set_attr "cc" "compare") 4804 (set_attr "length" "4,4,4,5,8") 4805 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")]) 4806 4807 4808;; ---------------------------------------------------------------------- 4809;; JUMP INSTRUCTIONS 4810;; ---------------------------------------------------------------------- 4811;; Conditional jump instructions 4812 4813;; "cbranchqi4" 4814;; "cbranchqq4" "cbranchuqq4" 4815(define_expand "cbranch<mode>4" 4816 [(set (cc0) 4817 (compare (match_operand:ALL1 1 "register_operand" "") 4818 (match_operand:ALL1 2 "nonmemory_operand" ""))) 4819 (set (pc) 4820 (if_then_else 4821 (match_operator 0 "ordered_comparison_operator" [(cc0) 4822 (const_int 0)]) 4823 (label_ref (match_operand 3 "" "")) 4824 (pc)))]) 4825 4826;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4" 4827;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4" 4828;; "cbranchpsi4" 4829(define_expand "cbranch<mode>4" 4830 [(parallel [(set (cc0) 4831 (compare (match_operand:ORDERED234 1 "register_operand" "") 4832 (match_operand:ORDERED234 2 "nonmemory_operand" ""))) 4833 (clobber (match_scratch:QI 4 ""))]) 4834 (set (pc) 4835 (if_then_else 4836 (match_operator 0 "ordered_comparison_operator" [(cc0) 4837 (const_int 0)]) 4838 (label_ref (match_operand 3 "" "")) 4839 (pc)))]) 4840 4841 4842;; Test a single bit in a QI/HI/SImode register. 4843;; Combine will create zero extract patterns for single bit tests. 4844;; permit any mode in source pattern by using VOIDmode. 4845 4846(define_insn "*sbrx_branch<mode>" 4847 [(set (pc) 4848 (if_then_else 4849 (match_operator 0 "eqne_operator" 4850 [(zero_extract:QIDI 4851 (match_operand:VOID 1 "register_operand" "r") 4852 (const_int 1) 4853 (match_operand 2 "const_int_operand" "n")) 4854 (const_int 0)]) 4855 (label_ref (match_operand 3 "" "")) 4856 (pc)))] 4857 "" 4858 { 4859 return avr_out_sbxx_branch (insn, operands); 4860 } 4861 [(set (attr "length") 4862 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 4863 (le (minus (pc) (match_dup 3)) (const_int 2046))) 4864 (const_int 2) 4865 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 4866 (const_int 2) 4867 (const_int 4)))) 4868 (set_attr "cc" "clobber")]) 4869 4870;; Same test based on bitwise AND. Keep this in case gcc changes patterns. 4871;; or for old peepholes. 4872;; Fixme - bitwise Mask will not work for DImode 4873 4874(define_insn "*sbrx_and_branch<mode>" 4875 [(set (pc) 4876 (if_then_else 4877 (match_operator 0 "eqne_operator" 4878 [(and:QISI 4879 (match_operand:QISI 1 "register_operand" "r") 4880 (match_operand:QISI 2 "single_one_operand" "n")) 4881 (const_int 0)]) 4882 (label_ref (match_operand 3 "" "")) 4883 (pc)))] 4884 "" 4885 { 4886 HOST_WIDE_INT bitnumber; 4887 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2])); 4888 operands[2] = GEN_INT (bitnumber); 4889 return avr_out_sbxx_branch (insn, operands); 4890 } 4891 [(set (attr "length") 4892 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 4893 (le (minus (pc) (match_dup 3)) (const_int 2046))) 4894 (const_int 2) 4895 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 4896 (const_int 2) 4897 (const_int 4)))) 4898 (set_attr "cc" "clobber")]) 4899 4900;; Convert sign tests to bit 7/15/31 tests that match the above insns. 4901(define_peephole2 4902 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "") 4903 (const_int 0))) 4904 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 4905 (label_ref (match_operand 1 "" "")) 4906 (pc)))] 4907 "" 4908 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0) 4909 (const_int 1) 4910 (const_int 7)) 4911 (const_int 0)) 4912 (label_ref (match_dup 1)) 4913 (pc)))]) 4914 4915(define_peephole2 4916 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "") 4917 (const_int 0))) 4918 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 4919 (label_ref (match_operand 1 "" "")) 4920 (pc)))] 4921 "" 4922 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0) 4923 (const_int 1) 4924 (const_int 7)) 4925 (const_int 0)) 4926 (label_ref (match_dup 1)) 4927 (pc)))]) 4928 4929(define_peephole2 4930 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "") 4931 (const_int 0))) 4932 (clobber (match_operand:HI 2 ""))]) 4933 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 4934 (label_ref (match_operand 1 "" "")) 4935 (pc)))] 4936 "" 4937 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768)) 4938 (const_int 0)) 4939 (label_ref (match_dup 1)) 4940 (pc)))]) 4941 4942(define_peephole2 4943 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "") 4944 (const_int 0))) 4945 (clobber (match_operand:HI 2 ""))]) 4946 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 4947 (label_ref (match_operand 1 "" "")) 4948 (pc)))] 4949 "" 4950 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768)) 4951 (const_int 0)) 4952 (label_ref (match_dup 1)) 4953 (pc)))]) 4954 4955(define_peephole2 4956 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 4957 (const_int 0))) 4958 (clobber (match_operand:SI 2 ""))]) 4959 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 4960 (label_ref (match_operand 1 "" "")) 4961 (pc)))] 4962 "" 4963 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2)) 4964 (const_int 0)) 4965 (label_ref (match_dup 1)) 4966 (pc)))] 4967 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);") 4968 4969(define_peephole2 4970 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 4971 (const_int 0))) 4972 (clobber (match_operand:SI 2 ""))]) 4973 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 4974 (label_ref (match_operand 1 "" "")) 4975 (pc)))] 4976 "" 4977 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2)) 4978 (const_int 0)) 4979 (label_ref (match_dup 1)) 4980 (pc)))] 4981 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);") 4982 4983;; ************************************************************************ 4984;; Implementation of conditional jumps here. 4985;; Compare with 0 (test) jumps 4986;; ************************************************************************ 4987 4988(define_insn "branch" 4989 [(set (pc) 4990 (if_then_else (match_operator 1 "simple_comparison_operator" 4991 [(cc0) 4992 (const_int 0)]) 4993 (label_ref (match_operand 0 "" "")) 4994 (pc)))] 4995 "" 4996 { 4997 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0); 4998 } 4999 [(set_attr "type" "branch") 5000 (set_attr "cc" "clobber")]) 5001 5002 5003;; Same as above but wrap SET_SRC so that this branch won't be transformed 5004;; or optimized in the remainder. 5005 5006(define_insn "branch_unspec" 5007 [(set (pc) 5008 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator" 5009 [(cc0) 5010 (const_int 0)]) 5011 (label_ref (match_operand 0 "" "")) 5012 (pc)) 5013 ] UNSPEC_IDENTITY))] 5014 "" 5015 { 5016 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0); 5017 } 5018 [(set_attr "type" "branch") 5019 (set_attr "cc" "none")]) 5020 5021;; **************************************************************** 5022;; AVR does not have following conditional jumps: LE,LEU,GT,GTU. 5023;; Convert them all to proper jumps. 5024;; ****************************************************************/ 5025 5026(define_insn "difficult_branch" 5027 [(set (pc) 5028 (if_then_else (match_operator 1 "difficult_comparison_operator" 5029 [(cc0) 5030 (const_int 0)]) 5031 (label_ref (match_operand 0 "" "")) 5032 (pc)))] 5033 "" 5034 { 5035 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0); 5036 } 5037 [(set_attr "type" "branch1") 5038 (set_attr "cc" "clobber")]) 5039 5040;; revers branch 5041 5042(define_insn "rvbranch" 5043 [(set (pc) 5044 (if_then_else (match_operator 1 "simple_comparison_operator" 5045 [(cc0) 5046 (const_int 0)]) 5047 (pc) 5048 (label_ref (match_operand 0 "" ""))))] 5049 "" 5050 { 5051 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1); 5052 } 5053 [(set_attr "type" "branch1") 5054 (set_attr "cc" "clobber")]) 5055 5056(define_insn "difficult_rvbranch" 5057 [(set (pc) 5058 (if_then_else (match_operator 1 "difficult_comparison_operator" 5059 [(cc0) 5060 (const_int 0)]) 5061 (pc) 5062 (label_ref (match_operand 0 "" ""))))] 5063 "" 5064 { 5065 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1); 5066 } 5067 [(set_attr "type" "branch") 5068 (set_attr "cc" "clobber")]) 5069 5070;; ************************************************************************** 5071;; Unconditional and other jump instructions. 5072 5073(define_insn "jump" 5074 [(set (pc) 5075 (label_ref (match_operand 0 "" "")))] 5076 "" 5077 { 5078 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1 5079 ? "jmp %x0" 5080 : "rjmp %x0"; 5081 } 5082 [(set (attr "length") 5083 (if_then_else (match_operand 0 "symbol_ref_operand" "") 5084 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 5085 (const_int 1) 5086 (const_int 2)) 5087 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047)) 5088 (le (minus (pc) (match_dup 0)) (const_int 2047))) 5089 (const_int 1) 5090 (const_int 2)))) 5091 (set_attr "cc" "none")]) 5092 5093;; call 5094 5095;; Operand 1 not used on the AVR. 5096;; Operand 2 is 1 for tail-call, 0 otherwise. 5097(define_expand "call" 5098 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "") 5099 (match_operand:HI 1 "general_operand" "")) 5100 (use (const_int 0))])]) 5101 5102;; Operand 1 not used on the AVR. 5103;; Operand 2 is 1 for tail-call, 0 otherwise. 5104(define_expand "sibcall" 5105 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "") 5106 (match_operand:HI 1 "general_operand" "")) 5107 (use (const_int 1))])]) 5108 5109;; call value 5110 5111;; Operand 2 not used on the AVR. 5112;; Operand 3 is 1 for tail-call, 0 otherwise. 5113(define_expand "call_value" 5114 [(parallel[(set (match_operand 0 "register_operand" "") 5115 (call (match_operand:HI 1 "call_insn_operand" "") 5116 (match_operand:HI 2 "general_operand" ""))) 5117 (use (const_int 0))])]) 5118 5119;; Operand 2 not used on the AVR. 5120;; Operand 3 is 1 for tail-call, 0 otherwise. 5121(define_expand "sibcall_value" 5122 [(parallel[(set (match_operand 0 "register_operand" "") 5123 (call (match_operand:HI 1 "call_insn_operand" "") 5124 (match_operand:HI 2 "general_operand" ""))) 5125 (use (const_int 1))])]) 5126 5127(define_insn "call_insn" 5128 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s")) 5129 (match_operand:HI 1 "general_operand" "X,X,X,X")) 5130 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])] 5131 ;; Operand 1 not used on the AVR. 5132 ;; Operand 2 is 1 for tail-call, 0 otherwise. 5133 "" 5134 "@ 5135 %!icall 5136 %~call %x0 5137 %!ijmp 5138 %~jmp %x0" 5139 [(set_attr "cc" "clobber") 5140 (set_attr "length" "1,*,1,*") 5141 (set_attr "adjust_len" "*,call,*,call")]) 5142 5143(define_insn "call_value_insn" 5144 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r") 5145 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s")) 5146 (match_operand:HI 2 "general_operand" "X,X,X,X"))) 5147 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])] 5148 ;; Operand 2 not used on the AVR. 5149 ;; Operand 3 is 1 for tail-call, 0 otherwise. 5150 "" 5151 "@ 5152 %!icall 5153 %~call %x1 5154 %!ijmp 5155 %~jmp %x1" 5156 [(set_attr "cc" "clobber") 5157 (set_attr "length" "1,*,1,*") 5158 (set_attr "adjust_len" "*,call,*,call")]) 5159 5160(define_insn "nop" 5161 [(const_int 0)] 5162 "" 5163 "nop" 5164 [(set_attr "cc" "none") 5165 (set_attr "length" "1")]) 5166 5167; indirect jump 5168 5169(define_expand "indirect_jump" 5170 [(set (pc) 5171 (match_operand:HI 0 "nonmemory_operand" ""))] 5172 "" 5173 { 5174 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode)) 5175 { 5176 operands[0] = copy_to_mode_reg (HImode, operands[0]); 5177 } 5178 }) 5179 5180; indirect jump 5181(define_insn "*indirect_jump" 5182 [(set (pc) 5183 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))] 5184 "" 5185 "@ 5186 rjmp %x0 5187 jmp %x0 5188 ijmp 5189 push %A0\;push %B0\;ret 5190 eijmp" 5191 [(set_attr "length" "1,2,1,3,1") 5192 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp") 5193 (set_attr "cc" "none")]) 5194 5195;; table jump 5196;; For entries in jump table see avr_output_addr_vec. 5197 5198;; Table made from 5199;; "rjmp .L<n>" instructions for <= 8K devices 5200;; ".word gs(.L<n>)" addresses for > 8K devices 5201(define_insn "*tablejump" 5202 [(set (pc) 5203 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")] 5204 UNSPEC_INDEX_JMP)) 5205 (use (label_ref (match_operand 1 "" ""))) 5206 (clobber (match_dup 0)) 5207 (clobber (const_int 0))] 5208 "!AVR_HAVE_EIJMP_EICALL" 5209 "@ 5210 ijmp 5211 push %A0\;push %B0\;ret 5212 jmp __tablejump2__" 5213 [(set_attr "length" "1,3,2") 5214 (set_attr "isa" "rjmp,rjmp,jmp") 5215 (set_attr "cc" "none,none,clobber")]) 5216 5217(define_insn "*tablejump.3byte-pc" 5218 [(set (pc) 5219 (unspec:HI [(reg:HI REG_Z)] 5220 UNSPEC_INDEX_JMP)) 5221 (use (label_ref (match_operand 0 "" ""))) 5222 (clobber (reg:HI REG_Z)) 5223 (clobber (reg:QI 24))] 5224 "AVR_HAVE_EIJMP_EICALL" 5225 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__" 5226 [(set_attr "length" "6") 5227 (set_attr "isa" "eijmp") 5228 (set_attr "cc" "clobber")]) 5229 5230 5231;; FIXME: casesi comes up with an SImode switch value $0 which 5232;; is quite some overhead because most code would use HI or 5233;; even QI. We add an AVR specific pass .avr-casesi which 5234;; tries to recover from the superfluous extension to SImode. 5235;; 5236;; Using "tablejump" could be a way out, but this also does 5237;; not perform in a satisfying manner as the middle end will 5238;; already multiply the table index by 2. Note that this 5239;; multiplication is performed by libgcc's __tablejump2__. 5240;; The multiplication there, however, runs *after* the table 5241;; start (a byte address) has been added, not before it like 5242;; "tablejump" will do. 5243;; 5244;; The preferred solution would be to let the middle ends pass 5245;; down information on the index as an additional casesi operand. 5246;; 5247;; If this expander is changed, you'll likely have to go through 5248;; "casesi_<mode>_sequence" (used to recog + extract casesi 5249;; sequences in pass .avr-casesi) and propagate all adjustments 5250;; also to that pattern and the code of the extra pass. 5251 5252(define_expand "casesi" 5253 [(parallel [(set (match_dup 5) 5254 (plus:SI (match_operand:SI 0 "register_operand") 5255 (match_operand:SI 1 "const_int_operand"))) 5256 (clobber (scratch:QI))]) 5257 (parallel [(set (cc0) 5258 (compare (match_dup 5) 5259 (match_operand:SI 2 "const_int_operand"))) 5260 (clobber (scratch:QI))]) 5261 5262 (set (pc) 5263 (if_then_else (gtu (cc0) 5264 (const_int 0)) 5265 (label_ref (match_operand 4)) 5266 (pc))) 5267 5268 (set (match_dup 7) 5269 (match_dup 6)) 5270 5271 (parallel [(set (pc) 5272 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP)) 5273 (use (label_ref (match_dup 3))) 5274 (clobber (match_dup 7)) 5275 (clobber (match_dup 8))])] 5276 "" 5277 { 5278 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode); 5279 operands[5] = gen_reg_rtx (SImode); 5280 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0); 5281 5282 if (AVR_HAVE_EIJMP_EICALL) 5283 { 5284 operands[7] = gen_rtx_REG (HImode, REG_Z); 5285 operands[8] = all_regs_rtx[24]; 5286 } 5287 else 5288 { 5289 operands[6] = gen_rtx_PLUS (HImode, operands[6], 5290 gen_rtx_LABEL_REF (VOIDmode, operands[3])); 5291 operands[7] = gen_reg_rtx (HImode); 5292 operands[8] = const0_rtx; 5293 } 5294 }) 5295 5296 5297;; This insn is used only for easy operand extraction. 5298;; The elements must match an extension to SImode plus 5299;; a sequence generated by casesi above. 5300 5301;; "casesi_qi_sequence" 5302;; "casesi_hi_sequence" 5303(define_insn "casesi_<mode>_sequence" 5304 [(set (match_operand:SI 0 "register_operand") 5305 (match_operator:SI 9 "extend_operator" 5306 [(match_operand:QIHI 10 "register_operand")])) 5307 5308 ;; What follows is a matcher for code from casesi. 5309 ;; We keep the same operand numbering (except for $9 and $10 5310 ;; which don't appear in casesi). 5311 (parallel [(set (match_operand:SI 5 "register_operand") 5312 (plus:SI (match_dup 0) 5313 (match_operand:SI 1 "const_int_operand"))) 5314 (clobber (scratch:QI))]) 5315 (parallel [(set (cc0) 5316 (compare (match_dup 5) 5317 (match_operand:SI 2 "const_int_operand"))) 5318 (clobber (scratch:QI))]) 5319 5320 (set (pc) 5321 (if_then_else (gtu (cc0) 5322 (const_int 0)) 5323 (label_ref (match_operand 4)) 5324 (pc))) 5325 5326 (set (match_operand:HI 7 "register_operand") 5327 (match_operand:HI 6)) 5328 5329 (parallel [(set (pc) 5330 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP)) 5331 (use (label_ref (match_operand 3))) 5332 (clobber (match_dup 7)) 5333 (clobber (match_operand:QI 8))])] 5334 "optimize 5335 && avr_casei_sequence_check_operands (operands)" 5336 { gcc_unreachable(); } 5337 ) 5338 5339 5340;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 5341;; This instruction sets Z flag 5342 5343(define_insn "sez" 5344 [(set (cc0) (const_int 0))] 5345 "" 5346 "sez" 5347 [(set_attr "length" "1") 5348 (set_attr "cc" "compare")]) 5349 5350;; Clear/set/test a single bit in I/O address space. 5351 5352(define_insn "*cbi" 5353 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i")) 5354 (and:QI (mem:QI (match_dup 0)) 5355 (match_operand:QI 1 "single_zero_operand" "n")))] 5356 "" 5357 { 5358 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); 5359 return "cbi %i0,%2"; 5360 } 5361 [(set_attr "length" "1") 5362 (set_attr "cc" "none")]) 5363 5364(define_insn "*sbi" 5365 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i")) 5366 (ior:QI (mem:QI (match_dup 0)) 5367 (match_operand:QI 1 "single_one_operand" "n")))] 5368 "" 5369 { 5370 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); 5371 return "sbi %i0,%2"; 5372 } 5373 [(set_attr "length" "1") 5374 (set_attr "cc" "none")]) 5375 5376;; Lower half of the I/O space - use sbic/sbis directly. 5377(define_insn "*sbix_branch" 5378 [(set (pc) 5379 (if_then_else 5380 (match_operator 0 "eqne_operator" 5381 [(zero_extract:QIHI 5382 (mem:QI (match_operand 1 "low_io_address_operand" "i")) 5383 (const_int 1) 5384 (match_operand 2 "const_int_operand" "n")) 5385 (const_int 0)]) 5386 (label_ref (match_operand 3 "" "")) 5387 (pc)))] 5388 "" 5389 { 5390 return avr_out_sbxx_branch (insn, operands); 5391 } 5392 [(set (attr "length") 5393 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 5394 (le (minus (pc) (match_dup 3)) (const_int 2046))) 5395 (const_int 2) 5396 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 5397 (const_int 2) 5398 (const_int 4)))) 5399 (set_attr "cc" "clobber")]) 5400 5401;; Tests of bit 7 are pessimized to sign tests, so we need this too... 5402(define_insn "*sbix_branch_bit7" 5403 [(set (pc) 5404 (if_then_else 5405 (match_operator 0 "gelt_operator" 5406 [(mem:QI (match_operand 1 "low_io_address_operand" "i")) 5407 (const_int 0)]) 5408 (label_ref (match_operand 2 "" "")) 5409 (pc)))] 5410 "" 5411 { 5412 operands[3] = operands[2]; 5413 operands[2] = GEN_INT (7); 5414 return avr_out_sbxx_branch (insn, operands); 5415 } 5416 [(set (attr "length") 5417 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046)) 5418 (le (minus (pc) (match_dup 2)) (const_int 2046))) 5419 (const_int 2) 5420 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 5421 (const_int 2) 5422 (const_int 4)))) 5423 (set_attr "cc" "clobber")]) 5424 5425;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs. 5426(define_insn "*sbix_branch_tmp" 5427 [(set (pc) 5428 (if_then_else 5429 (match_operator 0 "eqne_operator" 5430 [(zero_extract:QIHI 5431 (mem:QI (match_operand 1 "high_io_address_operand" "n")) 5432 (const_int 1) 5433 (match_operand 2 "const_int_operand" "n")) 5434 (const_int 0)]) 5435 (label_ref (match_operand 3 "" "")) 5436 (pc)))] 5437 "" 5438 { 5439 return avr_out_sbxx_branch (insn, operands); 5440 } 5441 [(set (attr "length") 5442 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046)) 5443 (le (minus (pc) (match_dup 3)) (const_int 2045))) 5444 (const_int 3) 5445 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 5446 (const_int 3) 5447 (const_int 5)))) 5448 (set_attr "cc" "clobber")]) 5449 5450(define_insn "*sbix_branch_tmp_bit7" 5451 [(set (pc) 5452 (if_then_else 5453 (match_operator 0 "gelt_operator" 5454 [(mem:QI (match_operand 1 "high_io_address_operand" "n")) 5455 (const_int 0)]) 5456 (label_ref (match_operand 2 "" "")) 5457 (pc)))] 5458 "" 5459 { 5460 operands[3] = operands[2]; 5461 operands[2] = GEN_INT (7); 5462 return avr_out_sbxx_branch (insn, operands); 5463 } 5464 [(set (attr "length") 5465 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046)) 5466 (le (minus (pc) (match_dup 2)) (const_int 2045))) 5467 (const_int 3) 5468 (if_then_else (match_test "!AVR_HAVE_JMP_CALL") 5469 (const_int 3) 5470 (const_int 5)))) 5471 (set_attr "cc" "clobber")]) 5472 5473;; ************************* Peepholes ******************************** 5474 5475(define_peephole ; "*dec-and-branchsi!=-1.d.clobber" 5476 [(parallel [(set (match_operand:SI 0 "d_register_operand" "") 5477 (plus:SI (match_dup 0) 5478 (const_int -1))) 5479 (clobber (scratch:QI))]) 5480 (parallel [(set (cc0) 5481 (compare (match_dup 0) 5482 (const_int -1))) 5483 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 5484 (set (pc) 5485 (if_then_else (eqne (cc0) 5486 (const_int 0)) 5487 (label_ref (match_operand 2 "" "")) 5488 (pc)))] 5489 "" 5490 { 5491 const char *op; 5492 int jump_mode; 5493 CC_STATUS_INIT; 5494 if (test_hard_reg_class (ADDW_REGS, operands[0])) 5495 output_asm_insn ("sbiw %0,1" CR_TAB 5496 "sbc %C0,__zero_reg__" CR_TAB 5497 "sbc %D0,__zero_reg__", operands); 5498 else 5499 output_asm_insn ("subi %A0,1" CR_TAB 5500 "sbc %B0,__zero_reg__" CR_TAB 5501 "sbc %C0,__zero_reg__" CR_TAB 5502 "sbc %D0,__zero_reg__", operands); 5503 5504 jump_mode = avr_jump_mode (operands[2], insn); 5505 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 5506 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 5507 5508 switch (jump_mode) 5509 { 5510 case 1: return "%1 %2"; 5511 case 2: return "%1 .+2\;rjmp %2"; 5512 case 3: return "%1 .+4\;jmp %2"; 5513 } 5514 5515 gcc_unreachable(); 5516 return ""; 5517 }) 5518 5519(define_peephole ; "*dec-and-branchhi!=-1" 5520 [(set (match_operand:HI 0 "d_register_operand" "") 5521 (plus:HI (match_dup 0) 5522 (const_int -1))) 5523 (parallel [(set (cc0) 5524 (compare (match_dup 0) 5525 (const_int -1))) 5526 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 5527 (set (pc) 5528 (if_then_else (eqne (cc0) 5529 (const_int 0)) 5530 (label_ref (match_operand 2 "" "")) 5531 (pc)))] 5532 "" 5533 { 5534 const char *op; 5535 int jump_mode; 5536 CC_STATUS_INIT; 5537 if (test_hard_reg_class (ADDW_REGS, operands[0])) 5538 output_asm_insn ("sbiw %0,1", operands); 5539 else 5540 output_asm_insn ("subi %A0,1" CR_TAB 5541 "sbc %B0,__zero_reg__", operands); 5542 5543 jump_mode = avr_jump_mode (operands[2], insn); 5544 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 5545 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 5546 5547 switch (jump_mode) 5548 { 5549 case 1: return "%1 %2"; 5550 case 2: return "%1 .+2\;rjmp %2"; 5551 case 3: return "%1 .+4\;jmp %2"; 5552 } 5553 5554 gcc_unreachable(); 5555 return ""; 5556 }) 5557 5558;; Same as above but with clobber flavour of addhi3 5559(define_peephole ; "*dec-and-branchhi!=-1.d.clobber" 5560 [(parallel [(set (match_operand:HI 0 "d_register_operand" "") 5561 (plus:HI (match_dup 0) 5562 (const_int -1))) 5563 (clobber (scratch:QI))]) 5564 (parallel [(set (cc0) 5565 (compare (match_dup 0) 5566 (const_int -1))) 5567 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 5568 (set (pc) 5569 (if_then_else (eqne (cc0) 5570 (const_int 0)) 5571 (label_ref (match_operand 2 "" "")) 5572 (pc)))] 5573 "" 5574 { 5575 const char *op; 5576 int jump_mode; 5577 CC_STATUS_INIT; 5578 if (test_hard_reg_class (ADDW_REGS, operands[0])) 5579 output_asm_insn ("sbiw %0,1", operands); 5580 else 5581 output_asm_insn ("subi %A0,1" CR_TAB 5582 "sbc %B0,__zero_reg__", operands); 5583 5584 jump_mode = avr_jump_mode (operands[2], insn); 5585 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 5586 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 5587 5588 switch (jump_mode) 5589 { 5590 case 1: return "%1 %2"; 5591 case 2: return "%1 .+2\;rjmp %2"; 5592 case 3: return "%1 .+4\;jmp %2"; 5593 } 5594 5595 gcc_unreachable(); 5596 return ""; 5597 }) 5598 5599;; Same as above but with clobber flavour of addhi3 5600(define_peephole ; "*dec-and-branchhi!=-1.l.clobber" 5601 [(parallel [(set (match_operand:HI 0 "l_register_operand" "") 5602 (plus:HI (match_dup 0) 5603 (const_int -1))) 5604 (clobber (match_operand:QI 3 "d_register_operand" ""))]) 5605 (parallel [(set (cc0) 5606 (compare (match_dup 0) 5607 (const_int -1))) 5608 (clobber (match_operand:QI 1 "d_register_operand" ""))]) 5609 (set (pc) 5610 (if_then_else (eqne (cc0) 5611 (const_int 0)) 5612 (label_ref (match_operand 2 "" "")) 5613 (pc)))] 5614 "" 5615 { 5616 const char *op; 5617 int jump_mode; 5618 CC_STATUS_INIT; 5619 output_asm_insn ("ldi %3,1" CR_TAB 5620 "sub %A0,%3" CR_TAB 5621 "sbc %B0,__zero_reg__", operands); 5622 5623 jump_mode = avr_jump_mode (operands[2], insn); 5624 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 5625 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); 5626 5627 switch (jump_mode) 5628 { 5629 case 1: return "%1 %2"; 5630 case 2: return "%1 .+2\;rjmp %2"; 5631 case 3: return "%1 .+4\;jmp %2"; 5632 } 5633 5634 gcc_unreachable(); 5635 return ""; 5636 }) 5637 5638(define_peephole ; "*dec-and-branchqi!=-1" 5639 [(set (match_operand:QI 0 "d_register_operand" "") 5640 (plus:QI (match_dup 0) 5641 (const_int -1))) 5642 (set (cc0) 5643 (compare (match_dup 0) 5644 (const_int -1))) 5645 (set (pc) 5646 (if_then_else (eqne (cc0) 5647 (const_int 0)) 5648 (label_ref (match_operand 1 "" "")) 5649 (pc)))] 5650 "" 5651 { 5652 const char *op; 5653 int jump_mode; 5654 CC_STATUS_INIT; 5655 cc_status.value1 = operands[0]; 5656 cc_status.flags |= CC_OVERFLOW_UNUSABLE; 5657 5658 output_asm_insn ("subi %A0,1", operands); 5659 5660 jump_mode = avr_jump_mode (operands[1], insn); 5661 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; 5662 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op); 5663 5664 switch (jump_mode) 5665 { 5666 case 1: return "%0 %1"; 5667 case 2: return "%0 .+2\;rjmp %1"; 5668 case 3: return "%0 .+4\;jmp %1"; 5669 } 5670 5671 gcc_unreachable(); 5672 return ""; 5673 }) 5674 5675 5676(define_peephole ; "*cpse.eq" 5677 [(set (cc0) 5678 (compare (match_operand:ALL1 1 "register_operand" "r,r") 5679 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00"))) 5680 (set (pc) 5681 (if_then_else (eq (cc0) 5682 (const_int 0)) 5683 (label_ref (match_operand 0 "" "")) 5684 (pc)))] 5685 "jump_over_one_insn_p (insn, operands[0])" 5686 "@ 5687 cpse %1,%2 5688 cpse %1,__zero_reg__") 5689 5690;; This peephole avoids code like 5691;; 5692;; TST Rn ; cmpqi3 5693;; BREQ .+2 ; branch 5694;; RJMP .Lm 5695;; 5696;; Notice that the peephole is always shorter than cmpqi + branch. 5697;; The reason to write it as peephole is that sequences like 5698;; 5699;; AND Rm, Rn 5700;; BRNE .La 5701;; 5702;; shall not be superseeded. With a respective combine pattern 5703;; the latter sequence would be 5704;; 5705;; AND Rm, Rn 5706;; CPSE Rm, __zero_reg__ 5707;; RJMP .La 5708;; 5709;; and thus longer and slower and not easy to be rolled back. 5710 5711(define_peephole ; "*cpse.ne" 5712 [(set (cc0) 5713 (compare (match_operand:ALL1 1 "register_operand" "") 5714 (match_operand:ALL1 2 "reg_or_0_operand" ""))) 5715 (set (pc) 5716 (if_then_else (ne (cc0) 5717 (const_int 0)) 5718 (label_ref (match_operand 0 "" "")) 5719 (pc)))] 5720 "!AVR_HAVE_JMP_CALL 5721 || !TARGET_SKIP_BUG" 5722 { 5723 if (operands[2] == CONST0_RTX (<MODE>mode)) 5724 operands[2] = zero_reg_rtx; 5725 5726 return 3 == avr_jump_mode (operands[0], insn) 5727 ? "cpse %1,%2\;jmp %0" 5728 : "cpse %1,%2\;rjmp %0"; 5729 }) 5730 5731;;pppppppppppppppppppppppppppppppppppppppppppppppppppp 5732;;prologue/epilogue support instructions 5733 5734(define_insn "popqi" 5735 [(set (match_operand:QI 0 "register_operand" "=r") 5736 (mem:QI (pre_inc:HI (reg:HI REG_SP))))] 5737 "" 5738 "pop %0" 5739 [(set_attr "cc" "none") 5740 (set_attr "length" "1")]) 5741 5742;; Enable Interrupts 5743(define_expand "enable_interrupt" 5744 [(clobber (const_int 0))] 5745 "" 5746 { 5747 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 5748 MEM_VOLATILE_P (mem) = 1; 5749 emit_insn (gen_cli_sei (const1_rtx, mem)); 5750 DONE; 5751 }) 5752 5753;; Disable Interrupts 5754(define_expand "disable_interrupt" 5755 [(clobber (const_int 0))] 5756 "" 5757 { 5758 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 5759 MEM_VOLATILE_P (mem) = 1; 5760 emit_insn (gen_cli_sei (const0_rtx, mem)); 5761 DONE; 5762 }) 5763 5764(define_insn "cli_sei" 5765 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")] 5766 UNSPECV_ENABLE_IRQS) 5767 (set (match_operand:BLK 1 "" "") 5768 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))] 5769 "" 5770 "@ 5771 cli 5772 sei" 5773 [(set_attr "length" "1") 5774 (set_attr "cc" "none")]) 5775 5776;; Library prologue saves 5777(define_insn "call_prologue_saves" 5778 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES) 5779 (match_operand:HI 0 "immediate_operand" "i,i") 5780 (set (reg:HI REG_SP) 5781 (minus:HI (reg:HI REG_SP) 5782 (match_operand:HI 1 "immediate_operand" "i,i"))) 5783 (use (reg:HI REG_X)) 5784 (clobber (reg:HI REG_Z))] 5785 "" 5786 "ldi r30,lo8(gs(1f)) 5787 ldi r31,hi8(gs(1f)) 5788 %~jmp __prologue_saves__+((18 - %0) * 2) 57891:" 5790 [(set_attr "length" "5,6") 5791 (set_attr "cc" "clobber") 5792 (set_attr "isa" "rjmp,jmp")]) 5793 5794; epilogue restores using library 5795(define_insn "epilogue_restores" 5796 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES) 5797 (set (reg:HI REG_Y) 5798 (plus:HI (reg:HI REG_Y) 5799 (match_operand:HI 0 "immediate_operand" "i,i"))) 5800 (set (reg:HI REG_SP) 5801 (plus:HI (reg:HI REG_Y) 5802 (match_dup 0))) 5803 (clobber (reg:QI REG_Z))] 5804 "" 5805 "ldi r30, lo8(%0) 5806 %~jmp __epilogue_restores__ + ((18 - %0) * 2)" 5807 [(set_attr "length" "2,3") 5808 (set_attr "cc" "clobber") 5809 (set_attr "isa" "rjmp,jmp")]) 5810 5811 5812;; $0 = Chunk: 1 = Prologue, 2 = Epilogue 5813;; $1 = Register as printed by chunk 0 (Done) in final postscan. 5814(define_expand "gasisr" 5815 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand") 5816 (match_operand:QI 1 "const_int_operand")] 5817 UNSPECV_GASISR) 5818 (set (reg:HI REG_SP) 5819 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR)) 5820 (set (match_dup 2) 5821 (unspec_volatile:BLK [(match_dup 2)] 5822 UNSPECV_MEMORY_BARRIER))])] 5823 "avr_gasisr_prologues" 5824 { 5825 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 5826 MEM_VOLATILE_P (operands[2]) = 1; 5827 }) 5828 5829(define_insn "*gasisr" 5830 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K") 5831 (match_operand:QI 1 "const_int_operand" "n,n")] 5832 UNSPECV_GASISR) 5833 (set (reg:HI REG_SP) 5834 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR)) 5835 (set (match_operand:BLK 2) 5836 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))] 5837 "avr_gasisr_prologues" 5838 "__gcc_isr %0" 5839 [(set_attr "length" "6,5") 5840 (set_attr "cc" "clobber")]) 5841 5842 5843; return 5844(define_insn "return" 5845 [(return)] 5846 "reload_completed && avr_simple_epilogue ()" 5847 "ret" 5848 [(set_attr "cc" "none") 5849 (set_attr "length" "1")]) 5850 5851(define_insn "return_from_epilogue" 5852 [(return)] 5853 "reload_completed 5854 && cfun->machine 5855 && !(cfun->machine->is_interrupt || cfun->machine->is_signal) 5856 && !cfun->machine->is_naked" 5857 "ret" 5858 [(set_attr "cc" "none") 5859 (set_attr "length" "1")]) 5860 5861(define_insn "return_from_interrupt_epilogue" 5862 [(return)] 5863 "reload_completed 5864 && cfun->machine 5865 && (cfun->machine->is_interrupt || cfun->machine->is_signal) 5866 && !cfun->machine->is_naked" 5867 "reti" 5868 [(set_attr "cc" "none") 5869 (set_attr "length" "1")]) 5870 5871(define_insn "return_from_naked_epilogue" 5872 [(return)] 5873 "reload_completed 5874 && cfun->machine 5875 && cfun->machine->is_naked" 5876 "" 5877 [(set_attr "cc" "none") 5878 (set_attr "length" "0")]) 5879 5880(define_expand "prologue" 5881 [(const_int 0)] 5882 "" 5883 { 5884 avr_expand_prologue (); 5885 DONE; 5886 }) 5887 5888(define_expand "epilogue" 5889 [(const_int 0)] 5890 "" 5891 { 5892 avr_expand_epilogue (false /* sibcall_p */); 5893 DONE; 5894 }) 5895 5896(define_expand "sibcall_epilogue" 5897 [(const_int 0)] 5898 "" 5899 { 5900 avr_expand_epilogue (true /* sibcall_p */); 5901 DONE; 5902 }) 5903 5904;; Some instructions resp. instruction sequences available 5905;; via builtins. 5906 5907(define_insn "delay_cycles_1" 5908 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n") 5909 (const_int 1)] 5910 UNSPECV_DELAY_CYCLES) 5911 (set (match_operand:BLK 1 "" "") 5912 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 5913 (clobber (match_scratch:QI 2 "=&d"))] 5914 "" 5915 "ldi %2,lo8(%0) 59161: dec %2 5917 brne 1b" 5918 [(set_attr "length" "3") 5919 (set_attr "cc" "clobber")]) 5920 5921(define_insn "delay_cycles_2" 5922 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n") 5923 (const_int 2)] 5924 UNSPECV_DELAY_CYCLES) 5925 (set (match_operand:BLK 1 "" "") 5926 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 5927 (clobber (match_scratch:HI 2 "=&w,&d"))] 5928 "" 5929 "@ 5930 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b 5931 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b" 5932 [(set_attr "length" "4,5") 5933 (set_attr "isa" "no_tiny,tiny") 5934 (set_attr "cc" "clobber")]) 5935 5936(define_insn "delay_cycles_3" 5937 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 5938 (const_int 3)] 5939 UNSPECV_DELAY_CYCLES) 5940 (set (match_operand:BLK 1 "" "") 5941 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 5942 (clobber (match_scratch:QI 2 "=&d")) 5943 (clobber (match_scratch:QI 3 "=&d")) 5944 (clobber (match_scratch:QI 4 "=&d"))] 5945 "" 5946 "ldi %2,lo8(%0) 5947 ldi %3,hi8(%0) 5948 ldi %4,hlo8(%0) 59491: subi %2,1 5950 sbci %3,0 5951 sbci %4,0 5952 brne 1b" 5953 [(set_attr "length" "7") 5954 (set_attr "cc" "clobber")]) 5955 5956(define_insn "delay_cycles_4" 5957 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 5958 (const_int 4)] 5959 UNSPECV_DELAY_CYCLES) 5960 (set (match_operand:BLK 1 "" "") 5961 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER)) 5962 (clobber (match_scratch:QI 2 "=&d")) 5963 (clobber (match_scratch:QI 3 "=&d")) 5964 (clobber (match_scratch:QI 4 "=&d")) 5965 (clobber (match_scratch:QI 5 "=&d"))] 5966 "" 5967 "ldi %2,lo8(%0) 5968 ldi %3,hi8(%0) 5969 ldi %4,hlo8(%0) 5970 ldi %5,hhi8(%0) 59711: subi %2,1 5972 sbci %3,0 5973 sbci %4,0 5974 sbci %5,0 5975 brne 1b" 5976 [(set_attr "length" "9") 5977 (set_attr "cc" "clobber")]) 5978 5979 5980;; __builtin_avr_insert_bits 5981 5982(define_insn "insert_bits" 5983 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r") 5984 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f") 5985 (match_operand:QI 2 "register_operand" "r ,r ,r") 5986 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")] 5987 UNSPEC_INSERT_BITS))] 5988 "" 5989 { 5990 return avr_out_insert_bits (operands, NULL); 5991 } 5992 [(set_attr "adjust_len" "insert_bits") 5993 (set_attr "cc" "clobber")]) 5994 5995 5996;; __builtin_avr_flash_segment 5997 5998;; Just a helper for the next "official" expander. 5999 6000(define_expand "flash_segment1" 6001 [(set (match_operand:QI 0 "register_operand" "") 6002 (subreg:QI (match_operand:PSI 1 "register_operand" "") 6003 2)) 6004 (set (cc0) 6005 (compare (match_dup 0) 6006 (const_int 0))) 6007 (set (pc) 6008 (if_then_else (ge (cc0) 6009 (const_int 0)) 6010 (label_ref (match_operand 2 "" "")) 6011 (pc))) 6012 (set (match_dup 0) 6013 (const_int -1))]) 6014 6015(define_expand "flash_segment" 6016 [(parallel [(match_operand:QI 0 "register_operand" "") 6017 (match_operand:PSI 1 "register_operand" "")])] 6018 "" 6019 { 6020 rtx label = gen_label_rtx (); 6021 emit (gen_flash_segment1 (operands[0], operands[1], label)); 6022 emit_label (label); 6023 DONE; 6024 }) 6025 6026;; Actually, it's too late now to work out address spaces known at compiletime. 6027;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin. 6028;; However, avr_addr_space_convert can add some built-in knowledge for PSTR 6029;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved. 6030 6031(define_insn_and_split "*split.flash_segment" 6032 [(set (match_operand:QI 0 "register_operand" "=d") 6033 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri") 6034 (match_operand:HI 2 "register_operand" "r")) 6035 2))] 6036 "" 6037 { gcc_unreachable(); } 6038 "" 6039 [(set (match_dup 0) 6040 (match_dup 1))]) 6041 6042 6043;; Parity 6044 6045;; Postpone expansion of 16-bit parity to libgcc call until after combine for 6046;; better 8-bit parity recognition. 6047 6048(define_expand "parityhi2" 6049 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6050 (parity:HI (match_operand:HI 1 "register_operand" ""))) 6051 (clobber (reg:HI 24))])]) 6052 6053(define_insn_and_split "*parityhi2" 6054 [(set (match_operand:HI 0 "register_operand" "=r") 6055 (parity:HI (match_operand:HI 1 "register_operand" "r"))) 6056 (clobber (reg:HI 24))] 6057 "!reload_completed" 6058 { gcc_unreachable(); } 6059 "&& 1" 6060 [(set (reg:HI 24) 6061 (match_dup 1)) 6062 (set (reg:HI 24) 6063 (parity:HI (reg:HI 24))) 6064 (set (match_dup 0) 6065 (reg:HI 24))]) 6066 6067(define_insn_and_split "*parityqihi2" 6068 [(set (match_operand:HI 0 "register_operand" "=r") 6069 (parity:HI (match_operand:QI 1 "register_operand" "r"))) 6070 (clobber (reg:HI 24))] 6071 "!reload_completed" 6072 { gcc_unreachable(); } 6073 "&& 1" 6074 [(set (reg:QI 24) 6075 (match_dup 1)) 6076 (set (reg:HI 24) 6077 (zero_extend:HI (parity:QI (reg:QI 24)))) 6078 (set (match_dup 0) 6079 (reg:HI 24))]) 6080 6081(define_expand "paritysi2" 6082 [(set (reg:SI 22) 6083 (match_operand:SI 1 "register_operand" "")) 6084 (set (reg:HI 24) 6085 (truncate:HI (parity:SI (reg:SI 22)))) 6086 (set (match_dup 2) 6087 (reg:HI 24)) 6088 (set (match_operand:SI 0 "register_operand" "") 6089 (zero_extend:SI (match_dup 2)))] 6090 "" 6091 { 6092 operands[2] = gen_reg_rtx (HImode); 6093 }) 6094 6095(define_insn "*parityhi2.libgcc" 6096 [(set (reg:HI 24) 6097 (parity:HI (reg:HI 24)))] 6098 "" 6099 "%~call __parityhi2" 6100 [(set_attr "type" "xcall") 6101 (set_attr "cc" "clobber")]) 6102 6103(define_insn "*parityqihi2.libgcc" 6104 [(set (reg:HI 24) 6105 (zero_extend:HI (parity:QI (reg:QI 24))))] 6106 "" 6107 "%~call __parityqi2" 6108 [(set_attr "type" "xcall") 6109 (set_attr "cc" "clobber")]) 6110 6111(define_insn "*paritysihi2.libgcc" 6112 [(set (reg:HI 24) 6113 (truncate:HI (parity:SI (reg:SI 22))))] 6114 "" 6115 "%~call __paritysi2" 6116 [(set_attr "type" "xcall") 6117 (set_attr "cc" "clobber")]) 6118 6119 6120;; Popcount 6121 6122(define_expand "popcounthi2" 6123 [(set (reg:HI 24) 6124 (match_operand:HI 1 "register_operand" "")) 6125 (set (reg:HI 24) 6126 (popcount:HI (reg:HI 24))) 6127 (set (match_operand:HI 0 "register_operand" "") 6128 (reg:HI 24))] 6129 "" 6130 "") 6131 6132(define_expand "popcountsi2" 6133 [(set (reg:SI 22) 6134 (match_operand:SI 1 "register_operand" "")) 6135 (set (reg:HI 24) 6136 (truncate:HI (popcount:SI (reg:SI 22)))) 6137 (set (match_dup 2) 6138 (reg:HI 24)) 6139 (set (match_operand:SI 0 "register_operand" "") 6140 (zero_extend:SI (match_dup 2)))] 6141 "" 6142 { 6143 operands[2] = gen_reg_rtx (HImode); 6144 }) 6145 6146(define_insn "*popcounthi2.libgcc" 6147 [(set (reg:HI 24) 6148 (popcount:HI (reg:HI 24)))] 6149 "" 6150 "%~call __popcounthi2" 6151 [(set_attr "type" "xcall") 6152 (set_attr "cc" "clobber")]) 6153 6154(define_insn "*popcountsi2.libgcc" 6155 [(set (reg:HI 24) 6156 (truncate:HI (popcount:SI (reg:SI 22))))] 6157 "" 6158 "%~call __popcountsi2" 6159 [(set_attr "type" "xcall") 6160 (set_attr "cc" "clobber")]) 6161 6162(define_insn "*popcountqi2.libgcc" 6163 [(set (reg:QI 24) 6164 (popcount:QI (reg:QI 24)))] 6165 "" 6166 "%~call __popcountqi2" 6167 [(set_attr "type" "xcall") 6168 (set_attr "cc" "clobber")]) 6169 6170(define_insn_and_split "*popcountqihi2.libgcc" 6171 [(set (reg:HI 24) 6172 (zero_extend:HI (popcount:QI (reg:QI 24))))] 6173 "" 6174 "#" 6175 "" 6176 [(set (reg:QI 24) 6177 (popcount:QI (reg:QI 24))) 6178 (set (reg:QI 25) 6179 (const_int 0))]) 6180 6181;; Count Leading Zeros 6182 6183(define_expand "clzhi2" 6184 [(set (reg:HI 24) 6185 (match_operand:HI 1 "register_operand" "")) 6186 (parallel [(set (reg:HI 24) 6187 (clz:HI (reg:HI 24))) 6188 (clobber (reg:QI 26))]) 6189 (set (match_operand:HI 0 "register_operand" "") 6190 (reg:HI 24))]) 6191 6192(define_expand "clzsi2" 6193 [(set (reg:SI 22) 6194 (match_operand:SI 1 "register_operand" "")) 6195 (parallel [(set (reg:HI 24) 6196 (truncate:HI (clz:SI (reg:SI 22)))) 6197 (clobber (reg:QI 26))]) 6198 (set (match_dup 2) 6199 (reg:HI 24)) 6200 (set (match_operand:SI 0 "register_operand" "") 6201 (zero_extend:SI (match_dup 2)))] 6202 "" 6203 { 6204 operands[2] = gen_reg_rtx (HImode); 6205 }) 6206 6207(define_insn "*clzhi2.libgcc" 6208 [(set (reg:HI 24) 6209 (clz:HI (reg:HI 24))) 6210 (clobber (reg:QI 26))] 6211 "" 6212 "%~call __clzhi2" 6213 [(set_attr "type" "xcall") 6214 (set_attr "cc" "clobber")]) 6215 6216(define_insn "*clzsihi2.libgcc" 6217 [(set (reg:HI 24) 6218 (truncate:HI (clz:SI (reg:SI 22)))) 6219 (clobber (reg:QI 26))] 6220 "" 6221 "%~call __clzsi2" 6222 [(set_attr "type" "xcall") 6223 (set_attr "cc" "clobber")]) 6224 6225;; Count Trailing Zeros 6226 6227(define_expand "ctzhi2" 6228 [(set (reg:HI 24) 6229 (match_operand:HI 1 "register_operand" "")) 6230 (parallel [(set (reg:HI 24) 6231 (ctz:HI (reg:HI 24))) 6232 (clobber (reg:QI 26))]) 6233 (set (match_operand:HI 0 "register_operand" "") 6234 (reg:HI 24))]) 6235 6236(define_expand "ctzsi2" 6237 [(set (reg:SI 22) 6238 (match_operand:SI 1 "register_operand" "")) 6239 (parallel [(set (reg:HI 24) 6240 (truncate:HI (ctz:SI (reg:SI 22)))) 6241 (clobber (reg:QI 22)) 6242 (clobber (reg:QI 26))]) 6243 (set (match_dup 2) 6244 (reg:HI 24)) 6245 (set (match_operand:SI 0 "register_operand" "") 6246 (zero_extend:SI (match_dup 2)))] 6247 "" 6248 { 6249 operands[2] = gen_reg_rtx (HImode); 6250 }) 6251 6252(define_insn "*ctzhi2.libgcc" 6253 [(set (reg:HI 24) 6254 (ctz:HI (reg:HI 24))) 6255 (clobber (reg:QI 26))] 6256 "" 6257 "%~call __ctzhi2" 6258 [(set_attr "type" "xcall") 6259 (set_attr "cc" "clobber")]) 6260 6261(define_insn "*ctzsihi2.libgcc" 6262 [(set (reg:HI 24) 6263 (truncate:HI (ctz:SI (reg:SI 22)))) 6264 (clobber (reg:QI 22)) 6265 (clobber (reg:QI 26))] 6266 "" 6267 "%~call __ctzsi2" 6268 [(set_attr "type" "xcall") 6269 (set_attr "cc" "clobber")]) 6270 6271;; Find First Set 6272 6273(define_expand "ffshi2" 6274 [(set (reg:HI 24) 6275 (match_operand:HI 1 "register_operand" "")) 6276 (parallel [(set (reg:HI 24) 6277 (ffs:HI (reg:HI 24))) 6278 (clobber (reg:QI 26))]) 6279 (set (match_operand:HI 0 "register_operand" "") 6280 (reg:HI 24))]) 6281 6282(define_expand "ffssi2" 6283 [(set (reg:SI 22) 6284 (match_operand:SI 1 "register_operand" "")) 6285 (parallel [(set (reg:HI 24) 6286 (truncate:HI (ffs:SI (reg:SI 22)))) 6287 (clobber (reg:QI 22)) 6288 (clobber (reg:QI 26))]) 6289 (set (match_dup 2) 6290 (reg:HI 24)) 6291 (set (match_operand:SI 0 "register_operand" "") 6292 (zero_extend:SI (match_dup 2)))] 6293 "" 6294 { 6295 operands[2] = gen_reg_rtx (HImode); 6296 }) 6297 6298(define_insn "*ffshi2.libgcc" 6299 [(set (reg:HI 24) 6300 (ffs:HI (reg:HI 24))) 6301 (clobber (reg:QI 26))] 6302 "" 6303 "%~call __ffshi2" 6304 [(set_attr "type" "xcall") 6305 (set_attr "cc" "clobber")]) 6306 6307(define_insn "*ffssihi2.libgcc" 6308 [(set (reg:HI 24) 6309 (truncate:HI (ffs:SI (reg:SI 22)))) 6310 (clobber (reg:QI 22)) 6311 (clobber (reg:QI 26))] 6312 "" 6313 "%~call __ffssi2" 6314 [(set_attr "type" "xcall") 6315 (set_attr "cc" "clobber")]) 6316 6317;; Copysign 6318 6319(define_insn "copysignsf3" 6320 [(set (match_operand:SF 0 "register_operand" "=r") 6321 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 6322 (match_operand:SF 2 "register_operand" "r")] 6323 UNSPEC_COPYSIGN))] 6324 "" 6325 "bst %D2,7\;bld %D0,7" 6326 [(set_attr "length" "2") 6327 (set_attr "cc" "none")]) 6328 6329;; Swap Bytes (change byte-endianness) 6330 6331(define_expand "bswapsi2" 6332 [(set (reg:SI 22) 6333 (match_operand:SI 1 "register_operand" "")) 6334 (set (reg:SI 22) 6335 (bswap:SI (reg:SI 22))) 6336 (set (match_operand:SI 0 "register_operand" "") 6337 (reg:SI 22))]) 6338 6339(define_insn "*bswapsi2.libgcc" 6340 [(set (reg:SI 22) 6341 (bswap:SI (reg:SI 22)))] 6342 "" 6343 "%~call __bswapsi2" 6344 [(set_attr "type" "xcall") 6345 (set_attr "cc" "clobber")]) 6346 6347 6348;; CPU instructions 6349 6350;; NOP taking 1 or 2 Ticks 6351(define_expand "nopv" 6352 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")] 6353 UNSPECV_NOP) 6354 (set (match_dup 1) 6355 (unspec_volatile:BLK [(match_dup 1)] 6356 UNSPECV_MEMORY_BARRIER))])] 6357 "" 6358 { 6359 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 6360 MEM_VOLATILE_P (operands[1]) = 1; 6361 }) 6362 6363(define_insn "*nopv" 6364 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")] 6365 UNSPECV_NOP) 6366 (set (match_operand:BLK 1 "" "") 6367 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))] 6368 "" 6369 "@ 6370 nop 6371 rjmp ." 6372 [(set_attr "length" "1") 6373 (set_attr "cc" "none")]) 6374 6375;; SLEEP 6376(define_expand "sleep" 6377 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP) 6378 (set (match_dup 0) 6379 (unspec_volatile:BLK [(match_dup 0)] 6380 UNSPECV_MEMORY_BARRIER))])] 6381 "" 6382 { 6383 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 6384 MEM_VOLATILE_P (operands[0]) = 1; 6385 }) 6386 6387(define_insn "*sleep" 6388 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP) 6389 (set (match_operand:BLK 0 "" "") 6390 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))] 6391 "" 6392 "sleep" 6393 [(set_attr "length" "1") 6394 (set_attr "cc" "none")]) 6395 6396;; WDR 6397(define_expand "wdr" 6398 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR) 6399 (set (match_dup 0) 6400 (unspec_volatile:BLK [(match_dup 0)] 6401 UNSPECV_MEMORY_BARRIER))])] 6402 "" 6403 { 6404 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 6405 MEM_VOLATILE_P (operands[0]) = 1; 6406 }) 6407 6408(define_insn "*wdr" 6409 [(unspec_volatile [(const_int 0)] UNSPECV_WDR) 6410 (set (match_operand:BLK 0 "" "") 6411 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))] 6412 "" 6413 "wdr" 6414 [(set_attr "length" "1") 6415 (set_attr "cc" "none")]) 6416 6417;; FMUL 6418(define_expand "fmul" 6419 [(set (reg:QI 24) 6420 (match_operand:QI 1 "register_operand" "")) 6421 (set (reg:QI 25) 6422 (match_operand:QI 2 "register_operand" "")) 6423 (parallel [(set (reg:HI 22) 6424 (unspec:HI [(reg:QI 24) 6425 (reg:QI 25)] UNSPEC_FMUL)) 6426 (clobber (reg:HI 24))]) 6427 (set (match_operand:HI 0 "register_operand" "") 6428 (reg:HI 22))] 6429 "" 6430 { 6431 if (AVR_HAVE_MUL) 6432 { 6433 emit_insn (gen_fmul_insn (operand0, operand1, operand2)); 6434 DONE; 6435 } 6436 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 6437 }) 6438 6439(define_insn "fmul_insn" 6440 [(set (match_operand:HI 0 "register_operand" "=r") 6441 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 6442 (match_operand:QI 2 "register_operand" "a")] 6443 UNSPEC_FMUL))] 6444 "AVR_HAVE_MUL" 6445 "fmul %1,%2 6446 movw %0,r0 6447 clr __zero_reg__" 6448 [(set_attr "length" "3") 6449 (set_attr "cc" "clobber")]) 6450 6451(define_insn "*fmul.call" 6452 [(set (reg:HI 22) 6453 (unspec:HI [(reg:QI 24) 6454 (reg:QI 25)] UNSPEC_FMUL)) 6455 (clobber (reg:HI 24))] 6456 "!AVR_HAVE_MUL" 6457 "%~call __fmul" 6458 [(set_attr "type" "xcall") 6459 (set_attr "cc" "clobber")]) 6460 6461;; FMULS 6462(define_expand "fmuls" 6463 [(set (reg:QI 24) 6464 (match_operand:QI 1 "register_operand" "")) 6465 (set (reg:QI 25) 6466 (match_operand:QI 2 "register_operand" "")) 6467 (parallel [(set (reg:HI 22) 6468 (unspec:HI [(reg:QI 24) 6469 (reg:QI 25)] UNSPEC_FMULS)) 6470 (clobber (reg:HI 24))]) 6471 (set (match_operand:HI 0 "register_operand" "") 6472 (reg:HI 22))] 6473 "" 6474 { 6475 if (AVR_HAVE_MUL) 6476 { 6477 emit_insn (gen_fmuls_insn (operand0, operand1, operand2)); 6478 DONE; 6479 } 6480 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 6481 }) 6482 6483(define_insn "fmuls_insn" 6484 [(set (match_operand:HI 0 "register_operand" "=r") 6485 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 6486 (match_operand:QI 2 "register_operand" "a")] 6487 UNSPEC_FMULS))] 6488 "AVR_HAVE_MUL" 6489 "fmuls %1,%2 6490 movw %0,r0 6491 clr __zero_reg__" 6492 [(set_attr "length" "3") 6493 (set_attr "cc" "clobber")]) 6494 6495(define_insn "*fmuls.call" 6496 [(set (reg:HI 22) 6497 (unspec:HI [(reg:QI 24) 6498 (reg:QI 25)] UNSPEC_FMULS)) 6499 (clobber (reg:HI 24))] 6500 "!AVR_HAVE_MUL" 6501 "%~call __fmuls" 6502 [(set_attr "type" "xcall") 6503 (set_attr "cc" "clobber")]) 6504 6505;; FMULSU 6506(define_expand "fmulsu" 6507 [(set (reg:QI 24) 6508 (match_operand:QI 1 "register_operand" "")) 6509 (set (reg:QI 25) 6510 (match_operand:QI 2 "register_operand" "")) 6511 (parallel [(set (reg:HI 22) 6512 (unspec:HI [(reg:QI 24) 6513 (reg:QI 25)] UNSPEC_FMULSU)) 6514 (clobber (reg:HI 24))]) 6515 (set (match_operand:HI 0 "register_operand" "") 6516 (reg:HI 22))] 6517 "" 6518 { 6519 if (AVR_HAVE_MUL) 6520 { 6521 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2)); 6522 DONE; 6523 } 6524 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24)); 6525 }) 6526 6527(define_insn "fmulsu_insn" 6528 [(set (match_operand:HI 0 "register_operand" "=r") 6529 (unspec:HI [(match_operand:QI 1 "register_operand" "a") 6530 (match_operand:QI 2 "register_operand" "a")] 6531 UNSPEC_FMULSU))] 6532 "AVR_HAVE_MUL" 6533 "fmulsu %1,%2 6534 movw %0,r0 6535 clr __zero_reg__" 6536 [(set_attr "length" "3") 6537 (set_attr "cc" "clobber")]) 6538 6539(define_insn "*fmulsu.call" 6540 [(set (reg:HI 22) 6541 (unspec:HI [(reg:QI 24) 6542 (reg:QI 25)] UNSPEC_FMULSU)) 6543 (clobber (reg:HI 24))] 6544 "!AVR_HAVE_MUL" 6545 "%~call __fmulsu" 6546 [(set_attr "type" "xcall") 6547 (set_attr "cc" "clobber")]) 6548 6549 6550;; Some combiner patterns dealing with bits. 6551;; See PR42210 6552 6553;; Move bit $3.0 into bit $0.$4 6554(define_insn "*movbitqi.1-6.a" 6555 [(set (match_operand:QI 0 "register_operand" "=r") 6556 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 6557 (match_operand:QI 2 "single_zero_operand" "n")) 6558 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r") 6559 (match_operand:QI 4 "const_0_to_7_operand" "n")) 6560 (match_operand:QI 5 "single_one_operand" "n"))))] 6561 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode)) 6562 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))" 6563 "bst %3,0\;bld %0,%4" 6564 [(set_attr "length" "2") 6565 (set_attr "cc" "none")]) 6566 6567;; Move bit $3.0 into bit $0.$4 6568;; Variation of above. Unfortunately, there is no canonicalized representation 6569;; of moving around bits. So what we see here depends on how user writes down 6570;; bit manipulations. 6571(define_insn "*movbitqi.1-6.b" 6572 [(set (match_operand:QI 0 "register_operand" "=r") 6573 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 6574 (match_operand:QI 2 "single_zero_operand" "n")) 6575 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r") 6576 (const_int 1)) 6577 (match_operand:QI 4 "const_0_to_7_operand" "n"))))] 6578 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" 6579 "bst %3,0\;bld %0,%4" 6580 [(set_attr "length" "2") 6581 (set_attr "cc" "none")]) 6582 6583;; Move bit $3.0 into bit $0.0. 6584;; For bit 0, combiner generates slightly different pattern. 6585(define_insn "*movbitqi.0" 6586 [(set (match_operand:QI 0 "register_operand" "=r") 6587 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 6588 (match_operand:QI 2 "single_zero_operand" "n")) 6589 (and:QI (match_operand:QI 3 "register_operand" "r") 6590 (const_int 1))))] 6591 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" 6592 "bst %3,0\;bld %0,0" 6593 [(set_attr "length" "2") 6594 (set_attr "cc" "none")]) 6595 6596;; Move bit $2.0 into bit $0.7. 6597;; For bit 7, combiner generates slightly different pattern 6598(define_insn "*movbitqi.7" 6599 [(set (match_operand:QI 0 "register_operand" "=r") 6600 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") 6601 (const_int 127)) 6602 (ashift:QI (match_operand:QI 2 "register_operand" "r") 6603 (const_int 7))))] 6604 "" 6605 "bst %2,0\;bld %0,7" 6606 [(set_attr "length" "2") 6607 (set_attr "cc" "none")]) 6608 6609;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM 6610;; and input/output match. We provide a special pattern for this, because 6611;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the 6612;; operation on I/O is atomic. 6613(define_insn "*insv.io" 6614 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i")) 6615 (const_int 1) 6616 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n")) 6617 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))] 6618 "" 6619 "@ 6620 cbi %i0,%1 6621 sbi %i0,%1 6622 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1" 6623 [(set_attr "length" "1,1,4") 6624 (set_attr "cc" "none")]) 6625 6626(define_insn "*insv.not.io" 6627 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i")) 6628 (const_int 1) 6629 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6630 (not:QI (match_operand:QI 2 "register_operand" "r")))] 6631 "" 6632 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1" 6633 [(set_attr "length" "4") 6634 (set_attr "cc" "none")]) 6635 6636;; The insv expander. 6637;; We only support 1-bit inserts 6638(define_expand "insv" 6639 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "") 6640 (match_operand:QI 1 "const1_operand" "") ; width 6641 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos 6642 (match_operand:QI 3 "nonmemory_operand" ""))] 6643 "optimize") 6644 6645;; Some more patterns to support moving around one bit which can be accomplished 6646;; by BST + BLD in most situations. Unfortunately, there is no canonical 6647;; representation, and we just implement some more cases that are not too 6648;; complicated. 6649 6650;; Insert bit $2.0 into $0.$1 6651(define_insn "*insv.reg" 6652 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l") 6653 (const_int 1) 6654 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n")) 6655 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))] 6656 "" 6657 "@ 6658 bst %2,0\;bld %0,%1 6659 andi %0,lo8(~(1<<%1)) 6660 ori %0,lo8(1<<%1) 6661 clt\;bld %0,%1 6662 set\;bld %0,%1" 6663 [(set_attr "length" "2,1,1,2,2") 6664 (set_attr "cc" "none,set_zn,set_zn,none,none")]) 6665 6666;; Insert bit $2.$3 into $0.$1 6667(define_insn "*insv.extract" 6668 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6669 (const_int 1) 6670 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6671 (any_extract:QI (match_operand:QI 2 "register_operand" "r") 6672 (const_int 1) 6673 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 6674 "" 6675 "bst %2,%3\;bld %0,%1" 6676 [(set_attr "length" "2") 6677 (set_attr "cc" "none")]) 6678 6679;; Insert bit $2.$3 into $0.$1 6680(define_insn "*insv.shiftrt" 6681 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6682 (const_int 1) 6683 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6684 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r") 6685 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 6686 "" 6687 "bst %2,%3\;bld %0,%1" 6688 [(set_attr "length" "2") 6689 (set_attr "cc" "none")]) 6690 6691;; Same, but with a NOT inverting the source bit. 6692;; Insert bit ~$2.$3 into $0.$1 6693(define_insn "*insv.not-shiftrt" 6694 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6695 (const_int 1) 6696 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6697 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r") 6698 (match_operand:QI 3 "const_0_to_7_operand" "n"))))] 6699 "" 6700 { 6701 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL); 6702 } 6703 [(set_attr "adjust_len" "insv_notbit") 6704 (set_attr "cc" "clobber")]) 6705 6706;; Insert bit ~$2.0 into $0.$1 6707(define_insn "*insv.xor1-bit.0" 6708 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6709 (const_int 1) 6710 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6711 (xor:QI (match_operand:QI 2 "register_operand" "r") 6712 (const_int 1)))] 6713 "" 6714 { 6715 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL); 6716 } 6717 [(set_attr "adjust_len" "insv_notbit_0") 6718 (set_attr "cc" "clobber")]) 6719 6720;; Insert bit ~$2.0 into $0.$1 6721(define_insn "*insv.not-bit.0" 6722 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6723 (const_int 1) 6724 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6725 (not:QI (match_operand:QI 2 "register_operand" "r")))] 6726 "" 6727 { 6728 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL); 6729 } 6730 [(set_attr "adjust_len" "insv_notbit_0") 6731 (set_attr "cc" "clobber")]) 6732 6733;; Insert bit ~$2.7 into $0.$1 6734(define_insn "*insv.not-bit.7" 6735 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6736 (const_int 1) 6737 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6738 (ge:QI (match_operand:QI 2 "register_operand" "r") 6739 (const_int 0)))] 6740 "" 6741 { 6742 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL); 6743 } 6744 [(set_attr "adjust_len" "insv_notbit_7") 6745 (set_attr "cc" "clobber")]) 6746 6747;; Insert bit ~$2.$3 into $0.$1 6748(define_insn "*insv.xor-extract" 6749 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r") 6750 (const_int 1) 6751 (match_operand:QI 1 "const_0_to_7_operand" "n")) 6752 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r") 6753 (match_operand:QI 4 "const_int_operand" "n")) 6754 (const_int 1) 6755 (match_operand:QI 3 "const_0_to_7_operand" "n")))] 6756 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))" 6757 { 6758 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL); 6759 } 6760 [(set_attr "adjust_len" "insv_notbit") 6761 (set_attr "cc" "clobber")]) 6762 6763 6764;; Some combine patterns that try to fix bad code when a value is composed 6765;; from byte parts like in PR27663. 6766;; The patterns give some release but the code still is not optimal, 6767;; in particular when subreg lowering (-fsplit-wide-types) is turned on. 6768;; That switch obfuscates things here and in many other places. 6769 6770;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0" 6771;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0" 6772(define_insn_and_split "*<code_stdname><mode>qi.byte0" 6773 [(set (match_operand:HISI 0 "register_operand" "=r") 6774 (xior:HISI 6775 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) 6776 (match_operand:HISI 2 "register_operand" "0")))] 6777 "" 6778 "#" 6779 "reload_completed" 6780 [(set (match_dup 3) 6781 (xior:QI (match_dup 3) 6782 (match_dup 1)))] 6783 { 6784 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0); 6785 }) 6786 6787;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3" 6788;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3" 6789(define_insn_and_split "*<code_stdname><mode>qi.byte1-3" 6790 [(set (match_operand:HISI 0 "register_operand" "=r") 6791 (xior:HISI 6792 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r")) 6793 (match_operand:QI 2 "const_8_16_24_operand" "n")) 6794 (match_operand:HISI 3 "register_operand" "0")))] 6795 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 6796 "#" 6797 "&& reload_completed" 6798 [(set (match_dup 4) 6799 (xior:QI (match_dup 4) 6800 (match_dup 1)))] 6801 { 6802 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT; 6803 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno); 6804 }) 6805 6806 6807(define_insn_and_split "*iorhi3.ashift8-ext.zerox" 6808 [(set (match_operand:HI 0 "register_operand" "=r,r") 6809 (ior:HI (ashift:HI (any_extend:HI 6810 (match_operand:QI 1 "register_operand" "r,r")) 6811 (const_int 8)) 6812 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))] 6813 "optimize" 6814 { gcc_unreachable(); } 6815 "&& reload_completed" 6816 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2))) 6817 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1))) 6818 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))] 6819 { 6820 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1); 6821 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0); 6822 6823 if (!reg_overlap_mentioned_p (hi, operands[2])) 6824 { 6825 emit_move_insn (hi, operands[1]); 6826 emit_move_insn (lo, operands[2]); 6827 DONE; 6828 } 6829 else if (!reg_overlap_mentioned_p (lo, operands[1])) 6830 { 6831 emit_move_insn (lo, operands[2]); 6832 emit_move_insn (hi, operands[1]); 6833 DONE; 6834 } 6835 6836 gcc_assert (REGNO (operands[1]) == REGNO (operands[0])); 6837 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0])); 6838 }) 6839 6840(define_insn_and_split "*iorhi3.ashift8-ext.reg" 6841 [(set (match_operand:HI 0 "register_operand" "=r") 6842 (ior:HI (ashift:HI (any_extend:HI 6843 (match_operand:QI 1 "register_operand" "r")) 6844 (const_int 8)) 6845 (match_operand:HI 2 "register_operand" "0")))] 6846 "optimize" 6847 { gcc_unreachable(); } 6848 "&& reload_completed" 6849 [(set (match_dup 3) 6850 (ior:QI (match_dup 4) 6851 (match_dup 1)))] 6852 { 6853 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 6854 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1); 6855 }) 6856 6857(define_insn_and_split "*iorhi3.ashift8-reg.zerox" 6858 [(set (match_operand:HI 0 "register_operand" "=r") 6859 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r") 6860 (const_int 8)) 6861 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))] 6862 "optimize" 6863 { gcc_unreachable(); } 6864 "&& reload_completed" 6865 [(set (match_dup 3) 6866 (match_dup 4))] 6867 { 6868 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 6869 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0); 6870 }) 6871 6872 6873(define_peephole2 6874 [(set (match_operand:QI 0 "register_operand") 6875 (const_int 0)) 6876 (set (match_dup 0) 6877 (ior:QI (match_dup 0) 6878 (match_operand:QI 1 "register_operand")))] 6879 "" 6880 [(set (match_dup 0) 6881 (match_dup 1))]) 6882 6883 6884(define_expand "extzv" 6885 [(set (match_operand:QI 0 "register_operand" "") 6886 (zero_extract:QI (match_operand:QI 1 "register_operand" "") 6887 (match_operand:QI 2 "const1_operand" "") 6888 (match_operand:QI 3 "const_0_to_7_operand" "")))]) 6889 6890(define_insn "*extzv" 6891 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r") 6892 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r") 6893 (const_int 1) 6894 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))] 6895 "" 6896 "@ 6897 andi %0,1 6898 mov %0,%1\;andi %0,1 6899 lsr %0\;andi %0,1 6900 swap %0\;andi %0,1 6901 bst %1,%2\;clr %0\;bld %0,0" 6902 [(set_attr "length" "1,2,2,2,3") 6903 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")]) 6904 6905(define_insn_and_split "*extzv.qihi1" 6906 [(set (match_operand:HI 0 "register_operand" "=r") 6907 (zero_extract:HI (match_operand:QI 1 "register_operand" "r") 6908 (const_int 1) 6909 (match_operand:QI 2 "const_0_to_7_operand" "n")))] 6910 "" 6911 "#" 6912 "" 6913 [(set (match_dup 3) 6914 (zero_extract:QI (match_dup 1) 6915 (const_int 1) 6916 (match_dup 2))) 6917 (set (match_dup 4) 6918 (const_int 0))] 6919 { 6920 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 6921 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 6922 }) 6923 6924(define_insn_and_split "*extzv.qihi2" 6925 [(set (match_operand:HI 0 "register_operand" "=r") 6926 (zero_extend:HI 6927 (zero_extract:QI (match_operand:QI 1 "register_operand" "r") 6928 (const_int 1) 6929 (match_operand:QI 2 "const_0_to_7_operand" "n"))))] 6930 "" 6931 "#" 6932 "" 6933 [(set (match_dup 3) 6934 (zero_extract:QI (match_dup 1) 6935 (const_int 1) 6936 (match_dup 2))) 6937 (set (match_dup 4) 6938 (const_int 0))] 6939 { 6940 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0); 6941 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1); 6942 }) 6943 6944;; ??? do_store_flag emits a hard-coded right shift to extract a bit without 6945;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example. 6946(define_insn_and_split "*extract.subreg.bit" 6947 [(set (match_operand:QI 0 "register_operand" "=r") 6948 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r") 6949 (match_operand:QI 2 "const_int_operand" "n")) 6950 0) 6951 (const_int 1)))] 6952 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 6953 { gcc_unreachable(); } 6954 "&& reload_completed" 6955 [;; "*extzv" 6956 (set (match_dup 0) 6957 (zero_extract:QI (match_dup 3) 6958 (const_int 1) 6959 (match_dup 4)))] 6960 { 6961 int bitno = INTVAL (operands[2]); 6962 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8); 6963 operands[4] = GEN_INT (bitno % 8); 6964 }) 6965 6966 6967;; Fixed-point instructions 6968(include "avr-fixed.md") 6969 6970;; Operations on 64-bit registers 6971(include "avr-dimode.md") 6972