1;; Machine description for GNU compiler, 2;; for ATMEL AVR micro controllers. 3;; Copyright (C) 1998-2021 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_CPYMEM 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, cpymem, 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 DF SC DC 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 "cpymemhi" 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_cpymemhi (operands)) 1003 DONE; 1004 1005 FAIL; 1006 }) 1007 1008(define_mode_attr CPYMEM_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;; "cpymem_qi" 1017;; "cpymem_hi" 1018(define_insn "cpymem_<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_CPYMEM) 1023 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_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_cpymem (insn, operands, NULL); 1031 } 1032 [(set_attr "adjust_len" "cpymem") 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;; "cpymemx_qi" 1043;; "cpymemx_hi" 1044(define_insn "cpymemx_<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_CPYMEM) 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