⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avr.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; -*- Mode: Scheme -*-;;   Machine description for GNU compiler,;;   for ATMEL AVR micro controllers.;;   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.;;   Contributed by Denis Chertykov (denisc@overta.ru);; This file is part of GNU CC.;; GNU CC is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 2, or (at your option);; any later version.;; GNU CC is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU CC; see the file COPYING.  If not, write to;; the Free Software Foundation, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;; Special characters after '%':;;  A  No effect (add 0).;;  B  Add 1 to REG number, MEM address or CONST_INT.;;  C  Add 2.;;  D  Add 3.;;  j  Branch condition.;;  k  Reverse branch condition.;;  o  Displacement for (mem (plus (reg) (const_int))) operands.;;  ~  Output 'r' if not AVR_MEGA.;; UNSPEC usage:;;  0  Length of a string, see "strlenhi".;;  1  Read from a word address in program memory, see "casesi".;; Condition code settings.(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"  (const_string "none"))(define_attr "type" "branch,branch1,arith,xcall"  (const_string "arith"))(define_attr "mcu_enhanced" "yes,no"  (const (if_then_else (symbol_ref "AVR_ENHANCED")		       (const_string "yes")		       (const_string "no"))))(define_attr "mcu_mega" "yes,no"  (const (if_then_else (symbol_ref "AVR_MEGA")		       (const_string "yes")		       (const_string "no"))))  ;; The size of instructions in bytes.;; XXX may depend from "cc"(define_attr "length" ""  (cond [(eq_attr "type" "branch")         (if_then_else (and (ge (minus (pc) (match_dup 0))                                (const_int -63))                            (le (minus (pc) (match_dup 0))                                (const_int 62)))                       (const_int 1)                       (if_then_else (and (ge (minus (pc) (match_dup 0))                                              (const_int -2045))                                          (le (minus (pc) (match_dup 0))                                              (const_int 2045)))                                     (const_int 2)                                     (const_int 3)))         (eq_attr "type" "branch1")         (if_then_else (and (ge (minus (pc) (match_dup 0))                                (const_int -62))                            (le (minus (pc) (match_dup 0))                                (const_int 61)))                       (const_int 2)                       (if_then_else (and (ge (minus (pc) (match_dup 0))                                              (const_int -2044))                                          (le (minus (pc) (match_dup 0))                                              (const_int 2043)))                                     (const_int 3)                                     (const_int 4)))	 (eq_attr "type" "xcall")	 (if_then_else (eq_attr "mcu_mega" "no")		       (const_int 1)		       (const_int 2))]        (const_int 2)))(define_insn "*pop1"  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 1)))]  ""  "pop __tmp_reg__"  [(set_attr "length" "1")])(define_insn "*pop2"  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 2)))]  ""  "pop __tmp_reg__	pop __tmp_reg__"  [(set_attr "length" "2")])(define_insn "*pop3"  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 3)))]  ""  "pop __tmp_reg__	pop __tmp_reg__ 	pop __tmp_reg__"  [(set_attr "length" "3")])(define_insn "*pop4"  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 4)))]  ""  "pop __tmp_reg__	pop __tmp_reg__	pop __tmp_reg__	pop __tmp_reg__"  [(set_attr "length" "4")])(define_insn "*pop5"  [(set (reg:HI 32) (plus:HI (reg:HI 32) (const_int 5)))]  ""  "pop __tmp_reg__	pop __tmp_reg__	pop __tmp_reg__	pop __tmp_reg__	pop __tmp_reg__"  [(set_attr "length" "5")])(define_insn "*pushqi"  [(set (mem:QI (post_dec (reg:HI 32)))        (match_operand:QI 0 "nonmemory_operand" "r,L"))]  "(operands[0] == const0_rtx || register_operand (operands[0], QImode))"  "@	push %0	push __zero_reg__"  [(set_attr "length" "1,1")])(define_insn "*pushhi"  [(set (mem:HI (post_dec (reg:HI 32)))        (match_operand:HI 0 "nonmemory_operand" "r,L"))]  "(operands[0] == const0_rtx || register_operand (operands[0], HImode))"  "@	push %B0\;push %A0	push __zero_reg__\;push __zero_reg__"  [(set_attr "length" "2,2")])(define_insn "*pushsi"  [(set (mem:SI (post_dec (reg:HI 32)))        (match_operand:SI 0 "nonmemory_operand" "r,L"))]  "(operands[0] == const0_rtx || register_operand (operands[0], SImode))"  "@	push %D0\;push %C0\;push %B0\;push %A0	push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"  [(set_attr "length" "4,4")])(define_insn "*pushsf"  [(set (mem:SF (post_dec (reg:HI 32)))        (match_operand:SF 0 "register_operand" "r"))]  ""  "push %D0	push %C0	push %B0	push %A0"  [(set_attr "length" "4")]);;========================================================================;; move byte;; The last alternative (any immediate constant to any register) is;; very expensive.  It should be optimized by peephole2 if a scratch;; register is available, but then that register could just as well be;; allocated for the variable we are loading.  But, most of NO_LD_REGS;; are call-saved registers, and most of LD_REGS are call-used registers,;; so this may still be a win for registers live across function calls.(define_expand "movqi"  [(set (match_operand:QI 0 "nonimmediate_operand" "")	(match_operand:QI 1 "general_operand" ""))]  ""  "/* One of the ops has to be in a register */   if (!register_operand(operand0, QImode)       && ! (register_operand(operand1, QImode) || const0_rtx == operand1))       operands[1] = copy_to_mode_reg(QImode, operand1);  ")(define_insn "*movqi"  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")	(match_operand:QI 1 "general_operand"       "r,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 "cc" "none,none,clobber,clobber,none,none,clobber")]);; This is used in peephole2 to optimize loading immediate constants;; if a scratch register from LD_REGS happens to be available.(define_insn "*reload_inqi"  [(set (match_operand:QI 0 "register_operand" "=l")	(match_operand:QI 1 "immediate_operand" "i"))   (clobber (match_operand:QI 2 "register_operand" "=&d"))]  "reload_completed"  "ldi %2,lo8(%1)	mov %0,%2"  [(set_attr "length" "2")   (set_attr "cc" "none")])(define_peephole2  [(match_scratch:QI 2 "d")   (set (match_operand:QI 0 "register_operand" "")	(match_operand:QI 1 "immediate_operand" ""))]  "(operands[1] != const0_rtx    && test_hard_reg_class (NO_LD_REGS, operands[0]))"  [(parallel [(set (match_dup 0) (match_dup 1))	      (clobber (match_dup 2))])]  "if (!avr_peep2_scratch_safe (operands[2]))     FAIL;");;============================================================================;; move word (16 bit)(define_expand "movhi"  [(set (match_operand:HI 0 "nonimmediate_operand" "")        (match_operand:HI 1 "general_operand"       ""))]  ""  "{   /* One of the ops has to be in a register */  if (!register_operand(operand0, HImode)      && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))    {      operands[1] = copy_to_mode_reg(HImode, operand1);    }}")(define_peephole2  [(match_scratch:QI 2 "d")   (set (match_operand:HI 0 "register_operand" "")       (match_operand:HI 1 "immediate_operand" ""))]  "(operands[1] != const0_rtx    && test_hard_reg_class (NO_LD_REGS, operands[0]))"  [(parallel [(set (match_dup 0) (match_dup 1))	      (clobber (match_dup 2))])]  "if (!avr_peep2_scratch_safe (operands[2]))     FAIL;");; '*' because it is not used in rtl generation, only in above peephole(define_insn "*reload_inhi"  [(set (match_operand:HI 0 "register_operand" "=r")        (match_operand:HI 1 "immediate_operand" "i"))   (clobber (match_operand:QI 2 "register_operand" "=&d"))]  "reload_completed"  "* return output_reload_inhi (insn, operands, NULL);"  [(set_attr "length" "4")   (set_attr "cc" "none")])(define_insn "*movhi"  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")        (match_operand:HI 1 "general_operand"       "r,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,6,7,2,6,5,2")   (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")]);;==========================================================================;; move double word (32 bit)(define_expand "movsi"  [(set (match_operand:SI 0 "nonimmediate_operand" "")        (match_operand:SI 1 "general_operand"  ""))]  ""  "{  /* One of the ops has to be in a register.  */  if (!register_operand (operand0, SImode)      && !(register_operand (operand1, SImode) || const0_rtx == operand1))    {      operands[1] = copy_to_mode_reg (SImode, operand1);    }}")(define_peephole2  [(match_scratch:QI 2 "d")   (set (match_operand:SI 0 "register_operand" "")       (match_operand:SI 1 "immediate_operand" ""))]  "(operands[1] != const0_rtx    && test_hard_reg_class (NO_LD_REGS, operands[0]))"  [(parallel [(set (match_dup 0) (match_dup 1))	      (clobber (match_dup 2))])]  "if (!avr_peep2_scratch_safe (operands[2]))     FAIL;");; '*' because it is not used in rtl generation.(define_insn "*reload_insi"  [(set (match_operand:SI 0 "register_operand" "=r")        (match_operand:SI 1 "immediate_operand" "i"))   (clobber (match_operand:QI 2 "register_operand" "=&d"))]  "reload_completed"  "* return output_reload_insisf (insn, operands, NULL);"  [(set_attr "length" "8")   (set_attr "cc" "none")])(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])"  "* return output_movsisf (insn, operands, NULL);"  [(set_attr "length" "4,4,8,9,4,10")   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")]);; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;; move floating point numbers (32 bit)(define_expand "movsf"  [(set (match_operand:SF 0 "nonimmediate_operand" "")        (match_operand:SF 1 "general_operand"  ""))]  ""  "{  /* One of the ops has to be in a register.  */  if (!register_operand (operand1, SFmode)      && !register_operand (operand0, SFmode))    {      operands[1] = copy_to_mode_reg (SFmode, operand1);    }}")(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,r,F,F"))]  "register_operand (operands[0], SFmode)   || register_operand (operands[1], SFmode)"  "* return output_movsisf (insn, operands, NULL);"  [(set_attr "length" "4,4,8,9,4,10")   (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")]);;=========================================================================;; move string (like memcpy)(define_expand "movstrhi"  [(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" ""))	      (clobber (match_dup 4))	      (clobber (match_dup 5))	      (clobber (match_dup 6))])]  ""  "{  rtx addr0, addr1;  int cnt8;  enum machine_mode mode;  if (GET_CODE (operands[2]) != CONST_INT)    FAIL;  cnt8 = byte_immediate_operand (operands[2], GET_MODE (operands[2]));  mode = cnt8 ? QImode : HImode;  operands[2] = copy_to_mode_reg (mode,                                  gen_int_mode (INTVAL (operands[2]), mode));  operands[4] = operands[2];  addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));  operands[5] = addr0;  operands[6] = addr1;  operands[0] = gen_rtx (MEM, BLKmode, addr0);  operands[1] = gen_rtx (MEM, BLKmode, addr1);}")(define_insn "*movstrqi_insn"  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))	(mem:BLK (match_operand:HI 1 "register_operand" "e")))   (use (match_operand:QI 2 "register_operand" "r"))   (use (match_operand:QI 3 "const_int_operand" "i"))   (clobber (match_dup 2))   (clobber (match_dup 0))   (clobber (match_dup 1))]  ""  "ld __tmp_reg__,%a1+	st %a0+,__tmp_reg__	dec %2	brne .-8"  [(set_attr "length" "4")   (set_attr "cc" "clobber")])(define_insn "*movstrhi"  [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))	(mem:BLK (match_operand:HI 1 "register_operand" "e,e")))   (use (match_operand:HI 2 "register_operand" "!w,d"))   (use (match_operand:HI 3 "const_int_operand" ""))   (clobber (match_dup 2))   (clobber (match_dup 0))   (clobber (match_dup 1))]  ""  "*{     if (which_alternative==0)       return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB	       AS2 (st,%a0+,__tmp_reg__)  CR_TAB	       AS2 (sbiw,%A2,1) CR_TAB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -