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

📄 cris.md

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; GCC machine description for CRIS cpu cores.;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.;; Contributed by Axis Communications.;; This file is part of GCC.;;;; GCC 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.;;;; GCC 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 GCC; 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 files "md.texi" and "rtl.def" for documentation on define_insn,;; match_*, et. al.;;;; The function cris_notice_update_cc in cris.c handles condition code;; updates for most instructions, helped by the "cc" attribute.;; There are several instructions that are orthogonal in size, and seems;; they could be matched by a single pattern without a specified size;; for the operand that is orthogonal.  However, this did not work on;; gcc-2.7.2 (and problably not on gcc-2.8.1), relating to that when a;; constant is substituted into an operand, the actual mode must be;; deduced from the pattern.  There is reasonable hope that that has been;; fixed, so FIXME: try again.;; You will notice that three-operand alternatives ("=r", "r", "!To");; are marked with a "!" constraint modifier to avoid being reloaded;; into.  This is because gcc would otherwise prefer to use the constant;; pool and its offsettable address instead of reloading to an;; ("=r", "0", "i") alternative.  Also, the constant-pool support was not;; only suboptimal but also buggy in 2.7.2, ??? maybe only in 2.6.3.;; All insns that look like (set (...) (plus (...) (reg:SI 8)));; get problems when reloading r8 (frame pointer) to r14 + offs (stack;; pointer).  Thus the instructions that get into trouble have specific;; checks against matching frame_pointer_rtx.;; ??? But it should be re-checked for gcc > 2.7.2;; FIXME: This changed some time ago (from 2000-03-16) for gcc-2.9x.;; FIXME: When PIC, all [rX=rY+S] could be enabled to match;; [rX=gotless_symbol].;; The movsi for a gotless symbol could be split (post reload).;; UNSPEC Usage:;; 0 PLT reference from call expansion: operand 0 is the address,;;   the mode is VOIDmode.  Always wrapped in CONST.;; We need an attribute to define whether an instruction can be put in;; a branch-delay slot or not, and whether it has a delay slot.;;;; Branches and return instructions have a delay slot, and cannot;; themselves be put in a delay slot.  This has changed *for short;; branches only* between architecture variants, but the possible win;; is presumed negligible compared to the added complexity of the machine;; description: one would have to add always-correct infrastructure to;; distinguish short branches.;;;; Whether an instruction can be put in a delay slot depends on the;; instruction (all short instructions except jumps and branches);; and the addressing mode (must not be prefixed or referring to pc).;; In short, any "slottable" instruction must be 16 bit and not refer;; to pc, or alter it.;;;; The possible values are "yes", "no" and "has_slot".  Yes/no means if;; the insn is slottable or not.  Has_slot means that the insn is a;; return insn or branch insn (which are not considered slottable since;; that is generally true).  Having the semmingly illogical value;; "has_slot" means we do not have to add another attribute just to say;; that an insn has a delay-slot, since it also infers that it is not;; slottable.  Better names for the attribute were found to be longer and;; not add readability to the machine description.;;;; The default that is defined here for this attribute is "no", not;; slottable, not having a delay-slot, so there's no need to worry about;; it being wrong for non-branch and return instructions.;;  The default could depend on the kind of insn and the addressing;; mode, but that would need more attributes and hairier, more error;; prone code.;;;;  There is an extra constraint, 'Q', which recognizes indirect reg,;; except when the reg is pc.  The constraints 'Q' and '>' together match;; all possible memory operands that are slottable.;;  For other operands, you need to check if it has a valid "slottable";; quick-immediate operand, where the particular signedness-variation;; may match the constraints 'I' or 'J'.), and include it in the;; constraint pattern for the slottable pattern.  An alternative using;; only "r" constraints is most often slottable.(define_attr "slottable" "no,yes,has_slot" (const_string "no"));; We also need attributes to sanely determine the condition code;; state.  See cris_notice_update_cc for how this is used.(define_attr "cc" "none,clobber,normal" (const_string "normal"));; A branch or return has one delay-slot.  The instruction in the;; delay-slot is always executed, independent of whether the branch is;; taken or not.  Note that besides setting "slottable" to "has_slot",;; there also has to be a "%#" at the end of a "delayed" instruction;; output pattern (for "jump" this means "ba %l0%#"), so print_operand can;; catch it and print a "nop" if necessary.  This method was stolen from;; sparc.md.(define_delay (eq_attr "slottable" "has_slot")  [(eq_attr "slottable" "yes") (nil) (nil)]);; Test insns.;; DImode;;;; Allow register and offsettable mem operands only; post-increment is;; not worth the trouble.(define_insn "tstdi"  [(set (cc0)	(match_operand:DI 0 "nonimmediate_operand" "r,o"))]  ""  "test.d %M0\;ax\;test.d %H0");; No test insns with side-effect on the mem addressing.;;;; See note on cmp-insns with side-effects (or lack of them);; Normal named test patterns from SI on.;; FIXME: Seems they should change to be in order smallest..largest.(define_insn "tstsi"  [(set (cc0)	(match_operand:SI 0 "nonimmediate_operand" "r,Q>,m"))]  ""  "test.d %0"  [(set_attr "slottable" "yes,yes,no")])(define_insn "tsthi"  [(set (cc0)	(match_operand:HI 0 "nonimmediate_operand" "r,Q>,m"))]  ""  "test.w %0"  [(set_attr "slottable" "yes,yes,no")])(define_insn "tstqi"  [(set (cc0)	(match_operand:QI 0 "nonimmediate_operand" "r,Q>,m"))]  ""  "test.b %0"  [(set_attr "slottable" "yes,yes,no")]);; It seems that the position of the sign-bit and the fact that 0.0 is;; all 0-bits would make "tstsf" a straight-forward implementation;;; either "test.d" it for positive/negative or "btstq 30,r" it for;; zeroness.;;;; FIXME: Do that some time; check next_cc0_user to determine if;; zero or negative is tested for.;; Compare insns.;; We could optimize the sizes of the immediate operands for various;; cases, but that is not worth it because of the very little usage of;; DImode for anything else but a structure/block-mode.  Just do the;; obvious stuff for the straight-forward constraint letters.(define_insn "cmpdi"  [(set (cc0)	(compare (match_operand:DI 0 "nonimmediate_operand" "r,r,r,r,r,r,o")		 (match_operand:DI 1 "general_operand" "K,I,P,n,r,o,r")))]  ""  "@   cmpq %1,%M0\;ax\;cmpq 0,%H0   cmpq %1,%M0\;ax\;cmpq -1,%H0   cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0   cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0   cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0   cmp.d %M1,%M0\;ax\;cmp.d %H1,%H0   cmp.d %M0,%M1\;ax\;cmp.d %H0,%H1");; Note that compare insns with side effect addressing mode (e.g.):;;;; cmp.S [rx=ry+i],rz;;; cmp.S [%3=%1+%2],%0;;;; are *not* usable for gcc since the reloader *does not accept*;; cc0-changing insns with side-effects other than setting the condition;; codes.  The reason is that the reload stage *may* cause another insn to;; be output after the main instruction, in turn invalidating cc0 for the;; insn using the test.  (This does not apply to the CRIS case, since a;; reload for output -- move to memory -- does not change the condition;; code.  Unfortunately we have no way to describe that at the moment.  I;; think code would improve being in the order of one percent faster.;; We have cmps and cmpu (compare reg w. sign/zero extended mem).;; These are mostly useful for compares in SImode, using 8 or 16-bit;; constants, but sometimes gcc will find its way to use it for other;; (memory) operands.  Avoid side-effect patterns, though (see above).;;;; FIXME: These could have an anonymous mode for operand 1.;; QImode(define_insn "*cmp_extsi"  [(set (cc0)	(compare	 (match_operand:SI 0 "register_operand" "r,r")	 (match_operator:SI 2 "cris_extend_operator"			 [(match_operand:QI 1 "memory_operand" "Q>,m")])))]  ""  "cmp%e2.%s1 %1,%0"  [(set_attr "slottable" "yes,no")]);; HImode(define_insn "*cmp_exthi"  [(set (cc0)	(compare	 (match_operand:SI 0 "register_operand" "r,r")	 (match_operator:SI 2 "cris_extend_operator"			 [(match_operand:HI 1 "memory_operand" "Q>,m")])))]  ""  "cmp%e2.%s1 %1,%0"  [(set_attr "slottable" "yes,no")]);; Swap operands; it seems the canonical look (if any) is not enforced.;;;; FIXME: Investigate that.;; FIXME: These could have an anonymous mode for operand 1.;; QImode(define_insn "*cmp_swapextqi"  [(set (cc0)	(compare	 (match_operator:SI 2 "cris_extend_operator"			    [(match_operand:QI 0 "memory_operand" "Q>,m")])	 (match_operand:SI 1 "register_operand" "r,r")))]  ""  "cmp%e2.%s0 %0,%1" ; The function cris_notice_update_cc knows about		     ; swapped operands to compares.  [(set_attr "slottable" "yes,no")]);; HImode(define_insn "*cmp_swapexthi"  [(set (cc0)	(compare	 (match_operator:SI 2 "cris_extend_operator"			    [(match_operand:HI 0 "memory_operand" "Q>,m")])	 (match_operand:SI 1 "register_operand" "r,r")))]  ""  "cmp%e2.%s0 %0,%1" ; The function cris_notice_update_cc knows about		     ; swapped operands to compares.  [(set_attr "slottable" "yes,no")]);; The "normal" compare patterns, from SI on.(define_insn "cmpsi"  [(set (cc0)	(compare	 (match_operand:SI 0 "nonimmediate_operand" "r,r,r,r,Q>,Q>,r,r,m,m")	 (match_operand:SI 1 "general_operand" "I,r,Q>,M,M,r,P,g,M,r")))]  ""  "@   cmpq %1,%0   cmp.d %1,%0   cmp.d %1,%0   test.d %0   test.d %0   cmp.d %0,%1   cmp%e1.%z1 %1,%0   cmp.d %1,%0   test.d %0   cmp.d %0,%1"  [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,no,no,no")])(define_insn "cmphi"  [(set (cc0)	(compare (match_operand:HI 0 "nonimmediate_operand" "r,r,Q>,Q>,r,m,m")		 (match_operand:HI 1 "general_operand" "r,Q>,M,r,g,M,r")))]  ""  "@   cmp.w %1,%0   cmp.w %1,%0   test.w %0   cmp.w %0,%1   cmp.w %1,%0   test.w %0   cmp.w %0,%1"  [(set_attr "slottable" "yes,yes,yes,yes,no,no,no")])(define_insn "cmpqi"  [(set (cc0)	(compare	 (match_operand:QI 0 "nonimmediate_operand" "r,r,r,Q>,Q>,r,m,m")	 (match_operand:QI 1 "general_operand" "r,Q>,M,M,r,g,M,r")))]  ""  "@   cmp.b %1,%0   cmp.b %1,%0   test.b %0   test.b %0   cmp.b %0,%1   cmp.b %1,%0   test.b %0   cmp.b %0,%1"  [(set_attr "slottable" "yes,yes,yes,yes,yes,no,no,no")]);; Pattern matching the BTST insn.;; It is useful for "if (i & val)" constructs, where val is an exact;; power of 2, or if val + 1 is a power of two, where we check for a bunch;; of zeros starting at bit 0).;; SImode.  This mode is the only one needed, since gcc automatically;; extends subregs for lower-size modes.  FIXME: Add test-case.(define_insn "*btst"  [(set (cc0)	(zero_extract	 (match_operand:SI 0 "nonmemory_operand" "r,r,r,r,r,r,n")	 (match_operand:SI 1 "const_int_operand" "K,n,K,n,K,n,n")	 (match_operand:SI 2 "nonmemory_operand" "M,M,K,n,r,r,r")))]  ;; Either it is a single bit, or consecutive ones starting at 0.  "GET_CODE (operands[1]) == CONST_INT   && (operands[1] == const1_rtx || operands[2] == const0_rtx)   && (REG_S_P (operands[0])       || (operands[1] == const1_rtx	   && REG_S_P (operands[2])	   && GET_CODE (operands[0]) == CONST_INT	   && exact_log2 (INTVAL (operands[0])) >= 0))";; The last "&&" condition above should be caught by some kind of;; canonicalization in gcc, but we can easily help with it here.;;  It results from expressions of the type;; "power_of_2_value & (1 << y)".;;;; Since there may be codes with tests in on bits (in constant position);; beyond the size of a word, handle that by assuming those bits are 0.;; GCC should handle that, but it's a matter of easily-added belts while;; having suspenders.  "@   btstq (%1-1),%0   test.d %0   btstq %2,%0   clearf nz   btst %2,%0   clearf nz   cmpq %p0,%2" [(set_attr "slottable" "yes")]);; Move insns.;; The whole mandatory movdi family is here; expander, "anonymous";; recognizer and splitter.  We're forced to have a movdi pattern,;; although GCC should be able to split it up itself.  Normally it can,;; but if other insns have DI operands (as is the case here), reload;; must be able to generate or match a movdi.  many testcases fail at;; -O3 or -fssa if we don't have this.  FIXME: Fix GCC...  See;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00104.html>.;; However, a patch from Richard Kenner (similar to the cause of;; discussion at the URL above), indicates otherwise.  See;; <URL:http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00554.html>.;; The truth has IMO is not been decided yet, so check from time to;; time by disabling the movdi patterns.(define_expand "movdi"  [(set (match_operand:DI 0 "nonimmediate_operand" "")	(match_operand:DI 1 "general_operand" ""))]  ""  "{  if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)    operands[1] = copy_to_mode_reg (DImode, operands[1]);  /* Some other ports (as of 2001-09-10 for example mcore and romp) also     prefer to split up constants early, like this.  The testcase in     gcc.c-torture/execute/961213-1.c shows that CSE2 gets confused by the     resulting subreg sets when using the construct from mcore (as of FSF     CVS, version -r 1.5), and it believes that the high part (the last one     emitted) is the final value.  This construct from romp seems more     robust, especially considering the head comments from     emit_no_conflict_block.  */  if ((GET_CODE (operands[1]) == CONST_INT       || GET_CODE (operands[1]) == CONST_DOUBLE)      && ! reload_completed      && ! reload_in_progress)    {      rtx insns;      rtx op0 = operands[0];      rtx op1 = operands[1];      start_sequence ();      emit_move_insn (operand_subword (op0, 0, 1, DImode),		      operand_subword (op1, 0, 1, DImode));      emit_move_insn (operand_subword (op0, 1, 1, DImode),		      operand_subword (op1, 1, 1, DImode));

⌨️ 快捷键说明

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