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

📄 tahoe.md

📁 gcc编译工具没有什么特别
💻 MD
📖 第 1 页 / 共 4 页
字号:
;; Machine description for GNU compiler, Tahoe version;; Copyright (C) 1989, 1994, 1996, 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.; File: tahoe.md;; Original port made at the University of Buffalo by Devon Bowen,; Dale Wiles and Kevin Zachmann.;; Piet van Oostrum (piet@cs.ruu.nl) made changes for HCX/UX, fixed; some bugs and made some improvements (hopefully).;; Mail bugs reports or fixes to:	gcc@cs.buffalo.edu; movdi must call the output_move_double routine to move it around since; the tahoe doesn't efficiently support 8 bit moves.(define_insn "movdi"  [(set (match_operand:DI 0 "general_operand" "=g")	(match_operand:DI 1 "general_operand" "g"))]  ""  "*{  CC_STATUS_INIT;  return output_move_double (operands);}"); the trick in the movsi is accessing the contents of the sp register.  The; tahoe doesn't allow you to access it directly so you have to access the; address of the top of the stack instead.(define_insn "movsi"  [(set (match_operand:SI 0 "general_operand" "=g")	(match_operand:SI 1 "general_operand" "g"))]  ""  "*{   rtx link;   if (operands[1] == const1_rtx      && (link = find_reg_note (insn, REG_WAS_0, 0))      && ! INSN_DELETED_P (XEXP (link, 0))      && GET_CODE (XEXP (link, 0)) != NOTE      && no_labels_between_p (XEXP (link, 0), insn)      /* Make sure the reg hasn't been clobbered.  */      && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))    return \"incl %0\";   if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)    {      if (push_operand (operands[0], SImode))	return \"pushab %a1\";      return \"movab %a1,%0\";    }  if (operands[1] == const0_rtx)    return \"clrl %0\";  if (push_operand (operands[0], SImode))    return \"pushl %1\";  if (GET_CODE(operands[1]) == REG && REGNO(operands[1]) == 14)    return \"moval (sp),%0\";  return \"movl %1,%0\";}")(define_insn "movhi"  [(set (match_operand:HI 0 "general_operand" "=g")	(match_operand:HI 1 "general_operand" "g"))]  ""  "*{ rtx link; if (operands[1] == const1_rtx     && (link = find_reg_note (insn, REG_WAS_0, 0))     && ! INSN_DELETED_P (XEXP (link, 0))     && GET_CODE (XEXP (link, 0)) != NOTE     && no_labels_between_p (XEXP (link, 0), insn)     /* Make sure the reg hasn't been clobbered.  */     && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))    return \"incw %0\";  if (operands[1] == const0_rtx)    return \"clrw %0\";  return \"movw %1,%0\";}")(define_insn "movqi"  [(set (match_operand:QI 0 "general_operand" "=g")	(match_operand:QI 1 "general_operand" "g"))]  ""  "*{  if (operands[1] == const0_rtx)    return \"clrb %0\";  return \"movb %1,%0\";}"); movsf has three cases since they can move from one place to another; or to/from the fpp and since different instructions are needed for; each case.  The fpp related instructions don't set the flags properly.(define_insn "movsf"  [(set (match_operand:SF 0 "general_operand" "=g,=a,=g")	(match_operand:SF 1 "general_operand" "g,g,a"))]  ""  "*{  CC_STATUS_INIT;  switch (which_alternative)    {    case 0: return \"movl %1,%0\";    case 1: return \"ldf %1\";    case 2: return \"stf %0\";   }}"); movdf has a number of different cases.  If it's going to or from; the fpp, use the special instructions to do it.  If not, use the; output_move_double function.(define_insn "movdf"  [(set (match_operand:DF 0 "general_operand" "=a,=g,?=g")	(match_operand:DF 1 "general_operand" "g,a,g"))]  ""  "*{  CC_STATUS_INIT;  switch (which_alternative)    {    case 0:      return \"ldd %1\";    case 1:      if (push_operand (operands[0], DFmode))        return \"pushd\";      else        return \"std %0\";    case 2:      return output_move_double (operands);   }}");========================================================================; The tahoe has the following semantics for byte (and similar for word); operands: if the operand is a register or immediate, it takes the full 32; bit operand, if the operand is memory, it sign-extends the byte.  The; operation is performed on the 32 bit values.  If the destination is a; register, the full 32 bit result is stored, if the destination is memory,; of course only the low part is stored.  The condition code is based on the; 32 bit operation.  Only on the movz instructions the byte from memory is; zero-extended rather than sign-extended.; This means that for arithmetic instructions we can use addb etc.  to; perform a long add from a signed byte from memory to a register.  Of; course this would also work for logical operations, but that doesn't seem; very useful.(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(plus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))		 (sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "addb3 %1,%2,%0")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(plus:SI (match_operand:SI 1 "nonmemory_operand" "%ri")		 (sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"addb2 %2,%0\";  return \"addb3 %1,%2,%0\";}"); We can also consider the result to be a half integer(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(plus:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))		 (sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "addb3 %1,%2,%0")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(plus:HI (match_operand:HI 1 "nonmemory_operand" "%ri")		 (sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"addb2 %2,%0\";  return \"addb3 %1,%2,%0\";}"); The same applies to words (HI)(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(plus:SI (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))		 (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]  ""  "addw3 %1,%2,%0")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(plus:SI (match_operand:SI 1 "nonmemory_operand" "%ri")		 (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"addw2 %2,%0\";  return \"addw3 %1,%2,%0\";}"); ======================= Now for subtract ==============================(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))		  (sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "subb3 %2,%1,%0")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (match_operand:SI 1 "nonmemory_operand" "ri")		  (sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"subb2 %2,%0\";  return \"subb3 %2,%1,%0\";}")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))		  (match_operand:SI 2 "nonmemory_operand" "ri")))]  ""  "subb3 %2,%1,%0"); We can also consider the result to be a half integer(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(minus:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))		 (sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "subb3 %2,%1,%0")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(minus:HI (match_operand:HI 1 "nonmemory_operand" "%ri")		 (sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"subb2 %2,%0\";  return \"subb3 %2,%1,%0\";}")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(minus:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))		 (match_operand:HI 2 "nonmemory_operand" "ri")))]  ""  "subb3 %2,%1,%0"); The same applies to words (HI)(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))		  (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]  ""  "subw3 %2,%1,%0")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (match_operand:SI 1 "nonmemory_operand" "ri")		 (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    return \"subw2 %2,%0\";  return \"subw3 %2,%1,%0\";}")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(minus:SI (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))		  (match_operand:SI 2 "nonmemory_operand" "ri")))]  ""  "subw3 %2,%1,%0"); ======================= Now for neg ==============================(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(neg:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))))]  ""  "mnegb %1,%0")(define_insn ""  [(set (match_operand:HI 0 "register_operand" "=r")	(neg:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))))]  ""  "mnegb %1,%0")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r")	(neg:SI (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))))]  ""  "mnegw %1,%0");========================================================================(define_insn "addsi3"  [(set (match_operand:SI 0 "general_operand" "=g")	(plus:SI (match_operand:SI 1 "general_operand" "g")		 (match_operand:SI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"incl %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && INTVAL (operands[2]) == -1)	return \"decl %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && (unsigned) (- INTVAL (operands[2])) < 64)	return \"subl2 $%n2,%0\";      return \"addl2 %2,%0\";    }  if (rtx_equal_p (operands[0], operands[2]))    return \"addl2 %1,%0\";  if (GET_CODE (operands[2]) == CONST_INT      && GET_CODE (operands[1]) == REG)    {      if (push_operand (operands[0], SImode))        return \"pushab %c2(%1)\";      return \"movab %c2(%1),%0\";    }  if (GET_CODE (operands[2]) == CONST_INT      && (unsigned) (- INTVAL (operands[2])) < 64)    return \"subl3 $%n2,%1,%0\";  return \"addl3 %1,%2,%0\";}")(define_insn "addhi3"  [(set (match_operand:HI 0 "general_operand" "=g")	(plus:HI (match_operand:HI 1 "general_operand" "g")		 (match_operand:HI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"incw %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && INTVAL (operands[2]) == -1)	return \"decw %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && (unsigned) (- INTVAL (operands[2])) < 64)	return \"subw2 $%n2,%0\";      return \"addw2 %2,%0\";    }  if (rtx_equal_p (operands[0], operands[2]))    return \"addw2 %1,%0\";  if (GET_CODE (operands[2]) == CONST_INT      && (unsigned) (- INTVAL (operands[2])) < 64)    return \"subw3 $%n2,%1,%0\";  return \"addw3 %1,%2,%0\";}")(define_insn "addqi3"  [(set (match_operand:QI 0 "general_operand" "=g")	(plus:QI (match_operand:QI 1 "general_operand" "g")		 (match_operand:QI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"incb %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && INTVAL (operands[2]) == -1)	return \"decb %0\";      if (GET_CODE (operands[2]) == CONST_INT	  && (unsigned) (- INTVAL (operands[2])) < 64)	return \"subb2 $%n2,%0\";      return \"addb2 %2,%0\";    }  if (rtx_equal_p (operands[0], operands[2]))    return \"addb2 %1,%0\";  if (GET_CODE (operands[2]) == CONST_INT      && (unsigned) (- INTVAL (operands[2])) < 64)    return \"subb3 $%n2,%1,%0\";  return \"addb3 %1,%2,%0\";}"); addsf3 can only add into the fpp register since the fpp is treated; as a separate unit in the machine.  It also doesn't set the flags at; all.(define_insn "addsf3"  [(set (match_operand:SF 0 "register_operand" "=a")	(plus:SF (match_operand:SF 1 "register_operand" "%0")		 (match_operand:SF 2 "general_operand" "g")))]  ""  "*{  CC_STATUS_INIT;  return \"addf %2\";}"); adddf3 can only add into the fpp reg since the fpp is treated as a; separate entity.  Doubles can only be read from a register or memory; since a double is not an immediate mode.  Flags are not set by this; instruction.(define_insn "adddf3"  [(set (match_operand:DF 0 "register_operand" "=a")	(plus:DF (match_operand:DF 1 "register_operand" "%0")		 (match_operand:DF 2 "general_operand" "rm")))]  ""  "*{  CC_STATUS_INIT;  return \"addd %2\";}"); Subtraction from the sp (needed by the built in alloc function) needs; to be different since the sp cannot be directly read on the tahoe.; If it's a simple constant, you just use displacement.  Otherwise, you; push the sp, and then do the subtraction off the stack.(define_insn "subsi3"  [(set (match_operand:SI 0 "general_operand" "=g")	(minus:SI (match_operand:SI 1 "general_operand" "g")		  (match_operand:SI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"decl %0\";      if (GET_CODE(operands[0]) == REG && REGNO(operands[0]) == 14)        {	  if (GET_CODE(operands[2]) == CONST_INT)	    return \"movab %n2(sp),sp\";	  else	    return \"pushab (sp)\;subl3 %2,(sp),sp\";	}      return \"subl2 %2,%0\";    }  if (rtx_equal_p (operands[1], operands[2]))    return \"clrl %0\";  return \"subl3 %2,%1,%0\";}")(define_insn "subhi3"  [(set (match_operand:HI 0 "general_operand" "=g")	(minus:HI (match_operand:HI 1 "general_operand" "g")		  (match_operand:HI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"decw %0\";      return \"subw2 %2,%0\";    }  if (rtx_equal_p (operands[1], operands[2]))    return \"clrw %0\";  return \"subw3 %2,%1,%0\";}")(define_insn "subqi3"  [(set (match_operand:QI 0 "general_operand" "=g")	(minus:QI (match_operand:QI 1 "general_operand" "g")		  (match_operand:QI 2 "general_operand" "g")))]  ""  "*{  if (rtx_equal_p (operands[0], operands[1]))    {      if (operands[2] == const1_rtx)	return \"decb %0\";      return \"subb2 %2,%0\";    }

⌨️ 快捷键说明

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