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

📄 mn10200.md

📁 gcc编译工具没有什么特别
💻 MD
📖 第 1 页 / 共 4 页
字号:
;; GCC machine description for Matsushita MN10200;; Copyright (C) 1997, 1998 Free Software Foundation, Inc.;; Contributed by Jeff Law (law@cygnus.com).;; 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.;; The original PO technology requires these to be ordered by speed,;; so that assigner will pick the fastest.;; See file "rtl.def" for documentation on define_insn, match_*, et. al.;; Condition code settings.;; none - insn does not affect cc;; none_0hit - insn does not affect cc but it does modify operand 0;;	This attribute is used to keep track of when operand 0 changes.;; 	See the description of NOTICE_UPDATE_CC for more info.;; set_znv - sets z,n,v to usable values; c is unknown.;; set_zn  - sets z,n to usable values; v,c is unknown.;; compare - compare instruction;; clobber - value of cc is unknown(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"  (const_string "clobber"));; ----------------------------------------------------------------------;; MOVE INSTRUCTIONS;; ----------------------------------------------------------------------;;;; Some general notes on move instructions.;;;; The hardware can't encode nop moves involving data registers, so;; we catch them and emit a nop instead.;;;; Loads/stores to/from address registers must be 16bit aligned,;; thus we avoid them for QImode.;;;; Stores from address registers always store 24bits, so avoid;; stores from address registers in HImode, SImode, and SFmode.;;;; As a result of the various problems using address registers in;; QImode, HImode, SImode, and SFmode, we discourage their use via;; '*' in their constraints.  They're still allowed, but they're never;; the preferred class for insns with those modes.;; movqi(define_expand "movqi"  [(set (match_operand:QI 0 "general_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))    operands[1] = copy_to_mode_reg (QImode, operand1);}");; We avoid memory operations involving address registers because we;; can't be sure they'll be suitably aligned.;;;; We also discourage holding QImode values in address registers.(define_insn ""  [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a")	(match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))]  "register_operand (operands[0], QImode)   || register_operand (operands[1], QImode)"  "@  nop  sub %0,%0  sub %0,%0  mov %S1,%0  movbu %1,%0  movb %1,%0  mov %1,%0  mov %1,%0  mov %1,%0"  [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]);; movhi(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  /* One of the ops has to be in a register */  if (!register_operand (operand1, HImode)      && !register_operand (operand0, HImode))    operands[1] = copy_to_mode_reg (HImode, operand1);}")(define_insn ""  [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a")	(match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))]  "register_operand (operands[0], HImode)   || register_operand (operands[1], HImode)"  "@  nop  sub %0,%0  sub %0,%0  mov %s1,%0  mov %1,%0  mov %1,%0  mov %1,%0  mov %1,%0  mov %1,%0  mov %A1,%0"  [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]);; movpsi and helpers(define_expand "movpsi"  [(set (match_operand:PSI 0 "general_operand" "")	(match_operand:PSI 1 "general_operand" ""))]  ""  "{  /* One of the ops has to be in a register */  if (!register_operand (operand1, PSImode)      && !register_operand (operand0, PSImode))    operands[1] = copy_to_mode_reg (PSImode, operand1);}");; Constant and indexed addresses are not valid addresses for PSImode,;; therefore they won't be matched by the general movpsi pattern below.;; ??? We had patterns to handle indexed addresses, but they kept making;; us run out of regs, so they were eliminated.(define_insn ""  [(set (match_operand:PSI 0 "register_operand" "=a")	(match_operand:PSI 1 "constant_memory_operand" ""))]  ""  "mov %A1,%0"  [(set_attr "cc" "none_0hit")])(define_insn ""  [(set (match_operand:PSI 0 "constant_memory_operand" "=X")	(match_operand:PSI 1 "register_operand" "a"))]  ""  "mov %1,%A0"  [(set_attr "cc" "none_0hit")]);; We want to prefer address registers here because 24bit moves to/from;; memory are shorter and faster when done via address registers.(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m")	(match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))]  "register_operand (operands[0], PSImode)   || register_operand (operands[1], PSImode)"  "@  nop  sub %0,%0  mov %1,%0  mov %A1,%0  mov %1,%A0  movx %A1,%0  movx %1,%A0"  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])(define_expand "movsi"  [(set (match_operand:SI 0 "general_operand" "")	(match_operand:SI 1 "general_operand" ""))]  ""  "{  /* One of the ops has to be in a register */  if (!register_operand (operand1, SImode)      && !register_operand (operand0, SImode))    operands[1] = copy_to_mode_reg (SImode, operand1);}")(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")	(match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))]  "register_operand (operands[0], SImode)   || register_operand (operands[1], SImode)"  "*{  switch (which_alternative)    {    case 0:      return \"nop\";    case 1:    case 2:      return \"sub %H0,%H0\;sub %L0,%L0\";    case 3:    case 5:    case 6:    case 7:      return \"mov %H1,%H0\;mov %L1,%L0\";    /* The next two cases try to optimize cases where one half       of the constant is all zeros, or when the two halves are       the same.  */    case 4:    case 8:      if (REG_P (operands[0])	  && GET_CODE (operands[1]) == CONST_INT	  && (INTVAL (operands[1]) & 0xffff0000) == 0)	output_asm_insn (\"sub %H0,%H0\", operands);      else	output_asm_insn (\"mov %h1,%H0\", operands);      if (GET_CODE (operands[1]) == CONST_INT	  && ((INTVAL (operands[1]) & 0xffff)	      == ((INTVAL (operands[1]) >> 16) & 0xffff)))	output_asm_insn (\"mov %H0,%L0\", operands);      else if (GET_CODE (operands[1]) == CONST_INT	       && (INTVAL (operands[1]) & 0xffff) == 0)	output_asm_insn (\"sub %L0,%L0\", operands);      else	output_asm_insn (\"mov %o1,%L0\", operands);      return \"\";    }}"  [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])(define_expand "movsf"  [(set (match_operand:SF 0 "general_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 ""  [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")	(match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))]  "register_operand (operands[0], SFmode)   || register_operand (operands[1], SFmode)"  "*{  switch (which_alternative)    {    case 0:      return \"nop\";    case 1:    case 2:      return \"sub %H0,%H0\;sub %L0,%L0\";    default:      {        long val;        REAL_VALUE_TYPE rv;	if (GET_CODE (operands[1]) == CONST_DOUBLE)	  {	    REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);	    REAL_VALUE_TO_TARGET_SINGLE (rv, val);	  }	if (GET_CODE (operands[1]) == CONST_INT)	  val = INTVAL (operands[1]);        if ((GET_CODE (operands[1]) == CONST_INT	     || GET_CODE (operands[1]) == CONST_DOUBLE)	    && (val & 0xffff0000) == 0)	  output_asm_insn (\"sub %H0,%H0\", operands);	else	  output_asm_insn (\"mov %h1,%H0\", operands);		if (GET_CODE (operands[1]) == CONST_INT	    && ((INTVAL (operands[1]) & 0xffff)		 == ((INTVAL (operands[1]) >> 16) & 0xffff)))	  output_asm_insn (\"mov %H0,%L0\", operands);        else if ((GET_CODE (operands[1]) == CONST_INT		  || GET_CODE (operands[1]) == CONST_DOUBLE)		 && (val & 0x0000ffff) == 0)	  output_asm_insn (\"sub %L0,%L0\", operands);	else	  output_asm_insn (\"mov %o1,%L0\", operands);	return \"\";      }    }}"  [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]);; ----------------------------------------------------------------------;; TEST INSTRUCTIONS;; ----------------------------------------------------------------------;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns;; when we start trying to optimize this port.(define_insn "tsthi"  [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "da"))]  ""  "* return output_tst (operands[0], insn);"  [(set_attr "cc" "set_znv")])(define_insn "tstpsi"  [(set (cc0) (match_operand:PSI 0 "nonimmediate_operand" "da"))]  ""  "* return output_tst (operands[0], insn);"  [(set_attr "cc" "set_znv")])(define_insn ""  [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))]  ""  "* return output_tst (operands[0], insn);"  [(set_attr "cc" "set_znv")])(define_insn ""  [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))]  ""  "* return output_tst (operands[0], insn);"  [(set_attr "cc" "set_znv")])(define_insn "cmphi"  [(set (cc0)	(compare:HI (match_operand:HI 0 "nonimmediate_operand" "da")		    (match_operand:HI 1 "general_operand" "dai")))]  ""  "cmp %1,%0"  [(set_attr "cc" "compare")])(define_insn "cmppsi"  [(set (cc0)	(compare:PSI (match_operand:PSI 0 "nonimmediate_operand" "da")		     (match_operand:PSI 1 "general_operand" "dai")))]  ""  "cmp %1,%0"  [(set_attr "cc" "compare")]);; ----------------------------------------------------------------------;; ADD INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "addhi3"  [(set (match_operand:HI 0 "general_operand" "=d")	(plus:HI (match_operand:HI 1 "general_operand" "%0")		 (match_operand:HI 2 "general_operand" "dai")))]  ""  "add %2,%0"  [(set_attr "cc" "set_zn")])(define_insn "addpsi3"  [(set (match_operand:PSI 0 "general_operand" "=da")	(plus:PSI (match_operand:PSI 1 "general_operand" "%0")		  (match_operand:PSI 2 "general_operand" "dai")))]  ""  "add %2,%0"  [(set_attr "cc" "set_zn")]);; We want to avoid using explicit registers; reload won't tell us;; if it has to spill them and may generate incorrect code in such;; cases.;;;; So we call out to a library routine to perform 32bit add or;; subtract operations.;;;; operand2 must be nonmemory_operand so that we will accept CONST_INTs;; during initial code generation.(define_expand "addsi3"  [(set (match_operand:SI 0 "register_operand" "")	(plus:SI (match_operand:SI 1 "register_operand" "")		 (match_operand:SI 2 "nonmemory_operand" "")))]  ""  "{  /* If adding a CONST_INT, we are better off generating code ourselves.     During RTL generation we call out to library routines.     After RTL generation we can not call the library routines as     they need to push arguments via virtual_outgoing_args_rtx which     has already been instantiated.  So, after RTL generation we just     FAIL and open code the operation.  */  if (GET_CODE (operands[2]) == CONST_INT)    {      if (!rtx_equal_p (operands[0], operands[1]))	emit_move_insn (operands[0], operands[1]);      emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2]));      DONE;    }  else if (rtx_equal_function_value_matters)    {      rtx ret, insns;      start_sequence ();      ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__addsi3\"),				     NULL_RTX, 1, SImode, 2, operands[1],				     SImode, operands[2], SImode);      insns = get_insns ();      end_sequence ();      emit_libcall_block (insns, operands[0], ret,			  gen_rtx (PLUS, SImode, operands[1], operands[2]));      DONE;    }  else    FAIL;}")(define_insn "addsi3_const"  [(set (match_operand:SI 0 "register_operand" "=d")	(plus:SI (match_operand:SI 1 "register_operand" "0")		 (match_operand:SI 2 "const_int_operand" "i")))   (clobber (match_scratch:SI 3 "=&d"))]  ""  "*{  unsigned long value = INTVAL (operands[2]);  /* If only the high bits are set in the constant, then we only     need a single add operation.  It might be better to catch this     at RTL expansion time.  */  if ((value & 0xffff) == 0)    return \"add %h2,%H0\";  value >>= 16;  value &= 0xffff;  if (value == 0)    return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\";  else    return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\";}"  [(set_attr "cc" "clobber")]);; ----------------------------------------------------------------------;; SUBTRACT INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "subhi3"  [(set (match_operand:HI 0 "general_operand" "=d")	(minus:HI (match_operand:HI 1 "general_operand" "0")		  (match_operand:HI 2 "general_operand" "dai")))]  ""  "sub %2,%0"  [(set_attr "cc" "set_zn")])(define_insn "subpsi3"  [(set (match_operand:PSI 0 "general_operand" "=da")	(minus:PSI (match_operand:PSI 1 "general_operand" "0")		  (match_operand:PSI 2 "general_operand" "dai")))]  ""  "sub %2,%0"  [(set_attr "cc" "set_zn")])(define_expand "subsi3"  [(set (match_operand:SI 0 "register_operand" "")	(minus:SI (match_operand:SI 1 "register_operand" "")		  (match_operand:SI 2 "register_operand" "")))]  ""  "{  /* During RTL generation we call out to library routines.     After RTL generation we can not call the library routines as     they need to push arguments via virtual_outgoing_args_rtx which     has already been instantiated.  So, after RTL generation we just     FAIL and open code the operation.  */  if (rtx_equal_function_value_matters)    {      rtx ret, insns;      start_sequence ();      ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__subsi3\"),				     NULL_RTX, 1, SImode, 2, operands[1],				     SImode, operands[2], SImode);      insns = get_insns ();      end_sequence ();      emit_libcall_block (insns, operands[0], ret,			  gen_rtx (MINUS, SImode, operands[1], operands[2]));      DONE;    }  else    FAIL;}");; There isn't a negate instruction, so we fake it.;;;; We used to expand this into patterns, but a single pattern;; actually generates better overall code.;; ;; We could do HImode negations with a "not;add" sequence, but;; generally it's generated slightly worse code.;;;; The second alternative is not strictly necesasry, but helps;; when the register allocators start running short of registers.(define_insn "neghi2"  [(set (match_operand:HI 0 "general_operand" "=&d,d")        (neg:HI (match_operand:HI 1 "general_operand" "d,0")))]  ""  "@  sub %0,%0\;sub %1,%0  not %0\;add 1,%0"  [(set_attr "cc" "set_zn")])

⌨️ 快捷键说明

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