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