diff options
Diffstat (limited to 'gcc/config/avr/avr.md')
-rw-r--r-- | gcc/config/avr/avr.md | 831 |
1 files changed, 582 insertions, 249 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 59330104fa0..bddfe933ee6 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -28,9 +28,21 @@ ;; j Branch condition. ;; k Reverse branch condition. ;;..m..Constant Direct Data memory address. +;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT +;; RAM address. The resulting addres is suitable to be used in IN/OUT. ;; o Displacement for (mem (plus (reg) (const_int))) operands. ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z) ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30) +;; T/T Print operand suitable for BLD/BST instruction, i.e. register and +;; bit number. This gets 2 operands: The first %T gets a REG_P and +;; just cashes the operand for the next %T. The second %T gets +;; a CONST_INT that represents a bit position. +;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13) +;; "%T0%T1" it will print "r19,5". +;; Notice that you must not write a comma between %T0 and %T1. +;; T/t Similar to above, but don't print the comma and the bit number. +;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13) +;; "%T0%t1" it will print "r19". ;;..x..Constant Direct Program memory address. ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL. ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL. @@ -42,21 +54,27 @@ (REG_Z 30) (REG_W 24) (REG_SP 32) + (LPM_REGNO 0) ; implicit target register of LPM (TMP_REGNO 0) ; temporary register r0 (ZERO_REGNO 1) ; zero register r1 - - (SREG_ADDR 0x5F) - (RAMPZ_ADDR 0x5B) + + ;; RAM addresses of some SFRs common to all Devices. + + (SREG_ADDR 0x5F) ; Status Register + (SP_ADDR 0x5D) ; Stack Pointer + (RAMPZ_ADDR 0x5B) ; Address' high part when loading via ELPM ]) (define_c_enum "unspec" [UNSPEC_STRLEN + UNSPEC_MOVMEM UNSPEC_INDEX_JMP UNSPEC_FMUL UNSPEC_FMULS UNSPEC_FMULSU UNSPEC_COPYSIGN UNSPEC_IDENTITY + UNSPEC_MAP_BITS ]) (define_c_enum "unspecv" @@ -127,24 +145,25 @@ "out_bitop, out_plus, out_plus_noclobber, addto_sp, tsthi, tstpsi, tstsi, compare, call, mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32, + xload, movmem, ashlqi, ashrqi, lshrqi, ashlhi, ashrhi, lshrhi, ashlsi, ashrsi, lshrsi, ashlpsi, ashrpsi, lshrpsi, + map_bits, no" (const_string "no")) ;; Flavours of instruction set architecture (ISA), used in enabled attribute -;; mov: ISA has no MOVW -;; movw: ISA has MOVW -;; rjmp: ISA has no CALL/JMP -;; jmp: ISA has CALL/JMP -;; ijmp: ISA has no EICALL/EIJMP -;; eijmp: ISA has EICALL/EIJMP +;; mov : ISA has no MOVW movw : ISA has MOVW +;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP +;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP +;; lpm : ISA has no LPMX lpmx : ISA has LPMX +;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX (define_attr "isa" - "mov,movw, rjmp,jmp, ijmp,eijmp, + "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, standard" (const_string "standard")) @@ -175,6 +194,22 @@ (and (eq_attr "isa" "eijmp") (match_test "AVR_HAVE_EIJMP_EICALL")) (const_int 1) + + (and (eq_attr "isa" "lpm") + (match_test "!AVR_HAVE_LPMX")) + (const_int 1) + + (and (eq_attr "isa" "lpmx") + (match_test "AVR_HAVE_LPMX")) + (const_int 1) + + (and (eq_attr "isa" "elpm") + (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX")) + (const_int 1) + + (and (eq_attr "isa" "elpmx") + (match_test "AVR_HAVE_ELPMX")) + (const_int 1) ] (const_int 0))) @@ -242,12 +277,10 @@ ;; even though its function is identical to that in builtins.c (define_expand "nonlocal_goto" - [ - (use (match_operand 0 "general_operand")) - (use (match_operand 1 "general_operand")) - (use (match_operand 2 "general_operand")) - (use (match_operand 3 "general_operand")) - ] + [(use (match_operand 0 "general_operand")) + (use (match_operand 1 "general_operand")) + (use (match_operand 2 "general_operand")) + (use (match_operand 3 "general_operand"))] "" { rtx r_label = copy_to_reg (operands[1]); @@ -315,6 +348,168 @@ "") ;;======================================================================== +;; Move stuff around + +(define_expand "load<mode>_libgcc" + [(set (match_dup 3) + (match_dup 2)) + (set (reg:MOVMODE 22) + (match_operand:MOVMODE 1 "memory_operand" "")) + (set (match_operand:MOVMODE 0 "register_operand" "") + (reg:MOVMODE 22))] + "avr_load_libgcc_p (operands[1])" + { + operands[3] = gen_rtx_REG (HImode, REG_Z); + operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX); + operands[1] = replace_equiv_address (operands[1], operands[3]); + set_mem_addr_space (operands[1], ADDR_SPACE_PGM); + }) + +(define_insn "load_<mode>_libgcc" + [(set (reg:MOVMODE 22) + (match_operand:MOVMODE 0 "memory_operand" "m,m"))] + "avr_load_libgcc_p (operands[0]) + && REG_P (XEXP (operands[0], 0)) + && REG_Z == REGNO (XEXP (operands[0], 0))" + { + operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode)); + return "%~call __load_%0"; + } + [(set_attr "length" "1,2") + (set_attr "isa" "rjmp,jmp") + (set_attr "cc" "clobber")]) + + +(define_insn_and_split "xload8_A" + [(set (match_operand:QI 0 "register_operand" "=r") + (match_operand:QI 1 "memory_operand" "m")) + (clobber (reg:HI REG_Z))] + "can_create_pseudo_p() + && avr_mem_pgmx_p (operands[1]) + && REG_P (XEXP (operands[1], 0))" + { gcc_unreachable(); } + "&& 1" + [(clobber (const_int 0))] + { + rtx insn, addr = XEXP (operands[1], 0); + rtx hi8 = gen_reg_rtx (QImode); + rtx reg_z = gen_rtx_REG (HImode, REG_Z); + + emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); + emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2)); + + insn = emit_insn (gen_xload_8 (operands[0], hi8)); + set_mem_addr_space (SET_SRC (single_set (insn)), + MEM_ADDR_SPACE (operands[1])); + DONE; + }) + +(define_insn_and_split "xload<mode>_A" + [(set (match_operand:MOVMODE 0 "register_operand" "=r") + (match_operand:MOVMODE 1 "memory_operand" "m")) + (clobber (reg:QI 21)) + (clobber (reg:HI REG_Z))] + "QImode != <MODE>mode + && can_create_pseudo_p() + && avr_mem_pgmx_p (operands[1]) + && REG_P (XEXP (operands[1], 0))" + { gcc_unreachable(); } + "&& 1" + [(clobber (const_int 0))] + { + rtx addr = XEXP (operands[1], 0); + rtx reg_z = gen_rtx_REG (HImode, REG_Z); + rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2); + addr_space_t as = MEM_ADDR_SPACE (operands[1]); + rtx hi8, insn; + + emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); + + if (avr_xload_libgcc_p (<MODE>mode)) + { + emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8); + insn = emit_insn (gen_xload_<mode>_libgcc ()); + emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22)); + } + else if (avr_current_arch->n_segments == 1 + && GET_MODE_SIZE (<MODE>mode) > 2 + && !AVR_HAVE_LPMX) + { + rtx src = gen_rtx_MEM (<MODE>mode, reg_z); + + as = ADDR_SPACE_PGM; + insn = emit_insn (gen_load_<mode>_libgcc (src)); + emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22)); + } + else + { + hi8 = gen_reg_rtx (QImode); + emit_move_insn (hi8, addr_hi8); + insn = emit_insn (gen_xload_<mode> (operands[0], hi8)); + } + + set_mem_addr_space (SET_SRC (single_set (insn)), as); + + DONE; + }) + +;; Move value from address space pgmx to a register +;; These insns must be prior to respective generic move insn. + +(define_insn "xload_8" + [(set (match_operand:QI 0 "register_operand" "=r") + (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r") + (reg:HI REG_Z))))] + "" + { + return avr_out_xload (insn, operands, NULL); + } + [(set_attr "adjust_len" "xload") + (set_attr "cc" "clobber")]) + +;; "xload_hi_libgcc" +;; "xload_psi_libgcc" +;; "xload_si_libgcc" +;; "xload_sf_libgcc" +(define_insn "xload_<mode>_libgcc" + [(set (reg:MOVMODE 22) + (mem:MOVMODE (lo_sum:PSI (reg:QI 21) + (reg:HI REG_Z)))) + (clobber (reg:QI 21)) + (clobber (reg:HI REG_Z))] + "<MODE>mode != QImode + && avr_xload_libgcc_p (<MODE>mode)" + { + rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode)); + + /* Devices with ELPM* also have CALL. */ + + output_asm_insn ("call __xload_%0", &x_bytes); + return ""; + } + [(set_attr "length" "2") + (set_attr "cc" "clobber")]) + +;; "xload_hi" +;; "xload_psi" +;; "xload_si" +;; "xload_sf" +(define_insn "xload_<mode>" + [(set (match_operand:MOVMODE 0 "register_operand" "=r") + (mem:MOVMODE (lo_sum:PSI (match_operand:QI 1 "register_operand" "r") + (reg:HI REG_Z)))) + (clobber (scratch:HI)) + (clobber (reg:HI REG_Z))] + "<MODE>mode != QImode + && !avr_xload_libgcc_p (<MODE>mode)" + { + return avr_out_xload (insn, operands, NULL); + } + [(set_attr "adjust_len" "xload") + (set_attr "cc" "clobber")]) + + +;; General move expanders ;; "movqi" ;; "movhi" @@ -327,12 +522,40 @@ (match_operand:MOVMODE 1 "general_operand" ""))] "" { - /* One of the ops has to be in a register. */ - if (!register_operand (operands[0], <MODE>mode) - && !(register_operand (operands[1], <MODE>mode) - || CONST0_RTX (<MODE>mode) == operands[1])) + rtx dest = operands[0]; + rtx src = operands[1]; + + if (avr_mem_pgm_p (dest)) + DONE; + + /* One of the operands has to be in a register. */ + if (!register_operand (dest, <MODE>mode) + && !(register_operand (src, <MODE>mode) + || src == CONST0_RTX (<MODE>mode))) + { + operands[1] = src = copy_to_mode_reg (<MODE>mode, src); + } + + if (avr_mem_pgmx_p (src)) + { + rtx addr = XEXP (src, 0); + + if (!REG_P (addr)) + src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr)); + + if (QImode == <MODE>mode) + emit_insn (gen_xload8_A (dest, src)); + else + emit_insn (gen_xload<mode>_A (dest, src)); + + DONE; + } + + if (avr_load_libgcc_p (src)) { - operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]); + /* For the small devices, do loads per libgcc call. */ + emit_insn (gen_load<mode>_libgcc (dest, src)); + DONE; } }) @@ -346,11 +569,14 @@ ;; so this may still be a win for registers live across function calls. (define_insn "movqi_insn" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r") - (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))] - "(register_operand (operands[0],QImode) - || register_operand (operands[1], QImode) || const0_rtx == operands[1])" - "* return output_movqi (insn, operands, NULL);" + [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r") + (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))] + "register_operand (operands[0], QImode) + || register_operand (operands[1], QImode) + || const0_rtx == operands[1]" + { + return output_movqi (insn, operands, NULL); + } [(set_attr "length" "1,1,5,5,1,1,4") (set_attr "adjust_len" "mov8") (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")]) @@ -425,14 +651,17 @@ (set_attr "cc" "none")]) (define_insn "*movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,d,*r,q,r") - (match_operand:HI 1 "general_operand" "r,L,m,rL,i,i,r,q"))] - "(register_operand (operands[0],HImode) - || register_operand (operands[1],HImode) || const0_rtx == operands[1])" - "* return output_movhi (insn, operands, NULL);" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r") + (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))] + "register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || const0_rtx == operands[1]" + { + return output_movhi (insn, operands, NULL); + } [(set_attr "length" "2,2,6,7,2,6,5,2") (set_attr "adjust_len" "mov16") - (set_attr "cc" "none,clobber,clobber,clobber,none,clobber,none,none")]) + (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")]) (define_peephole2 ; movw [(set (match_operand:QI 0 "even_register_operand" "") @@ -462,6 +691,40 @@ operands[5] = gen_rtx_REG (HImode, REGNO (operands[3])); }) +;; For LPM loads from AS1 we split +;; R = *Z +;; to +;; R = *Z++ +;; Z = Z - sizeof (R) +;; +;; so that the second instruction can be optimized out. + +(define_split ; "split-lpmx" + [(set (match_operand:HISI 0 "register_operand" "") + (match_operand:HISI 1 "memory_operand" ""))] + "reload_completed + && AVR_HAVE_LPMX" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 3) + (plus:HI (match_dup 3) + (match_dup 4)))] + { + rtx addr = XEXP (operands[1], 0); + + if (!avr_mem_pgm_p (operands[1]) + || !REG_P (addr) + || reg_overlap_mentioned_p (addr, operands[0])) + { + FAIL; + } + + operands[2] = replace_equiv_address (operands[1], + gen_rtx_POST_INC (Pmode, addr)); + operands[3] = addr; + operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode); + }) + ;;========================================================================== ;; xpointer move (24 bit) @@ -492,7 +755,7 @@ (define_insn "*movpsi" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") - (match_operand:PSI 1 "general_operand" "r,L,Qm,rL,i ,i"))] + (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))] "register_operand (operands[0], PSImode) || register_operand (operands[1], PSImode) || const0_rtx == operands[1]" @@ -501,7 +764,7 @@ } [(set_attr "length" "3,3,8,9,4,10") (set_attr "adjust_len" "mov24") - (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")]) + (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) ;;========================================================================== ;; move double word (32 bit) @@ -532,23 +795,24 @@ (define_insn "*movsi" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r") - (match_operand:SI 1 "general_operand" "r,L,Qm,rL,i,i"))] - "(register_operand (operands[0],SImode) - || register_operand (operands[1],SImode) || const0_rtx == operands[1])" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") + (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || const0_rtx == operands[1]" { return output_movsisf (insn, operands, NULL); } [(set_attr "length" "4,4,8,9,4,10") (set_attr "adjust_len" "mov32") - (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")]) + (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ;; move floating point numbers (32 bit) (define_insn "*movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r") - (match_operand:SF 1 "general_operand" "r,G,Qm,rG,F,F"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r") + (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))] "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode) || operands[1] == CONST0_RTX (SFmode)" @@ -557,7 +821,7 @@ } [(set_attr "length" "4,4,8,9,4,10") (set_attr "adjust_len" "mov32") - (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")]) + (set_attr "cc" "none,none,clobber,clobber,none,clobber")]) (define_peephole2 ; *reload_insf [(match_scratch:QI 2 "d") @@ -585,166 +849,164 @@ ;;========================================================================= ;; move string (like memcpy) -;; implement as RTL loop (define_expand "movmemhi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:HI 2 "const_int_operand" "")) - (use (match_operand:HI 3 "const_int_operand" ""))])] + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:HI 2 "const_int_operand" "")) + (use (match_operand:HI 3 "const_int_operand" ""))])] "" - "{ - int prob; - HOST_WIDE_INT count; - enum machine_mode mode; - rtx label = gen_label_rtx (); - rtx loop_reg; - rtx jump; - - /* Copy pointers into new psuedos - they will be changed. */ - rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - - /* Create rtx for tmp register - we use this as scratch. */ - rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO); - - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - - count = INTVAL (operands[2]); - if (count <= 0) + { + if (avr_emit_movmemhi (operands)) + DONE; + FAIL; + }) - /* Work out branch probability for latter use. */ - prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count; - - /* See if constant fit 8 bits. */ - mode = (count < 0x100) ? QImode : HImode; - /* Create loop counter register. */ - loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode)); - - /* Now create RTL code for move loop. */ - /* Label at top of loop. */ - emit_label (label); - - /* Move one byte into scratch and inc pointer. */ - emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1)); - emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx)); - - /* Move to mem and inc pointer. */ - emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx); - emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx)); +(define_mode_attr MOVMEM_r_d [(QI "r") + (HI "d")]) + +;; $0, $4 : & dest +;; $1, $5 : & src +;; $2 : Address Space +;; $3, $7 : Loop register +;; $6 : Scratch register + +;; "movmem_qi" +;; "movmem_hi" +(define_insn "movmem_<mode>" + [(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) + (mem:BLK (match_operand:HI 1 "register_operand" "z"))) + (unspec [(match_operand:QI 2 "const_int_operand" "LP")] + UNSPEC_MOVMEM) + (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>")) + (clobber (match_operand:HI 4 "register_operand" "=0")) + (clobber (match_operand:HI 5 "register_operand" "=1")) + (clobber (match_operand:QI 6 "register_operand" "=&r")) + (clobber (match_operand:QIHI 7 "register_operand" "=3"))] + "" + { + return avr_out_movmem (insn, operands, NULL); + } + [(set_attr "adjust_len" "movmem") + (set_attr "cc" "clobber")]) - /* Decrement count. */ - emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx)); +;; Ditto and +;; $8, $9 : hh8 (& src) +;; $10 : RAMPZ_ADDR + +;; "movmem_qi_elpm" +;; "movmem_hi_elpm" +(define_insn "movmem_<mode>_elpm" + [(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) + (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r") + (match_operand:HI 1 "register_operand" "z")))) + (unspec [(match_operand:QI 2 "const_int_operand" "n")] + UNSPEC_MOVMEM) + (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>")) + (clobber (match_operand:HI 4 "register_operand" "=0")) + (clobber (match_operand:HI 5 "register_operand" "=1")) + (clobber (match_operand:QI 6 "register_operand" "=&r")) + (clobber (match_operand:QIHI 7 "register_operand" "=3")) + (clobber (match_operand:QI 9 "register_operand" "=8")) + (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))] + "" + { + return avr_out_movmem (insn, operands, NULL); + } + [(set_attr "adjust_len" "movmem") + (set_attr "cc" "clobber")]) - /* Compare with zero and jump if not equal. */ - emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1, - label); - /* Set jump probability based on loop count. */ - jump = get_last_insn (); - add_reg_note (jump, REG_BR_PROB, GEN_INT (prob)); - DONE; -}") -;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 +;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 ;; memset (%0, %2, %1) (define_expand "setmemhi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand 2 "const_int_operand" "")) - (use (match_operand:HI 1 "const_int_operand" "")) - (use (match_operand:HI 3 "const_int_operand" "n")) - (clobber (match_scratch:HI 4 "")) - (clobber (match_dup 5))])] + (match_operand 2 "const_int_operand" "")) + (use (match_operand:HI 1 "const_int_operand" "")) + (use (match_operand:HI 3 "const_int_operand" "")) + (clobber (match_scratch:HI 4 "")) + (clobber (match_dup 5))])] "" - "{ - rtx addr0; - enum machine_mode mode; + { + rtx addr0; + enum machine_mode mode; - /* If value to set is not zero, use the library routine. */ - if (operands[2] != const0_rtx) - FAIL; + /* If value to set is not zero, use the library routine. */ + if (operands[2] != const0_rtx) + FAIL; - if (!CONST_INT_P (operands[1])) - FAIL; + if (!CONST_INT_P (operands[1])) + FAIL; + + mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode; + operands[5] = gen_rtx_SCRATCH (mode); + operands[1] = copy_to_mode_reg (mode, + gen_int_mode (INTVAL (operands[1]), mode)); + addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); + operands[0] = gen_rtx_MEM (BLKmode, addr0); + }) - mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode; - operands[5] = gen_rtx_SCRATCH (mode); - operands[1] = copy_to_mode_reg (mode, - gen_int_mode (INTVAL (operands[1]), mode)); - addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - operands[0] = gen_rtx_MEM (BLKmode, addr0); -}") (define_insn "*clrmemqi" [(set (mem:BLK (match_operand:HI 0 "register_operand" "e")) - (const_int 0)) + (const_int 0)) (use (match_operand:QI 1 "register_operand" "r")) (use (match_operand:QI 2 "const_int_operand" "n")) (clobber (match_scratch:HI 3 "=0")) (clobber (match_scratch:QI 4 "=&1"))] "" - "st %a0+,__zero_reg__ - dec %1 - brne .-6" + "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b" [(set_attr "length" "3") (set_attr "cc" "clobber")]) + (define_insn "*clrmemhi" [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e")) - (const_int 0)) + (const_int 0)) (use (match_operand:HI 1 "register_operand" "!w,d")) (use (match_operand:HI 2 "const_int_operand" "n,n")) (clobber (match_scratch:HI 3 "=0,0")) (clobber (match_scratch:HI 4 "=&1,&1"))] "" - "*{ - if (which_alternative==0) - return (AS2 (st,%a0+,__zero_reg__) CR_TAB - AS2 (sbiw,%A1,1) CR_TAB - AS1 (brne,.-6)); - else - return (AS2 (st,%a0+,__zero_reg__) CR_TAB - AS2 (subi,%A1,1) CR_TAB - AS2 (sbci,%B1,0) CR_TAB - AS1 (brne,.-8)); -}" + "@ + 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b + 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b" [(set_attr "length" "3,4") (set_attr "cc" "clobber,clobber")]) (define_expand "strlenhi" - [(set (match_dup 4) - (unspec:HI [(match_operand:BLK 1 "memory_operand" "") - (match_operand:QI 2 "const_int_operand" "") - (match_operand:HI 3 "immediate_operand" "")] - UNSPEC_STRLEN)) - (set (match_dup 4) (plus:HI (match_dup 4) - (const_int -1))) - (set (match_operand:HI 0 "register_operand" "") - (minus:HI (match_dup 4) - (match_dup 5)))] - "" - "{ - rtx addr; - if (operands[2] != const0_rtx) - FAIL; - addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0)); - operands[1] = gen_rtx_MEM (BLKmode, addr); - operands[5] = addr; - operands[4] = gen_reg_rtx (HImode); -}") + [(set (match_dup 4) + (unspec:HI [(match_operand:BLK 1 "memory_operand" "") + (match_operand:QI 2 "const_int_operand" "") + (match_operand:HI 3 "immediate_operand" "")] + UNSPEC_STRLEN)) + (set (match_dup 4) + (plus:HI (match_dup 4) + (const_int -1))) + (set (match_operand:HI 0 "register_operand" "") + (minus:HI (match_dup 4) + (match_dup 5)))] + "" + { + rtx addr; + if (operands[2] != const0_rtx) + FAIL; + addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); + operands[1] = gen_rtx_MEM (BLKmode, addr); + operands[5] = addr; + operands[4] = gen_reg_rtx (HImode); + }) (define_insn "*strlenhi" - [(set (match_operand:HI 0 "register_operand" "=e") - (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0")) - (const_int 0) - (match_operand:HI 2 "immediate_operand" "i")] - UNSPEC_STRLEN))] - "" - "ld __tmp_reg__,%a0+ - tst __tmp_reg__ - brne .-6" + [(set (match_operand:HI 0 "register_operand" "=e") + (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0")) + (const_int 0) + (match_operand:HI 2 "immediate_operand" "i")] + UNSPEC_STRLEN))] + "" + "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b" [(set_attr "length" "3") (set_attr "cc" "clobber")]) @@ -2770,7 +3032,7 @@ (const_int 15)))] "" "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7" - [(set_attr "length" "3") + [(set_attr "length" "4") (set_attr "cc" "clobber")]) (define_insn "*rotlpsi2.1" @@ -2868,10 +3130,8 @@ (define_expand "ashlqi3" [(set (match_operand:QI 0 "register_operand" "") - (ashift:QI (match_operand:QI 1 "register_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "") + (ashift:QI (match_operand:QI 1 "register_operand" "") + (match_operand:QI 2 "nop_general_operand" "")))]) (define_split ; ashlqi3_const4 [(set (match_operand:QI 0 "d_register_operand" "") @@ -2903,21 +3163,25 @@ "") (define_insn "*ashlqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") - (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))] "" - "* return ashlqi3_out (insn, operands, NULL);" + { + return ashlqi3_out (insn, operands, NULL); + } [(set_attr "length" "5,0,1,2,4,6,9") (set_attr "adjust_len" "ashlqi") (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "ashlhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return ashlhi3_out (insn, operands, NULL);" + { + return ashlhi3_out (insn, operands, NULL); + } [(set_attr "length" "6,0,2,2,4,10,10") (set_attr "adjust_len" "ashlhi") (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) @@ -3005,11 +3269,13 @@ (define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return ashlsi3_out (insn, operands, NULL);" + { + return ashlsi3_out (insn, operands, NULL); + } [(set_attr "length" "8,0,4,4,8,10,12") (set_attr "adjust_len" "ashlsi") (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) @@ -3063,11 +3329,13 @@ (define_insn "*ashlhi3_const" [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" - "* return ashlhi3_out (insn, operands, NULL);" + { + return ashlhi3_out (insn, operands, NULL); + } [(set_attr "length" "0,2,2,4,10") (set_attr "adjust_len" "ashlhi") (set_attr "cc" "none,set_n,clobber,set_n,clobber")]) @@ -3084,11 +3352,13 @@ (define_insn "*ashlsi3_const" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" - "* return ashlsi3_out (insn, operands, NULL);" + { + return ashlsi3_out (insn, operands, NULL); + } [(set_attr "length" "0,4,4,10") (set_attr "adjust_len" "ashlsi") (set_attr "cc" "none,set_n,clobber,clobber")]) @@ -3109,21 +3379,25 @@ ;; arithmetic shift right (define_insn "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0") - (match_operand:QI 2 "general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r") + (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))] "" - "* return ashrqi3_out (insn, operands, NULL);" + { + return ashrqi3_out (insn, operands, NULL); + } [(set_attr "length" "5,0,1,2,5,4,9") (set_attr "adjust_len" "ashrqi") (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")]) (define_insn "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return ashrhi3_out (insn, operands, NULL);" + { + return ashrhi3_out (insn, operands, NULL); + } [(set_attr "length" "6,0,2,4,4,10,10") (set_attr "adjust_len" "ashrhi") (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) @@ -3141,11 +3415,13 @@ (set_attr "cc" "clobber")]) (define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return ashrsi3_out (insn, operands, NULL);" + { + return ashrsi3_out (insn, operands, NULL); + } [(set_attr "length" "8,0,4,6,8,10,12") (set_attr "adjust_len" "ashrsi") (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) @@ -3164,11 +3440,13 @@ (define_insn "*ashrhi3_const" [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" - "* return ashrhi3_out (insn, operands, NULL);" + { + return ashrhi3_out (insn, operands, NULL); + } [(set_attr "length" "0,2,4,4,10") (set_attr "adjust_len" "ashrhi") (set_attr "cc" "none,clobber,set_n,clobber,clobber")]) @@ -3185,11 +3463,13 @@ (define_insn "*ashrsi3_const" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" - "* return ashrsi3_out (insn, operands, NULL);" + { + return ashrsi3_out (insn, operands, NULL); + } [(set_attr "length" "0,4,4,10") (set_attr "adjust_len" "ashrsi") (set_attr "cc" "none,clobber,set_n,clobber")]) @@ -3198,11 +3478,9 @@ ;; logical shift right (define_expand "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "") + [(set (match_operand:QI 0 "register_operand" "") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "") + (match_operand:QI 2 "nop_general_operand" "")))]) (define_split ; lshrqi3_const4 [(set (match_operand:QI 0 "d_register_operand" "") @@ -3234,21 +3512,25 @@ "") (define_insn "*lshrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))] "" - "* return lshrqi3_out (insn, operands, NULL);" + { + return lshrqi3_out (insn, operands, NULL); + } [(set_attr "length" "5,0,1,2,4,6,9") (set_attr "adjust_len" "lshrqi") (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return lshrhi3_out (insn, operands, NULL);" + { + return lshrhi3_out (insn, operands, NULL); + } [(set_attr "length" "6,0,2,2,4,10,10") (set_attr "adjust_len" "lshrhi") (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) @@ -3266,11 +3548,13 @@ (set_attr "cc" "clobber")]) (define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))] "" - "* return lshrsi3_out (insn, operands, NULL);" + { + return lshrsi3_out (insn, operands, NULL); + } [(set_attr "length" "8,0,4,4,8,10,12") (set_attr "adjust_len" "lshrsi") (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) @@ -3324,11 +3608,13 @@ (define_insn "*lshrhi3_const" [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" - "* return lshrhi3_out (insn, operands, NULL);" + { + return lshrhi3_out (insn, operands, NULL); + } [(set_attr "length" "0,2,2,4,10") (set_attr "adjust_len" "lshrhi") (set_attr "cc" "none,clobber,clobber,clobber,clobber")]) @@ -3345,11 +3631,13 @@ (define_insn "*lshrsi3_const" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") - (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" - "* return lshrsi3_out (insn, operands, NULL);" + { + return lshrsi3_out (insn, operands, NULL); + } [(set_attr "length" "0,4,4,10") (set_attr "adjust_len" "lshrsi") (set_attr "cc" "none,clobber,clobber,clobber")]) @@ -3615,6 +3903,27 @@ operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); }) +(define_insn_and_split "n_extendhipsi2" + [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r") + (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n") + (match_operand:HI 2 "register_operand" "r,r,r,r"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + "" + "#" + "reload_completed" + [(set (match_dup 4) (match_dup 2)) + (set (match_dup 3) (match_dup 6)) + ; no-op move in the case where no scratch is needed + (set (match_dup 5) (match_dup 3))] + { + operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0); + operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2); + operands[6] = operands[1]; + + if (GET_CODE (operands[3]) == SCRATCH) + operands[3] = operands[5]; + }) + (define_insn_and_split "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))] @@ -4363,25 +4672,25 @@ (define_insn "*cbi" [(set (mem:QI (match_operand 0 "low_io_address_operand" "n")) - (and:QI (mem:QI (match_dup 0)) - (match_operand:QI 1 "single_zero_operand" "n")))] - "(optimize > 0)" -{ - operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); - return AS2 (cbi,%m0-0x20,%2); -} + (and:QI (mem:QI (match_dup 0)) + (match_operand:QI 1 "single_zero_operand" "n")))] + "optimize > 0" + { + operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff)); + return "cbi %i0,%2"; + } [(set_attr "length" "1") (set_attr "cc" "none")]) (define_insn "*sbi" [(set (mem:QI (match_operand 0 "low_io_address_operand" "n")) - (ior:QI (mem:QI (match_dup 0)) - (match_operand:QI 1 "single_one_operand" "n")))] - "(optimize > 0)" -{ - operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); - return AS2 (sbi,%m0-0x20,%2); -} + (ior:QI (mem:QI (match_dup 0)) + (match_operand:QI 1 "single_one_operand" "n")))] + "optimize > 0" + { + operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff)); + return "sbi %i0,%2"; + } [(set_attr "length" "1") (set_attr "cc" "none")]) @@ -4796,6 +5105,30 @@ [(set_attr "length" "9") (set_attr "cc" "clobber")]) +(define_insn "map_bitsqi" + [(set (match_operand:QI 0 "register_operand" "=d") + (unspec:QI [(match_operand:SI 1 "const_int_operand" "n") + (match_operand:QI 2 "register_operand" "r")] + UNSPEC_MAP_BITS))] + "" + { + return avr_out_map_bits (insn, operands, NULL); + } + [(set_attr "adjust_len" "map_bits") + (set_attr "cc" "clobber")]) + +(define_insn "map_bitshi" + [(set (match_operand:HI 0 "register_operand" "=&r") + (unspec:HI [(match_operand:DI 1 "const_double_operand" "n") + (match_operand:HI 2 "register_operand" "r")] + UNSPEC_MAP_BITS))] + "" + { + return avr_out_map_bits (insn, operands, NULL); + } + [(set_attr "adjust_len" "map_bits") + (set_attr "cc" "clobber")]) + ;; Parity @@ -5340,9 +5673,9 @@ (match_operand:QI 2 "nonmemory_operand" "L,P,r"))] "" "@ - cbi %m0-0x20,%1 - sbi %m0-0x20,%1 - sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1" + cbi %i0,%1 + sbi %i0,%1 + sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1" [(set_attr "length" "1,1,4") (set_attr "cc" "none")]) @@ -5352,7 +5685,7 @@ (match_operand:QI 1 "const_0_to_7_operand" "n")) (not:QI (match_operand:QI 2 "register_operand" "r")))] "" - "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1" + "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1" [(set_attr "length" "4") (set_attr "cc" "none")]) |