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

📄 arc.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 4 页
字号:
;; Machine description of the Argonaut ARC cpu for GNU C compiler;; Copyright (C) 1994, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.;; 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.;; See file "rtl.def" for documentation on define_insn, match_*, et. al.;; ??? This is an old port, and is undoubtedly suffering from bit rot.;; Insn type.  Used to default other attribute values.(define_attr "type"  "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"  (const_string "binary"));; Length (in # of insns, long immediate constants counted too).;; ??? There's a nasty interaction between the conditional execution fsm;; and insn lengths: insns with shimm values cannot be conditionally executed.(define_attr "length" ""  (cond [(eq_attr "type" "load")	 (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "store")	 (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "move,unary,compare")	 (if_then_else (match_operand 1 "long_immediate_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "binary,mul")	 (if_then_else (match_operand 2 "long_immediate_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "cmove")	 (if_then_else (match_operand 2 "register_operand" "")		       (const_int 1) (const_int 2))	 (eq_attr "type" "multi") (const_int 2)	]	(const_int 1)));; The length here is the length of a single asm.  Unfortunately it might be;; 1 or 2 so we must allow for 2.  That's ok though.  How often will users;; lament asm's not being put in delay slots?(define_asm_attributes  [(set_attr "length" "2")   (set_attr "type" "multi")]);; Condition codes: this one is used by final_prescan_insn to speed up;; conditionalizing instructions.  It saves having to scan the rtl to see if;; it uses or alters the condition codes.;; USE: This insn uses the condition codes (eg: a conditional branch).;; CANUSE: This insn can use the condition codes (for conditional execution).;; SET: All condition codes are set by this insn.;; SET_ZN: the Z and N flags are set by this insn.;; SET_ZNC: the Z, N, and C flags are set by this insn.;; CLOB: The condition codes are set to unknown values by this insn.;; NOCOND: This insn can't use and doesn't affect the condition codes.(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"  (cond [(and (eq_attr "type" "unary,binary,move")	      (eq_attr "length" "1"))	 (const_string "canuse")	 (eq_attr "type" "compare")	 (const_string "set")	 (eq_attr "type" "cmove,branch")	 (const_string "use")	 (eq_attr "type" "multi,misc")	 (const_string "clob")	 ]	 (const_string "nocond")));; Delay slots.(define_attr "in_delay_slot" "false,true"  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")	 (const_string "false")	 ]	 (if_then_else (eq_attr "length" "1")		       (const_string "true")		       (const_string "false"))))(define_delay (eq_attr "type" "call")  [(eq_attr "in_delay_slot" "true")   (eq_attr "in_delay_slot" "true")   (eq_attr "in_delay_slot" "true")])(define_delay (eq_attr "type" "branch,uncond_branch")  [(eq_attr "in_delay_slot" "true")   (eq_attr "in_delay_slot" "true")   (eq_attr "in_delay_slot" "true")])   ;; Function units of the ARC;; (define_function_unit {name} {num-units} {n-users} {test};;                       {ready-delay} {issue-delay} [{conflict-list}]);; 1) A conditional jump cannot immediately follow the insn setting the flags.;; This isn't a complete solution as it doesn't come with guarantees.  That;; is done in the branch patterns and in arc_print_operand.  This exists to;; avoid inserting a nop when we can.(define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")]);; 2) References to loaded registers should wait a cycle.;; Memory with load-delay of 1 (i.e., 2 cycle load).(define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0);; Units that take one cycle do not need to be specified.;; Move instructions.(define_expand "movqi"  [(set (match_operand:QI 0 "general_operand" "")	(match_operand:QI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (QImode, operands[1]);}")(define_insn "*movqi_insn"  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")	(match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))];; ??? Needed?  "register_operand (operands[0], QImode)   || register_operand (operands[1], QImode)"  "@   mov%? %0,%1   mov%? %0,%1   ldb%U1%V1 %0,%1   stb%U0%V0 %1,%0"  [(set_attr "type" "move,move,load,store")]);; ??? This may never match since there's no cmpqi insn.(define_insn "*movqi_set_cc_insn"  [(set (reg:CCZN 61) (compare:CCZN		       (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))		       (const_int 0)))   (set (match_operand:QI 0 "move_dest_operand" "=r")	(match_dup 1))]  ""  "mov%?.f %0,%1"  [(set_attr "type" "move")   (set_attr "cond" "set_zn")])(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (HImode, operands[1]);}")(define_insn "*movhi_insn"  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")	(match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]  "register_operand (operands[0], HImode)   || register_operand (operands[1], HImode)"  "@   mov%? %0,%1   mov%? %0,%1   ldw%U1%V1 %0,%1   stw%U0%V0 %1,%0"  [(set_attr "type" "move,move,load,store")]);; ??? Will this ever match?(define_insn "*movhi_set_cc_insn"  [(set (reg:CCZN 61) (compare:CCZN		       (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))		       (const_int 0)))   (set (match_operand:HI 0 "move_dest_operand" "=r")	(match_dup 1))];; ??? Needed?  "register_operand (operands[0], HImode)   || register_operand (operands[1], HImode)"  "mov%?.f %0,%1"  [(set_attr "type" "move")   (set_attr "cond" "set_zn")])(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (SImode, operands[1]);}")(define_insn "*movsi_insn"  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")	(match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]  "register_operand (operands[0], SImode)   || register_operand (operands[1], SImode)"  "@   mov%? %0,%1   mov%? %0,%S1   ld%U1%V1 %0,%1   st%U0%V0 %1,%0"  [(set_attr "type" "move,move,load,store")])(define_insn "*movsi_set_cc_insn"  [(set (reg:CCZN 61) (compare:CCZN		       (match_operand:SI 1 "move_src_operand" "rIJi")		       (const_int 0)))   (set (match_operand:SI 0 "move_dest_operand" "=r")	(match_dup 1))]  "register_operand (operands[0], SImode)   || register_operand (operands[1], SImode)"  "mov%?.f %0,%S1"  [(set_attr "type" "move")   (set_attr "cond" "set_zn")])(define_expand "movdi"  [(set (match_operand:DI 0 "general_operand" "")	(match_operand:DI 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (DImode, operands[1]);}")(define_insn "*movdi_insn"  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")	(match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]  "register_operand (operands[0], DImode)   || register_operand (operands[1], DImode)"  "*{  switch (which_alternative)    {    case 0 :      /* We normally copy the low-numbered register first.  However, if	 the first register operand 0 is the same as the second register of	 operand 1, we must copy in the opposite order.  */      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)	return \"mov %R0,%R1\;mov %0,%1\";      else	return \"mov %0,%1\;mov %R0,%R1\";    case 1 :      return \"mov %0,%L1\;mov %R0,%H1\";    case 2 :      /* If the low-address word is used in the address, we must load it	 last.  Otherwise, load it first.  Note that we cannot have	 auto-increment in that case since the address register is known to be	 dead.  */      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,			     operands [1], 0))	  return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";      else	  return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";    case 3 :      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";    default:      abort();    }}"  [(set_attr "type" "move,move,load,store")   ;; ??? The ld/st values could be 4 if it's [reg,bignum].   (set_attr "length" "2,4,2,2")]);(define_expand "movdi";  [(set (match_operand:DI 0 "general_operand" "");	(match_operand:DI 1 "general_operand" ""))];  "";  ";{;  /* Flow doesn't understand that this is effectively a DFmode move.;     It doesn't know that all of `operands[0]' is set.  */;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));;;  /* Emit insns that movsi_insn can handle.  */;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),;			operand_subword (operands[1], 0, 0, DImode)));;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),;			operand_subword (operands[1], 1, 0, DImode)));;  DONE;;}");; Floating point move insns.(define_expand "movsf"  [(set (match_operand:SF 0 "general_operand" "")	(match_operand:SF 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (SFmode, operands[1]);}")(define_insn "*movsf_insn"  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")	(match_operand:SF 1 "move_src_operand" "r,E,m,r"))]  "register_operand (operands[0], SFmode)   || register_operand (operands[1], SFmode)"  "@   mov%? %0,%1   mov%? %0,%1 ; %A1   ld%U1%V1 %0,%1   st%U0%V0 %1,%0"  [(set_attr "type" "move,move,load,store")])(define_expand "movdf"  [(set (match_operand:DF 0 "general_operand" "")	(match_operand:DF 1 "general_operand" ""))]  ""  "{  /* Everything except mem = const or mem = mem can be done easily.  */  if (GET_CODE (operands[0]) == MEM)    operands[1] = force_reg (DFmode, operands[1]);}")(define_insn "*movdf_insn"  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")	(match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]  "register_operand (operands[0], DFmode)   || register_operand (operands[1], DFmode)"  "*{  switch (which_alternative)    {    case 0 :      /* We normally copy the low-numbered register first.  However, if	 the first register operand 0 is the same as the second register of	 operand 1, we must copy in the opposite order.  */      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)	return \"mov %R0,%R1\;mov %0,%1\";      else	return \"mov %0,%1\;mov %R0,%R1\";    case 1 :      return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";    case 2 :      /* If the low-address word is used in the address, we must load it	 last.  Otherwise, load it first.  Note that we cannot have	 auto-increment in that case since the address register is known to be	 dead.  */      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,			     operands [1], 0))	return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";      else	return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";    case 3 :      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";    default:      abort();    }}"  [(set_attr "type" "move,move,load,store")   ;; ??? The ld/st values could be 4 if it's [reg,bignum].   (set_attr "length" "2,4,2,2")]);(define_expand "movdf";  [(set (match_operand:DF 0 "general_operand" "");	(match_operand:DF 1 "general_operand" ""))];  "";  ";{;  /* Flow doesn't understand that this is effectively a DFmode move.;     It doesn't know that all of `operands[0]' is set.  */;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));;;  /* Emit insns that movsi_insn can handle.  */;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),;			operand_subword (operands[1], 0, 0, DFmode)));;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),;			operand_subword (operands[1], 1, 0, DFmode)));

⌨️ 快捷键说明

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