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

📄 clipper.md

📁 gcc编译工具没有什么特别
💻 MD
📖 第 1 页 / 共 3 页
字号:
;;- Machine description for GNU compiler, Clipper Version;;   Copyright (C) 1987, 88, 91, 93, 94, 1997 Free Software Foundation, Inc.;; Contributed by Holger Teutsch (holger@hotbso.rhein-main.de);; 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.;;- 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.;;;; define attributes;;;; instruction type;;;; unknown is temporary in order to generate 'cc clobber' until attribute;; assignment is consistent;;(define_attr "type" "load,store,arith,fp,branch,unknown" (const_string "unknown"));; condition code setting;;;; clobber	destroyed;; unchanged;; set1		set cc_status.value1, e.g. sub r0,r1;; set2		set value1 and value2, e.g. mov r0,r1;; change0	may be side effect, i.e. load mem,r0;;;; note: loadi and loadq are 'arith' instructions that set the condition codes;;       mul,div,mod do NOT set the condition codes;;(define_attr "cc" "clobber,unchanged,set1,set2,change0" (cond [(eq_attr "type" "load")	(const_string "change0")	(eq_attr "type" "store,branch") (const_string "unchanged")	(eq_attr "type" "arith") (if_then_else (match_operand:SI 0 "" "")				  (const_string "set1")				  (const_string "clobber"))	]  (const_string "clobber")));;;; clipper seems to be a traditional risc processor;; we define a functional unit 'memory';;(define_function_unit "memory" 1 1 (eq_attr "type" "load") 4 0)     ;; We don't want to allow a constant operand for test insns because;; (set (cc0) (const_int foo)) has no mode information.  Such insns will;; be folded while optimizing anyway.(define_insn "tstsi"  [(set (cc0)	(match_operand:SI 0 "int_reg_operand" "r"))]  ""  "cmpq   $0,%0")(define_insn "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "nonimmediate_operand" "r,r,n")		 (match_operand:SI 1 "nonmemory_operand" "r,n,r")))]  ""  "*{  int val;  if (which_alternative == 0)    return \"cmpw   %1,%0\";  if (which_alternative == 1)    {      val = INTVAL (operands[1]);      if (0 <= val && val < 16)	return \"cmpq   %1,%0\";      return \"cmpi   %1,%0\";    }  cc_status.flags |= CC_REVERSED;	/* immediate must be first */  val = INTVAL (operands[0]);  if (0 <= val && val < 16)    return \"cmpq   %0,%1\";  return \"cmpi   %0,%1\";}")(define_insn "cmpdf"  [(set (cc0)	(compare (match_operand:DF 0 "fp_reg_operand" "f")		 (match_operand:DF 1 "fp_reg_operand" "f")))]  ""  "cmpd   %1,%0")(define_insn "cmpsf"  [(set (cc0)	(compare (match_operand:SF 0 "fp_reg_operand" "f")		 (match_operand:SF 1 "fp_reg_operand" "f")))]  ""  "cmps   %1,%0");;;; double and single float move;;(define_expand "movdf"  [(set (match_operand:DF 0 "general_operand" "")	(match_operand:DF 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM)    {      if (GET_CODE (operands[1]) == CONST_DOUBLE)	operands[1] = force_reg (DFmode,				 force_const_mem (DFmode, operands[1]));      else if (GET_CODE (operands[1]) != REG)	operands[1] = force_reg (DFmode, operands[1]);    }  else if (GET_CODE (operands[1]) == CONST_DOUBLE)    operands[1] = force_const_mem (DFmode, operands[1]);}");;;; provide two patterns with different predicates as we don't want combine;; to recombine a mem -> mem move;; (define_insn ""  [(set (match_operand:DF 0 "register_operand" "=*rf")	(match_operand:DF 1 "nonimmediate_operand" "*rfo"))]  ""  "*{#define FP_REG_P(X) (GET_CODE (X) == REG && REGNO (X) >= 16)  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	/* f -> f */	return \"movd   %1,%0\";      if (GET_CODE (operands[1]) == REG) /* r -> f */	return \"movld  %1,%0\";      return \"loadd  %1,%0\";		/* m -> f */    }  if (FP_REG_P (operands[1]))    {      if (GET_CODE (operands[0]) == REG) /* f -> r */	return \"movdl  %1,%0\";      abort ();    }  if (GET_CODE (operands[1]) == MEM)	/* m -> r */    {      rtx xops[4];      xops[0] = operands[0];      xops[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);      xops[2] = operands[1];      xops[3] = adj_offsettable_operand (operands[1], 4);      output_asm_insn (\"loadw  %2,%0\;loadw  %3,%1\", xops);      return \"\";    }  if (GET_CODE (operands[1]) == REG)	/* r -> r */    {      rtx xops[4];      xops[0] = operands[0];      xops[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);      xops[2] = operands[1];      xops[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);      output_asm_insn (\"movw   %2,%0\;movw   %3,%1\", xops);      return \"\";    }  abort ();#undef FP_REG_P}")(define_insn ""  [(set (match_operand:DF 0 "memory_operand" "=o,m")	(match_operand:DF 1 "register_operand" "*rf,f"))]  ""  "*{  rtx xops[4];  if (REGNO (operands[1]) >= 16)	/* f -> m */    return \"stord  %1,%0\";  xops[0] = operands[0];		/* r -> o */  xops[1] = adj_offsettable_operand (operands[0], 4);  xops[2] = operands[1];  xops[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);  output_asm_insn (\"storw  %2,%0\;storw  %3,%1\", xops);  return \"\";}"[(set_attr "type" "store,store") (set_attr "cc" "clobber,unchanged")])(define_expand "movsf"  [(set (match_operand:SF 0 "general_operand" "")	(match_operand:SF 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM)    {      if (GET_CODE (operands[1]) == CONST_DOUBLE)	operands[1] = force_reg (SFmode,				 force_const_mem (SFmode, operands[1]));      else if (GET_CODE (operands[1]) != REG)	operands[1] = force_reg (SFmode, operands[1]);    }  else if (GET_CODE (operands[1]) == CONST_DOUBLE)    operands[1] = force_const_mem (SFmode, operands[1]);}");;;; provide two patterns with different predicates as we don't want combine;; to recombine a mem -> mem move;; (define_insn ""  [(set (match_operand:SF 0 "register_operand" "=*rf")	(match_operand:SF 1 "nonimmediate_operand" "*rfm"))]  ""  "*{#define FP_REG_P(X) (GET_CODE (X) == REG && REGNO (X) >= 16)  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	/* f -> f */	return \"movs   %1,%0\";      if (GET_CODE (operands[1]) == REG) /* r -> f */	return	  \"subq   $8,sp\;storw  %1,(sp)\;loads  (sp),%0\;addq   $8,sp\";      return \"loads  %1,%0\";		/* m -> f */    }  if (FP_REG_P (operands[1]))    {      if (GET_CODE (operands[0]) == REG) /* f -> r */	return	  \"subq   $8,sp\;stors  %1,(sp)\;loadw  (sp),%0\;addq   $8,sp\";      abort ();    }  if (GET_CODE (operands[1]) == MEM)	/* m -> r */    return \"loadw   %1,%0\";  if (GET_CODE (operands[1]) == REG)	/* r -> r */    return \"movw    %1,%0\";  abort ();#undef FP_REG_P}")(define_insn ""  [(set (match_operand:SF 0 "memory_operand" "=m")	(match_operand:SF 1 "register_operand" "*rf"))]  ""  "*{  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) >= 16)    return \"stors  %1,%0\";		/* f-> m */  return \"storw   %1,%0\";		/* r -> m */}"[(set_attr "type" "store")])(define_expand "movdi"  [(set (match_operand:DI 0 "general_operand" "")	(match_operand:DI 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) != REG)    operands[1] = force_reg (DImode, operands[1]);}");; If an operand is a MEM but not offsettable, we can't load it into;; a register, so we must force the third alternative to be the one;; reloaded.  Hence we show the first as more expensive.(define_insn ""  [(set (match_operand:DI 0 "register_operand" "=?r,r,r")	(match_operand:DI 1 "general_operand"   "r,n,o"))]  ""  "*{  rtx xoperands[2],yoperands[2];  xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);  if (which_alternative == 0)		/* r -> r */    {      output_asm_insn (\"movw   %1,%0\", operands);      xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);      output_asm_insn (\"movw   %1,%0\", xoperands);      return \"\";    }  if (which_alternative == 1)		/* n -> r */    {      if (GET_CODE (operands[1]) == CONST_INT)	{	  output_asm_insn (\"loadi   %1,%0\", operands);	  output_asm_insn (\"loadq   $0,%0\", xoperands);	  return \"\";	}      if (GET_CODE (operands[1]) != CONST_DOUBLE)	abort ();      yoperands[0] = operands[0];      yoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));      output_asm_insn (\"loadi  %1,%0\", yoperands);      xoperands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));      output_asm_insn (\"loadi  %1,%0\", xoperands);      return \"\";    }					/* m -> r */  output_asm_insn (\"loadw  %1,%0\", operands);  xoperands[1] = adj_offsettable_operand (operands[1], 4);  output_asm_insn (\"loadw  %1,%0\", xoperands);  return \"\";}" [(set_attr "type" "arith,arith,load")  (set_attr "cc" "clobber,clobber,clobber")])(define_insn ""  [(set (match_operand:DI 0 "memory_operand" "=o")	(match_operand:DI 1 "register_operand" "r"))]  ""  "*{  rtx xops[4];  xops[0] = operands[0];  xops[1] = adj_offsettable_operand (operands[0], 4);  xops[2] = operands[1];  xops[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);  output_asm_insn (\"storw  %2,%0\;storw  %3,%1\", xops);  return \"\";}"[(set_attr "type" "store") (set_attr "cc" "clobber")])(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM &&      GET_CODE (operands[1]) != REG)    operands[1] = force_reg (SImode, operands[1]);}");; Reject both args with `general_operand' if not reloading because a;; mem -> mem move that was split by 'movsi' can be recombined to;; mem -> mem by the combiner.;;;; As a pseudo register can end up in a stack slot during reloading we must;; allow a r->m move for the next pattern. ;; The first predicate must be `general_operand' because a predicate must;; be true for each constraint.;;  (define_insn ""  [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m")	(match_operand:SI 1 "general_operand"  "r,m,n,i,r"))]  "reload_in_progress || register_operand (operands[0], SImode)"  "*{  int val;  if (which_alternative == 0)    return \"movw   %1,%0\";		/* reg -> reg */  if (which_alternative == 1)    return \"loadw  %1,%0\";		/* mem -> reg */  if (which_alternative == 2)    {      val = INTVAL (operands[1]);	/* known const ->reg */      if (val == -1)	return \"notq   $0,%0\";      if (val < 0 || val >= 16)	return \"loadi  %1,%0\";      return \"loadq  %1,%0\";    }  if (which_alternative == 3)		/* unknown const */    return \"loada  %a1,%0\";  return \"storw  %1,%0\";}"[(set_attr "type" "arith,load,arith,load,store") (set_attr "cc" "set2,change0,set1,change0,unchanged")])(define_insn ""  [(set (match_operand:SI 0 "memory_operand" "=m")	(match_operand:SI 1 "int_reg_operand" "r"))]  ""  "storw  %1,%0"[(set_attr "type" "store")]);; movhi;;;; loadh  mem to reg;; storh  reg to mem;;;;(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM      && ! register_operand (operands[1], HImode))    operands[1] = force_reg (HImode, operands[1]);}")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r,r,r")	(match_operand:HI 1 "general_operand"   "r,m,n"))]  ""  "@   movw   %1,%0   loadh  %1,%0   loadi  %1,%0"[(set_attr "type" "arith,load,arith")])(define_insn ""  [(set (match_operand:HI 0 "memory_operand"  "=m")	(match_operand:HI 1 "register_operand" "r"))]  ""  "storh  %1,%0" [(set_attr "type" "store")]);; movqi

⌨️ 快捷键说明

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