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

📄 i860.md

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description for Intel 860 chip for GNU C compiler;;   Copyright (C) 1989, 1990, 1997 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.;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;- Operand classes for the register allocator:/* Bit-test instructions.  */(define_insn ""  [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")			  (match_operand:SI 1 "logic_operand" "rL"))		  (const_int 0)))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"and %1,%0,%?r0\";}")(define_insn ""  [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")			  (match_operand:SI 1 "logic_operand" "rL"))		  (const_int 0)))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"and %1,%0,%?r0\";}")(define_insn ""  [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")			  (match_operand:SI 1 "immediate_operand" "i"))		  (const_int 0)))]  "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"  "*{  CC_STATUS_PARTIAL_INIT;  return \"andh %H1,%0,%?r0\";}")(define_insn ""  [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")			  (match_operand:SI 1 "immediate_operand" "i"))		  (const_int 0)))]  "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"andh %H1,%0,%?r0\";}")(define_insn ""  [(set (cc0) (eq (ashiftrt:SI		   (sign_extend:SI		    (ashift:QI (match_operand:QI 0 "register_operand" "r")			       (match_operand:QI 1 "logic_int" "n")))		   (match_operand:SI 2 "logic_int" "n"))		  (const_int 0)))]  ""  "*{  int width = 8 - INTVAL (operands[2]);  int pos = 8 - width - INTVAL (operands[1]);  CC_STATUS_PARTIAL_INIT;  operands[2] = GEN_INT (~((-1) << width) << pos);  return \"and %2,%0,%?r0\";}");; -------------------------------------------------------------------------;; SImode signed integer comparisons;; -------------------------------------------------------------------------(define_insn "cmpeqsi"  [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL")		  (match_operand:SI 1 "logic_operand" "L,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  if (REG_P (operands[0]))    return \"xor %1,%0,%?r0\";  else    return \"xor %0,%1,%?r0\";}")(define_insn "cmpnesi"  [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL")		  (match_operand:SI 1 "logic_operand" "L,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  if (REG_P (operands[0]))    return \"xor %1,%0,%?r0\";  else    return \"xor %0,%1,%?r0\";}")(define_insn "cmpltsi"  [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI")		  (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  if (REG_P (operands[1]))    return \"subs %0,%1,%?r0\";  else    {      cc_status.flags |= CC_REVERSED;      operands[1] = GEN_INT (- INTVAL (operands[1]));      return \"adds %1,%0,%?r0\";    }}")(define_insn "cmpgtsi"  [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI")		  (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  if (REG_P (operands[0]))    return \"subs %1,%0,%?r0\";  else    {      cc_status.flags |= CC_REVERSED;      operands[0] = GEN_INT (- INTVAL (operands[0]));      return \"adds %0,%1,%?r0\";    }}")(define_insn "cmplesi"  [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI")		  (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  if (REG_P (operands[0]))    return \"subs %1,%0,%?r0\";  else    {      cc_status.flags |= CC_REVERSED;      operands[0] = GEN_INT (- INTVAL (operands[0]));      return \"adds %0,%1,%?r0\";    }}")(define_insn "cmpgesi"  [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI")		  (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  if (REG_P (operands[1]))    return \"subs %0,%1,%?r0\";  else    {      cc_status.flags |= CC_REVERSED;      operands[1] = GEN_INT (- INTVAL (operands[1]));      return \"adds %1,%0,%?r0\";    }}");; -------------------------------------------------------------------------;; SImode unsigned integer comparisons;; -------------------------------------------------------------------------;; WARNING!  There is a small i860 hardware limitation (bug?) which we;; may run up against (if we are not careful) when we are trying to do;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x).;; Specifically, we must avoid using an `addu' instruction to perform;; such comparisons because the result (in the CC bit register) will;; come out wrong.  (This fact is documented in a footnote on page 7-10;; of the 1991 version of the i860 Microprocessor Family Programmer's;; Reference Manual).  Note that unsigned comparisons of this sort are;; always redundant anyway, because an unsigned quantity can never be;; less than zero.  When we see cases like this, we generate an;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1);; so as to get the CC bit register set properly for any subsequent;; conditional jump instruction.(define_insn "cmpgeusi"  [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI")		   (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  if (REG_P (operands[1]))    return \"subu %0,%1,%?r0\";  else    {      if (INTVAL (operands[1]) == 0)	return \"or 0,%?r0,%?r0\";      else	{	  cc_status.flags |= CC_REVERSED;	  operands[1] = GEN_INT (- INTVAL (operands[1]));	  return \"addu %1,%0,%?r0\";	}    }}")(define_insn "cmpleusi"  [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI")		   (match_operand:SI 1 "arith_operand" "I,r")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  if (REG_P (operands[0]))    return \"subu %1,%0,%?r0\";  else    {      if (INTVAL (operands[0]) == 0)	return \"or 0,%?r0,%?r0\";      else	{	  cc_status.flags |= CC_REVERSED;	  operands[0] = GEN_INT (- INTVAL (operands[0]));	  return \"addu %0,%1,%?r0\";	}    }}");; -------------------------------------------------------------------------;; SFmode floating-point comparisons;; -------------------------------------------------------------------------(define_insn "cmpeqsf"  [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfeq.ss %r0,%r1,%?f0\";}")(define_insn "cmpnesf"  [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfeq.ss %r1,%r0,%?f0\";}");; NOTE:  The i860 Programmer's Reference Manual says that when we are;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these;; in order to be IEEE compliant (in case a trap occurs during these;; operations).  Conversely, for (A <= B) or (A >= B) comparisons, we;; must use pfle to be IEEE compliant.(define_insn "cmpltsf"  [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfgt.ss %r1,%r0,%?f0\";}")(define_insn "cmpgtsf"  [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfgt.ss %r0,%r1,%?f0\";}");; NOTE:  The pfle opcode doesn't do what you think it does.  It is;; bass-ackwards.  It *clears* the CC flag if the first operand is;; less than or equal to the second.  Thus, we have to set CC_NEGATED;; for the following two patterns.(define_insn "cmplesf"  [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfle.ss %r0,%r1,%?f0\";}")(define_insn "cmpgesf"  [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG")		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfle.ss %r1,%r0,%?f0\";}");; -------------------------------------------------------------------------;; DFmode floating-point comparisons;; -------------------------------------------------------------------------(define_insn "cmpeqdf"  [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfeq.dd %r0,%r1,%?f0\";}")(define_insn "cmpnedf"  [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfeq.dd %r1,%r0,%?f0\";}");; NOTE:  The i860 Programmer's Reference Manual says that when we are;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these;; in order to be IEEE compliant (in case a trap occurs during these;; operations).  Conversely, for (A <= B) or (A >= B) comparisons, we;; must use pfle to be IEEE compliant.(define_insn "cmpltdf"  [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfgt.dd %r1,%r0,%?f0\";}")(define_insn "cmpgtdf"  [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  return \"pfgt.dd %r0,%r1,%?f0\";}");; NOTE:  The pfle opcode doesn't do what you think it does.  It is;; bass-ackwards.  It *clears* the CC flag if the first operand is;; less than or equal to the second.  Thus, we have to set CC_NEGATED;; for the following two patterns.(define_insn "cmpledf"  [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfle.dd %r0,%r1,%?f0\";}")(define_insn "cmpgedf"  [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG")		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]  ""  "*{  CC_STATUS_PARTIAL_INIT;  cc_status.flags |= CC_NEGATED;  return \"pfle.dd %r1,%r0,%?f0\";}");; ------------------------------------------------------------------------;; Integer EQ/NE comparisons against constant values which will fit in the;; 16-bit immediate field of an instruction.  These are made by combining.;; ------------------------------------------------------------------------(define_insn ""  [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))	          (match_operand:SI 1 "small_int" "I")))]  "INTVAL (operands[1]) >= 0"  "*{  CC_STATUS_PARTIAL_INIT;  return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\";}")(define_insn ""  [(set (cc0) (eq (match_operand:SI 0 "small_int" "I")	          (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))]  "INTVAL (operands[0]) >= 0"  "*{  CC_STATUS_PARTIAL_INIT;  return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\";}");; ------------------------------------------------------------------------;; Define the real conditional branch instructions.;; ------------------------------------------------------------------------(define_insn "cbranch"  [(set (pc) (if_then_else (eq (cc0) (const_int 0))			   (label_ref (match_operand 0 "" ""))			   (pc)))]  ""  "*{  if ((cc_prev_status.flags & CC_NEGATED) == 0)    return \"bnc %l0\";  else    return \"bc %l0\";}")(define_insn "flipped_cbranch"  [(set (pc) (if_then_else (ne (cc0)			       (const_int 0))			   (pc)			   (label_ref (match_operand 0 "" ""))))]  ""  "*{

⌨️ 快捷键说明

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