📄 avr.c
字号:
} else if (GET_CODE (base) == POST_INC) /* (R++) */ { if (reg_overlap_mentioned_p (dest, XEXP (base, 0))) fatal_insn ("incorrect insn:", insn); *l = 2; return (AS2 (ld,%A0,%1) CR_TAB AS2 (ld,%B0,%1)); } else if (CONSTANT_ADDRESS_P (base)) { if (avr_io_address_p (base, 2)) { *l = 2; return (AS2 (in,%A0,%A1-0x20) CR_TAB AS2 (in,%B0,%B1-0x20)); } *l = 4; return (AS2 (lds,%A0,%A1) CR_TAB AS2 (lds,%B0,%B1)); } fatal_insn ("unknown move insn:",insn); return "";}const char *out_movsi_r_mr (insn, op, l) rtx insn; rtx op[]; int *l; /* instruction length */{ rtx dest = op[0]; rtx src = op[1]; rtx base = XEXP (src, 0); int reg_dest = true_regnum (dest); int reg_base = true_regnum (base); int tmp; if (!l) l = &tmp; if (reg_base > 0) { if (reg_base == REG_X) /* (R26) */ { if (reg_dest == REG_X) /* "ld r26,-X" is undefined */ return *l=7, (AS2 (adiw,r26,3) CR_TAB AS2 (ld,r29,X) CR_TAB AS2 (ld,r28,-X) CR_TAB AS2 (ld,__tmp_reg__,-X) CR_TAB AS2 (sbiw,r26,1) CR_TAB AS2 (ld,r26,X) CR_TAB AS2 (mov,r27,__tmp_reg__)); else if (reg_dest == REG_X - 2) return *l=5, (AS2 (ld,%A0,X+) CR_TAB AS2 (ld,%B0,X+) CR_TAB AS2 (ld,__tmp_reg__,X+) CR_TAB AS2 (ld,%D0,X) CR_TAB AS2 (mov,%C0,__tmp_reg__)); else if (reg_unused_after (insn, base)) return *l=4, (AS2 (ld,%A0,X+) CR_TAB AS2 (ld,%B0,X+) CR_TAB AS2 (ld,%C0,X+) CR_TAB AS2 (ld,%D0,X)); else return *l=5, (AS2 (ld,%A0,X+) CR_TAB AS2 (ld,%B0,X+) CR_TAB AS2 (ld,%C0,X+) CR_TAB AS2 (ld,%D0,X) CR_TAB AS2 (sbiw,r26,3)); } else { if (reg_dest == reg_base) return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB AS2 (ldd,%C0,%1+2) CR_TAB AS2 (ldd,__tmp_reg__,%1+1) CR_TAB AS2 (ld,%A0,%1) CR_TAB AS2 (mov,%B0,__tmp_reg__)); else if (reg_base == reg_dest + 2) return *l=5, (AS2 (ld ,%A0,%1) CR_TAB AS2 (ldd,%B0,%1+1) CR_TAB AS2 (ldd,__tmp_reg__,%1+2) CR_TAB AS2 (ldd,%D0,%1+3) CR_TAB AS2 (mov,%C0,__tmp_reg__)); else return *l=4, (AS2 (ld ,%A0,%1) CR_TAB AS2 (ldd,%B0,%1+1) CR_TAB AS2 (ldd,%C0,%1+2) CR_TAB AS2 (ldd,%D0,%1+3)); } } else if (GET_CODE (base) == PLUS) /* (R + i) */ { int disp = INTVAL (XEXP (base, 1)); if (disp > MAX_LD_OFFSET (GET_MODE (src))) { if (REGNO (XEXP (base, 0)) != REG_Y) fatal_insn ("incorrect insn:",insn); if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))) return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB AS2 (ldd,%A0,Y+60) CR_TAB AS2 (ldd,%B0,Y+61) CR_TAB AS2 (ldd,%C0,Y+62) CR_TAB AS2 (ldd,%D0,Y+63) CR_TAB AS2 (sbiw,r28,%o1-60)); return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB AS2 (sbci,r29,hi8(-%o1)) CR_TAB AS2 (ld,%A0,Y) CR_TAB AS2 (ldd,%B0,Y+1) CR_TAB AS2 (ldd,%C0,Y+2) CR_TAB AS2 (ldd,%D0,Y+3) CR_TAB AS2 (subi,r28,lo8(%o1)) CR_TAB AS2 (sbci,r29,hi8(%o1))); } reg_base = true_regnum (XEXP (base, 0)); if (reg_base == REG_X) { /* R = (X + d) */ if (reg_dest == REG_X) { *l = 7; /* "ld r26,-X" is undefined */ return (AS2 (adiw,r26,%o1+3) CR_TAB AS2 (ld,r29,X) CR_TAB AS2 (ld,r28,-X) CR_TAB AS2 (ld,__tmp_reg__,-X) CR_TAB AS2 (sbiw,r26,1) CR_TAB AS2 (ld,r26,X) CR_TAB AS2 (mov,r27,__tmp_reg__)); } *l = 6; if (reg_dest == REG_X - 2) return (AS2 (adiw,r26,%o1) CR_TAB AS2 (ld,r24,X+) CR_TAB AS2 (ld,r25,X+) CR_TAB AS2 (ld,__tmp_reg__,X+) CR_TAB AS2 (ld,r27,X) CR_TAB AS2 (mov,r26,__tmp_reg__)); return (AS2 (adiw,r26,%o1) CR_TAB AS2 (ld,%A0,X+) CR_TAB AS2 (ld,%B0,X+) CR_TAB AS2 (ld,%C0,X+) CR_TAB AS2 (ld,%D0,X) CR_TAB AS2 (sbiw,r26,%o1+3)); } if (reg_dest == reg_base) return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB AS2 (ldd,%C0,%C1) CR_TAB AS2 (ldd,__tmp_reg__,%B1) CR_TAB AS2 (ldd,%A0,%A1) CR_TAB AS2 (mov,%B0,__tmp_reg__)); else if (reg_dest == reg_base - 2) return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB AS2 (ldd,%B0,%B1) CR_TAB AS2 (ldd,__tmp_reg__,%C1) CR_TAB AS2 (ldd,%D0,%D1) CR_TAB AS2 (mov,%C0,__tmp_reg__)); return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB AS2 (ldd,%B0,%B1) CR_TAB AS2 (ldd,%C0,%C1) CR_TAB AS2 (ldd,%D0,%D1)); } else if (GET_CODE (base) == PRE_DEC) /* (--R) */ return *l=4, (AS2 (ld,%D0,%1) CR_TAB AS2 (ld,%C0,%1) CR_TAB AS2 (ld,%B0,%1) CR_TAB AS2 (ld,%A0,%1)); else if (GET_CODE (base) == POST_INC) /* (R++) */ return *l=4, (AS2 (ld,%A0,%1) CR_TAB AS2 (ld,%B0,%1) CR_TAB AS2 (ld,%C0,%1) CR_TAB AS2 (ld,%D0,%1)); else if (CONSTANT_ADDRESS_P (base)) return *l=8, (AS2 (lds,%A0,%A1) CR_TAB AS2 (lds,%B0,%B1) CR_TAB AS2 (lds,%C0,%C1) CR_TAB AS2 (lds,%D0,%D1)); fatal_insn ("unknown move insn:",insn); return "";}const char *out_movsi_mr_r (insn, op, l) rtx insn; rtx op[]; int *l;{ rtx dest = op[0]; rtx src = op[1]; rtx base = XEXP (dest, 0); int reg_base = true_regnum (base); int reg_src = true_regnum (src); int tmp; if (!l) l = &tmp; if (CONSTANT_ADDRESS_P (base)) return *l=8,(AS2 (sts,%A0,%A1) CR_TAB AS2 (sts,%B0,%B1) CR_TAB AS2 (sts,%C0,%C1) CR_TAB AS2 (sts,%D0,%D1)); if (reg_base > 0) /* (r) */ { if (reg_base == REG_X) /* (R26) */ { if (reg_src == REG_X) { /* "st X+,r26" is undefined */ if (reg_unused_after (insn, base)) return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB AS2 (st,X,r26) CR_TAB AS2 (adiw,r26,1) CR_TAB AS2 (st,X+,__tmp_reg__) CR_TAB AS2 (st,X+,r28) CR_TAB AS2 (st,X,r29)); else return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB AS2 (st,X,r26) CR_TAB AS2 (adiw,r26,1) CR_TAB AS2 (st,X+,__tmp_reg__) CR_TAB AS2 (st,X+,r28) CR_TAB AS2 (st,X,r29) CR_TAB AS2 (sbiw,r26,3)); } else if (reg_base == reg_src + 2) { if (reg_unused_after (insn, base)) return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB AS2 (mov,__tmp_reg__,%D1) CR_TAB AS2 (st,%0+,%A1) CR_TAB AS2 (st,%0+,%B1) CR_TAB AS2 (st,%0+,__zero_reg__) CR_TAB AS2 (st,%0,__tmp_reg__) CR_TAB AS1 (clr,__zero_reg__)); else return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB AS2 (mov,__tmp_reg__,%D1) CR_TAB AS2 (st,%0+,%A1) CR_TAB AS2 (st,%0+,%B1) CR_TAB AS2 (st,%0+,__zero_reg__) CR_TAB AS2 (st,%0,__tmp_reg__) CR_TAB AS1 (clr,__zero_reg__) CR_TAB AS2 (sbiw,r26,3)); } return *l=5, (AS2 (st,%0+,%A1) CR_TAB AS2 (st,%0+,%B1) CR_TAB AS2 (st,%0+,%C1) CR_TAB AS2 (st,%0,%D1) CR_TAB AS2 (sbiw,r26,3)); } else return *l=4, (AS2 (st,%0,%A1) CR_TAB AS2 (std,%0+1,%B1) CR_TAB AS2 (std,%0+2,%C1) CR_TAB AS2 (std,%0+3,%D1)); } else if (GET_CODE (base) == PLUS) /* (R + i) */ { int disp = INTVAL (XEXP (base, 1)); reg_base = REGNO (XEXP (base, 0)); if (disp > MAX_LD_OFFSET (GET_MODE (dest))) { if (reg_base != REG_Y) fatal_insn ("incorrect insn:",insn); if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB AS2 (std,Y+60,%A1) CR_TAB AS2 (std,Y+61,%B1) CR_TAB AS2 (std,Y+62,%C1) CR_TAB AS2 (std,Y+63,%D1) CR_TAB AS2 (sbiw,r28,%o0-60)); return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB AS2 (sbci,r29,hi8(-%o0)) CR_TAB AS2 (st,Y,%A1) CR_TAB AS2 (std,Y+1,%B1) CR_TAB AS2 (std,Y+2,%C1) CR_TAB AS2 (std,Y+3,%D1) CR_TAB AS2 (subi,r28,lo8(%o0)) CR_TAB AS2 (sbci,r29,hi8(%o0))); } if (reg_base == REG_X) { /* (X + d) = R */ if (reg_src == REG_X) { *l = 9; return (AS2 (mov,__tmp_reg__,r26) CR_TAB AS2 (mov,__zero_reg__,r27) CR_TAB AS2 (adiw,r26,%o0) CR_TAB AS2 (st,X+,__tmp_reg__) CR_TAB AS2 (st,X+,__zero_reg__) CR_TAB AS2 (st,X+,r28) CR_TAB AS2 (st,X,r29) CR_TAB AS1 (clr,__zero_reg__) CR_TAB AS2 (sbiw,r26,%o0+3)); } else if (reg_src == REG_X - 2) { *l = 9; return (AS2 (mov,__tmp_reg__,r26) CR_TAB AS2 (mov,__zero_reg__,r27) CR_TAB AS2 (adiw,r26,%o0) CR_TAB AS2 (st,X+,r24) CR_TAB AS2 (st,X+,r25) CR_TAB AS2 (st,X+,__tmp_reg__) CR_TAB AS2 (st,X,__zero_reg__) CR_TAB AS1 (clr,__zero_reg__) CR_TAB AS2 (sbiw,r26,%o0+3)); } *l = 6; return (AS2 (adiw,r26,%o0) CR_TAB AS2 (st,X+,%A1) CR_TAB AS2 (st,X+,%B1) CR_TAB AS2 (st,X+,%C1) CR_TAB AS2 (st,X,%D1) CR_TAB AS2 (sbiw,r26,%o0+3)); } return *l=4, (AS2 (std,%A0,%A1) CR_TAB AS2 (std,%B0,%B1) CR_TAB AS2 (std,%C0,%C1) CR_TAB AS2 (std,%D0,%D1)); } else if (GET_CODE (base) == PRE_DEC) /* (--R) */ return *l=4, (AS2 (st,%0,%D1) CR_TAB AS2 (st,%0,%C1) CR_TAB AS2 (st,%0,%B1) CR_TAB AS2 (st,%0,%A1)); else if (GET_CODE (base) == POST_INC) /* (R++) */ return *l=4, (AS2 (st,%0,%A1) CR_TAB AS2 (st,%0,%B1) CR_TAB AS2 (st,%0,%C1) CR_TAB AS2 (st,%0,%D1)); fatal_insn ("unknown move insn:",insn); return "";}const char *output_movsisf(insn, operands, l) rtx insn; rtx operands[]; int *l;{ int dummy; rtx dest = operands[0]; rtx src = operands[1]; int *real_l = l; if (!l) l = &dummy; if (register_operand (dest, VOIDmode)) { if (register_operand (src, VOIDmode)) /* mov r,r */ { if (true_regnum (dest) > true_regnum (src)) { if (AVR_ENHANCED) { *l = 2; return (AS2 (movw,%C0,%C1) CR_TAB AS2 (movw,%A0,%A1)); } *l = 4; return (AS2 (mov,%D0,%D1) CR_TAB AS2 (mov,%C0,%C1) CR_TAB AS2 (mov,%B0,%B1) CR_TAB AS2 (mov,%A0,%A1)); } else { if (AVR_ENHANCED) { *l = 2; return (AS2 (movw,%A0,%A1) CR_TAB AS2 (movw,%C0,%C1)); } *l = 4; return (AS2 (mov,%A0,%A1) CR_TAB AS2 (mov,%B0,%B1) CR_TAB AS2 (mov,%C0,%C1) CR_TAB AS2 (mov,%D0,%D1)); } } else if (CONSTANT_P (src)) { if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */ { if (byte_immediate_operand (src, SImode) && reg_was_0 (insn, dest)) { *l = 1; return (AS2 (ldi,%A0,lo8(%1) ; reg_was_0)); } *l = 4; return (AS2 (ldi,%A0,lo8(%1)) CR_TAB AS2 (ldi,%B0,hi8(%1)) CR_TAB AS2 (ldi,%C0,hlo8(%1)) CR_TAB AS2 (ldi,%D0,hhi8(%1))); } if (GET_CODE (src) == CONST_INT) { const char *const clr_op0 = AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB AS1 (clr,%B0) CR_TAB AS2 (movw,%C0,%A0)) : (AS1 (clr,%A0) CR_TAB AS1 (clr,%B0) CR_TAB AS1 (clr,%C0) CR_TAB AS1 (clr,%D0)); if (src == const0_rtx) /* mov r,L */ { *l = AVR_ENHANCED ? 3 : 4; return clr_op0; } else if (src == const1_rtx) { if (reg_was_0 (insn, dest)) { *l = 1; return AS1 (inc,%A0 ; reg_was_0); } if (!real_l) output_asm_insn (clr_op0, operands); *l = AVR_ENHANCED ? 4 : 5; return AS1 (inc,%A0); } else if (src == constm1_rtx) { /* Immediate constants -1 to any register */ if (reg_was_0 (insn, dest)) { if (AVR_ENHANCED) { *l = 3; return (AS1 (dec,%A0) CR_TAB AS1 (dec,%B0) CR_TAB AS2 (movw,%C0,%A0)); } *l = 4; return (AS1 (dec,%D0 ; reg_was_0) CR_TAB AS1 (dec,%C0) CR_TAB AS1 (dec,%B0) CR_TAB AS1 (dec,%A0)); } if (AVR_ENHANCED) { *l = 4; return (AS1 (clr,%A0) CR_TAB AS1 (dec,%A0) CR_TAB AS2 (mov,%B0,%A0) CR_TAB AS2 (movw,%C0,%A0)); } *l = 5; return (AS1 (clr,%A0) CR_TAB AS1 (dec,%A0) CR_TAB AS2 (mov,%B0,%A0) CR_TAB AS2 (mov,%C0,%A0) CR_TAB AS2 (mov,%D0,%A0)); } else { int bit_nr = exact_log2 (INTVAL (src)); if (bit_nr >= 0) { if (reg_was_0 (insn, dest)) { *l = 2; if (!real_l) output_asm_insn ("set ; reg_was_0", operands); } else { *l = AVR_ENHANCED ? 5 : 6; if (!real_l) { output_asm_insn (clr_op0, operands); output_asm_insn ("set", operands); } } if (!real_l) avr_output_bld (operands, bit_nr); return ""; } } } /* Last resort, better than loading from memory. */ *l = 10; return (AS2 (mov,__tmp_reg__,r31) CR_TAB AS2 (ldi,r31,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -