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

📄 m68hc11.md

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description file for Motorola 68HC11 and 68HC12.;;- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.;;- Contributed by Stephane Carrez (stcarrez@nerim.fr);; 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.;; Note:;;   A first 68HC11 port was made by Otto Lind (otto@coactive.com);;   on gcc 2.6.3.  I have used it as a starting point for this port.;;   However, this new port is a complete re-write.  Its internal;;   design is completely different.  The generated code is not;;   compatible with the gcc 2.6.3 port.;;;;   The gcc 2.6.3 port is available at:;;;;   ftp.unina.it/pub/electronics/motorola/68hc11/gcc/gcc-6811-fsf.tar.gz;;;;- Instruction patterns.  When multiple patterns apply,;;- the first one in the file is chosen.;;-;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;;-;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;;; The following constraints are used:;;;; Single pair registers:;; a    register 'a'			 8-bit;; b    register 'b'			 8-bit;; d    register 'd'			16-bit;; t    pseudo soft register 'TMP'      16-bit;; v    register 'd' for 68hc11,	16-bit;;      NO_REG for 68hc12;;      (used for scratch register);; w    register 'sp'			16-bit ;; x    register 'x'			16-bit;; y    register 'y'			16-bit;; z    register 'z'			16-bit  (fake r for 68HC11 and 68HC12);; D    register 'd+x'			32-bit ;;;; Group of registers:;; q    register 'a' or 'b' or 'd'	 8-bit;; u    pseudo soft register		16-bit;; A    register 'x', 'y', 'z'		16-bit;; B    register 'x', 'y'               16-bit;; h	register 'd', 'x', 'y', 'z'	16-bit;;;; Other constraints:;;;; Q    an operand which is in memory but whose address is constant;;      (ie, a (MEM (SYMBOL_REF x))).  This constraint is used by;;      bset/bclr instructions together with linker relaxation.  The;;      operand can be translated to a page0 addressing mode if the;;      symbol address is in page0 (0..255).;;;; R    an operand which is in memory and whose address is expressed;;      with 68HC11/68HC12 indexed addressing mode.  In general this;;      is any valid (MEM) except a (MEM (SYMBOL_REF x)).;;;; U    an operand which is in memory and if it uses the 68HC12 indexed;;      addressing mode, the offset is in the range -16..+15.  This is;;      used by 68HC12 movb/movw instructions since they do not accept;;      the full 16-bit offset range (as other insn do).;;;;;; Immediate integer operand constraints:;;   `L' is for range -65536 to 65536;;   `M' is for values whose 16-bit low part is 0;;   'N' is for +1 or -1.;;   'O' is for 16 (for rotate using swap).;;   'P' is for range -8 to 2 (used by addhi_sp);;;; In many cases, it's not possible to use the 'g' or 'r' constraints.;;;; Operands modifiers:;;;;     %b	Get the low part of the operand (to obtain a QImode);;		This modified must always be used for QImode operations;;		because a correction must be applied when the operand;;		is a soft register (ex: *ZD1). Otherwise, we generate;;		*ZD1 and this is the high part of the register. For other;;		kinds of operands, if the operand is already QImode, no;;		additional correction is made.;;     %h	Get the high part of the operand (to obtain a QImode);;     %t	Represents the temporary/scratch register *_.tmp;;		The scratch register is used in some cases when GCC puts;;		some values in bad registers. ;;;; 32/64-bit Patterns:;;     The 68HC11 does not support 32/64-bit operations.  Most of the;;     32/64-bit patterns are defined to split the instruction in;;     16-bits patterns.  Providing split patterns generates better code;;     than letting GCC implement the 32/64-bit operation itself.;;;;;; Notes:;;;; o For iorqi3, andqi3, xorqi3 patterns, we must accept the 'A' constraint;;   otherwise some insn are not satisfied.;;;; o Split patterns that create a swap_areg pattern (xgdx or xgdy) must;;   be valid only when z_replacement_completed == 2 because once these;;   swap instructions are generated, a flow/cse pass fails to handle;;   them correctly (it would treat the X, Y or D register as dead sometimes).;;;; o Some split pattern generate instructions that operate on 'a' or 'b';;   register directly (high part and low part of D respectively).;;   Such split pattern must also be valid when z_replacement_completed == 2;;   because flow/cse is not aware that D is composed of {a, b}.;;;; o Split patterns that generate a (mem:QI (symbol_reg _.dx)) to access;;   the high part of a soft register must be expanded after z_replacement;;   pass.;;;;---------------------------------------------------------------------------;; Constants(define_constants [   ;; Register numbers   (X_REGNUM	    0)		; Index X register   (D_REGNUM	    1)		; Data register   (Y_REGNUM        2)		; Index Y register   (SP_REGNUM       3)          ; Stack pointer   (PC_REGNUM	    4)		; Program counter   (A_REGNUM        5)		; A (high part of D)   (B_REGNUM        6)		; B (low part of D)   (CC_REGNUM       7)		; Condition code register   (SOFT_Z_REGNUM  11)          ; Z soft register]);;--------------------------------------------------------------------;;-  Test;;--------------------------------------------------------------------;;;; The test and compare insn must not accept a memory operand with;; an auto-inc mode.  If we do this, the reload can emit move insns;; after the test or compare.  Such move will set the flags and therefore;; break the comparison.  This can happen if the auto-inc register;; does not happen to be a hard register (ie, reloading occurs).;; An offsetable memory operand should be ok.  The 'tst_operand' and;; 'cmp_operand' predicates take care of this rule.;;(define_expand "tstsi"  [(set (cc0)	(match_operand:SI 0 "tst_operand" ""))]  ""  "{  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = const0_rtx;  DONE;}")(define_expand "tsthi"  [(set (cc0)	(match_operand:HI 0 "tst_operand" ""))]  ""  "{  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = const0_rtx;  DONE;}")(define_insn "tsthi_1"  [(set (cc0)	(match_operand:HI 0 "tst_operand" "dx,*y"))]  ""  "*{   if (D_REG_P (operands[0]) && !TARGET_M6812)     return \"std\\t%t0\";   else     return \"cp%0\\t#0\";}")(define_expand "tstqi"  [(set (cc0)	(match_operand:QI 0 "tst_operand" ""))]  ""  "{  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = const0_rtx;  DONE;}");;;; Split pattern for (tst:QI) on an address register.;;(define_split  [(set (cc0)	(match_operand:QI 0 "hard_addr_reg_operand" ""))]  "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"  [(parallel [(set (reg:HI D_REGNUM) (match_dup 1))	      (set (match_dup 1) (reg:HI D_REGNUM))])   (set (cc0) (reg:QI D_REGNUM))   (parallel [(set (reg:HI D_REGNUM) (match_dup 1))	      (set (match_dup 1) (reg:HI D_REGNUM))])]  "operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]));")(define_insn "tstqi_1"  [(set (cc0)	(match_operand:QI 0 "tst_operand" "m,d,*A,!u"))]  ""  "*{  if (A_REG_P (operands[0]))    return \"#\";  else if (D_REG_P (operands[0]))    return \"tstb\";  else if (dead_register_here (insn, d_reg))    return \"ldab\\t%b0\";  else    return \"tst\\t%b0\";}");;;; tstqi_z_used, cmpqi_z_used and cmphi_z_used are patterns generated ;; during the Z register replacement.  They are used when an operand;; uses the Z register as an index register (ie, (MEM:QI (REG:HI Z))).;; In that case, we have to preserve the values of the replacement;; register (as well as the CC0 since the insns are compare insns).;; To do this, the replacement register is pushed on the stack and;; restored after the real compare.  A pattern+split is defined to;; avoid problems with the flow+cse register pass which are made;; after Z register replacement.;;(define_insn "tstqi_z_used"  [(set (cc0)	(match_operand:QI 0 "tst_operand" "m"))   (use (match_operand:HI 1 "hard_reg_operand" "dxy"))   (use (reg:HI 11))]  ""  "#")(define_split /* "tstqi_z_used" */  [(set (cc0)	(match_operand:QI 0 "tst_operand" ""))   (use (match_operand:HI 1 "hard_reg_operand" ""))   (use (reg:HI SOFT_Z_REGNUM))]  "z_replacement_completed == 2"  [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))   (set (match_dup 1) (match_dup 2))   (set (cc0) (match_dup 0))   (set (match_dup 1) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]  "operands[2] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);");;--------------------------------------------------------------------;;- Compare;;--------------------------------------------------------------------(define_expand "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "tst_operand" "")		 (match_operand:SI 1 "cmp_operand" "")))]  ""  "{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    operands[0] = force_reg (SImode, operands[0]);  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = operands[1];  DONE;}");;;; Comparison of a hard register with another one is provided because;; it helps GCC to avoid to spill a pseudo hard register.;; We use a temporary in page 0, this is equivalent to a pseudo hard reg.;; (except that we loose the information that the value is saved in it).;;;; The split pattern transforms the comparison into a save of one hard;; register and a comparison with the temporary.;;(define_split  [(set (cc0)	(compare (match_operand:HI 0 "hard_reg_operand" "")		 (match_operand:HI 1 "hard_reg_operand" "")))]  "reload_completed"  [(set (match_dup 2) (match_dup 1))   (set (cc0)        (compare (match_dup 0) (match_dup 2)))]  "operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);")(define_expand "cmphi"  [(set (cc0)	(compare (match_operand:HI 0 "tst_operand" "")		 (match_operand:HI 1 "cmp_operand" "")))]  ""  "{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    operands[0] = force_reg (HImode, operands[0]);  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = operands[1];  DONE;}")(define_insn "cmphi_1_hc12"  [(set (cc0)	(compare (match_operand:HI 0 "tst_operand" 				"d,?xy,xyd,?xy,d,m,!u,dxy,dxy")		 (match_operand:HI 1 "cmp_operand"				"i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]  "TARGET_M6812"  "*{  if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))    {      cc_status.flags |= CC_REVERSED;      return \"cp%1\\t%0\";    }  else if (H_REG_P (operands[1]))    return \"#\";  else    return \"cp%0\\t%1\";}")(define_insn "cmphi_1_hc11"  [(set (cc0)	(compare (match_operand:HI 0 "tst_operand" 				"dx,y,xyd,?xy,d,m,!u,dxy,dxy")		 (match_operand:HI 1 "cmp_operand"				"i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]  "TARGET_M6811"  "*{  if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))    {      cc_status.flags |= CC_REVERSED;      return \"cp%1\\t%0\";    }  else if (H_REG_P (operands[1]))    return \"#\";  else    return \"cp%0\\t%1\";}")(define_insn "cmphi_z_used"  [(set (cc0)	(compare (match_operand:HI 0 "tst_operand" "dxy,m")		 (match_operand:HI 1 "cmp_operand" "m,dxy")))   (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))   (use (reg:HI SOFT_Z_REGNUM))]  ""  "#")  (define_split /* "cmphi_z_used" */  [(set (cc0)	(compare (match_operand:HI 0 "tst_operand" "")		 (match_operand:HI 1 "cmp_operand" "")))   (use (match_operand:HI 2 "hard_reg_operand" ""))   (use (reg:HI SOFT_Z_REGNUM))]  "z_replacement_completed == 2"  [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))   (set (match_dup 2) (match_dup 3))   (set (cc0) (compare (match_dup 0) (match_dup 1)))   (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]  "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);");;;; 8-bit comparison with address register.;; There is no such comparison instruction, we have to temporarily switch;; the address register and the D register and do the comparison with D.;; The xgdx and xgdy instructions preserve the flags.;;(define_split  [(set (cc0)	(compare (match_operand:QI 0 "hard_addr_reg_operand" "")		 (match_operand:QI 1 "cmp_operand" "")))]  "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"  [(parallel [(set (reg:HI D_REGNUM) (match_dup 3))              (set (match_dup 3) (reg:HI D_REGNUM))])   (set (cc0)        (compare (reg:QI D_REGNUM) (match_dup 1)))   (parallel [(set (reg:HI D_REGNUM) (match_dup 3))              (set (match_dup 3) (reg:HI D_REGNUM))])]  "operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));")(define_split  [(set (cc0)	(compare (match_operand:QI 0 "hard_reg_operand" "")		 (match_operand:QI 1 "hard_reg_operand" "")))]  "reload_completed"  [(set (match_dup 3) (match_dup 4))   (set (cc0)        (compare (match_dup 0) (match_dup 2)))]  "operands[2] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);   operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);   operands[4] = gen_rtx (REG, HImode, REGNO (operands[1]));")(define_expand "cmpqi"  [(set (cc0)	(compare (match_operand:QI 0 "tst_operand" "")		 (match_operand:QI 1 "cmp_operand" "")))]  ""  "{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    operands[0] = force_reg (QImode, operands[0]);  m68hc11_compare_op0 = operands[0];  m68hc11_compare_op1 = operands[1];  DONE;}")(define_insn "bitcmpqi"  [(set (cc0)	(and:QI (match_operand:QI 0 "tst_operand" "d,d,d,m,!u")	        (match_operand:QI 1 "cmp_operand" "im,*B,u,d,d")))]  ""  "@   bitb\\t%b1   #   bitb\\t%b1   bitb\\t%b0   bitb\\t%b0")

⌨️ 快捷键说明

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