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

📄 frv.md

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; branch is true and instructions that annul if the branch is false are;; supported.;; Delay slot scheduling differs from instruction scheduling in that;; determining whether an instruction needs a delay slot is dependent only;; on the type of instruction being generated, not on data flow between the;; instructions.  See the next section for a discussion of data-dependent;; instruction scheduling.;; The requirement of an insn needing one or more delay slots is indicated via;; the `define_delay' expression.  It has the following form:;;;; (define_delay TEST;;   [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1;;    DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2;;    ...]);; TEST is an attribute test that indicates whether this `define_delay' applies;; to a particular insn.  If so, the number of required delay slots is;; determined by the length of the vector specified as the second argument.  An;; insn placed in delay slot N must satisfy attribute test DELAY-N.;; ANNUL-TRUE-N is an attribute test that specifies which insns may be annulled;; if the branch is true.  Similarly, ANNUL-FALSE-N specifies which insns in;; the delay slot may be annulled if the branch is false.  If annulling is not;; supported for that delay slot, `(nil)' should be coded.;; For example, in the common case where branch and call insns require a single;; delay slot, which may contain any insn other than a branch or call, the;; following would be placed in the `md' file:;; (define_delay (eq_attr "type" "branch,call");;		 [(eq_attr "type" "!branch,call") (nil) (nil)]);; Multiple `define_delay' expressions may be specified.  In this case, each;; such expression specifies different delay slot requirements and there must;; be no insn for which tests in two `define_delay' expressions are both true.;; For example, if we have a machine that requires one delay slot for branches;; but two for calls, no delay slot can contain a branch or call insn, and any;; valid insn in the delay slot for the branch can be annulled if the branch is;; true, we might represent this as follows:;; (define_delay (eq_attr "type" "branch");;   [(eq_attr "type" "!branch,call");;    (eq_attr "type" "!branch,call");;    (nil)]);;;; (define_delay (eq_attr "type" "call");;   [(eq_attr "type" "!branch,call") (nil) (nil);;    (eq_attr "type" "!branch,call") (nil) (nil)]);; Note - it is the backend's responsibility to fill any unfilled delay slots;; at assembler generation time.  This is usually done by adding a special print;; operand to the delayed instruction, and then in the PRINT_OPERAND function;; calling dbr_sequence_length() to determine how many delay slots were filled.;; For example:;;;; --------------<machine>.md-----------------;; (define_insn "call";;  [(call (match_operand 0 "memory_operand" "m");;         (match_operand 1 "" ""))];;   "";;   "call_delayed %0,%1,%2%#";;  [(set_attr "length" "4");;   (set_attr "type" "call")]);;;; -------------<machine>.h-------------------;; #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#');;;;  ------------<machine>.c------------------;; void;; machine_print_operand (file, x, code);;     FILE * file;;;     rtx    x;;;     int    code;;; {;;   switch (code);;   {;;   case '#':;;     if (dbr_sequence_length () == 0);;       fputs ("\n\tnop", file);;;     return;;; ::::::::::::::::::::;; ::;; :: Notes on Patterns;; ::;; ::::::::::::::::::::;; If you need to construct a sequence of assembler instructions in order;; to implement a pattern be sure to escape any backslashes and double quotes;; that you use, e.g.:;;;; (define_insn "an example";;   [(some rtl)];;   "";;   "*;;    { static char buffer [100];;;      sprintf (buffer, \"insn \\t %d\", REGNO (operands[1]));;;      return buffer;;;    }";; );;;; Also if there is more than one instruction, they can be separated by \\;;; which is a space saving synonym for \\n\\t:;;;; (define_insn "another example";;   [(some rtl)];;   "";;   "*;;    { static char buffer [100];;;      sprintf (buffer, \"insn1 \\t %d\\;insn2 \\t %%1\",;;        REGNO (operands[1]));;;      return buffer;;;    }";; );;;; ::::::::::::::::::::;; ::;; :: Moves;; ::;; ::::::::::::::::::::;; Wrap moves in define_expand to prevent memory->memory moves from being;; generated at the RTL level, which generates better code for most machines;; which can't do mem->mem moves.;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider;; than M, the effect of this instruction is to store the specified value in;; the part of the register that corresponds to mode M.  The effect on the rest;; of the register is undefined.;; This class of patterns is special in several ways.  First of all, each of;; these names *must* be defined, because there is no other way to copy a datum;; from one place to another.;; Second, these patterns are not used solely in the RTL generation pass.  Even;; the reload pass can generate move insns to copy values from stack slots into;; temporary registers.  When it does so, one of the operands is a hard;; register and the other is an operand that can need to be reloaded into a;; register.;; Therefore, when given such a pair of operands, the pattern must;; generate RTL which needs no reloading and needs no temporary;; registers--no registers other than the operands.  For example, if;; you support the pattern with a `define_expand', then in such a;; case the `define_expand' mustn't call `force_reg' or any other such;; function which might generate new pseudo registers.;; This requirement exists even for subword modes on a RISC machine;; where fetching those modes from memory normally requires several;; insns and some temporary registers.  Look in `spur.md' to see how;; the requirement can be satisfied.;; During reload a memory reference with an invalid address may be passed as an;; operand.  Such an address will be replaced with a valid address later in the;; reload pass.  In this case, nothing may be done with the address except to;; use it as it stands.  If it is copied, it will not be replaced with a valid;; address.  No attempt should be made to make such an address into a valid;; address and no routine (such as `change_address') that will do so may be;; called.  Note that `general_operand' will fail when applied to such an;; address.;;;; The global variable `reload_in_progress' (which must be explicitly declared;; if required) can be used to determine whether such special handling is;; required.;;;; The variety of operands that have reloads depends on the rest of;; the machine description, but typically on a RISC machine these can;; only be pseudo registers that did not get hard registers, while on;; other machines explicit memory references will get optional;; reloads.;;;; If a scratch register is required to move an object to or from memory, it;; can be allocated using `gen_reg_rtx' prior to reload.  But this is;; impossible during and after reload.  If there are cases needing scratch;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide;; patterns `reload_inM' or `reload_outM' to handle them.;; The constraints on a `moveM' must permit moving any hard register to any;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a;; value of 2.;; It is obligatory to support floating point `moveM' instructions;; into and out of any registers that can hold fixed point values,;; because unions and structures (which have modes `SImode' or;; `DImode') can be in those registers and they may have floating;; point members.;; There may also be a need to support fixed point `moveM' instructions in and;; out of floating point registers.  Unfortunately, I have forgotten why this;; was so, and I don't know whether it is still true.  If `HARD_REGNO_MODE_OK';; rejects fixed point values in floating point registers, then the constraints;; of the fixed point `moveM' instructions must be designed to avoid ever;; trying to reload into a floating point register.(define_expand "movqi"  [(set (match_operand:QI 0 "general_operand" "")	(match_operand:QI 1 "general_operand" ""))]  ""  "{ frv_emit_move (QImode, operands[0], operands[1]); DONE; }")(define_insn "*movqi_load"  [(set (match_operand:QI 0 "register_operand" "=d,f")	(match_operand:QI 1 "frv_load_operand" "m,m"))]  ""  "* return output_move_single (operands, insn);"  [(set_attr "length" "4")   (set_attr "type" "gload,fload")])(define_insn "*movqi_internal"  [(set (match_operand:QI 0 "move_destination_operand" "=d,d,m,m,?f,?f,?d,?m,f,d,f")	(match_operand:QI 1 "move_source_operand"       "L,d,d,O, d, f, f, f,GO,!m,!m"))]  "register_operand(operands[0], QImode) || reg_or_0_operand (operands[1], QImode)"  "* return output_move_single (operands, insn);"  [(set_attr "length" "4")   (set_attr "type" "int,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")])(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{ frv_emit_move (HImode, operands[0], operands[1]); DONE; }")(define_insn "*movhi_load"  [(set (match_operand:HI 0 "register_operand" "=d,f")	(match_operand:HI 1 "frv_load_operand" "m,m"))]  ""  "* return output_move_single (operands, insn);"  [(set_attr "length" "4")   (set_attr "type" "gload,fload")])(define_insn "*movhi_internal"  [(set (match_operand:HI 0 "move_destination_operand" "=d,d,d,m,m,?f,?f,?d,?m,f,d,f")	(match_operand:HI 1 "move_source_operand"       "L,n,d,d,O, d, f, f, f,GO,!m,!m"))]  "register_operand(operands[0], HImode) || reg_or_0_operand (operands[1], HImode)"  "* return output_move_single (operands, insn);"  [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4")   (set_attr "type" "int,multi,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")]);; Split 2 word load of constants into sethi/setlo instructions(define_split  [(set (match_operand:HI 0 "integer_register_operand" "")	(match_operand:HI 1 "int_2word_operand" ""))]  "reload_completed"  [(set (match_dup 0)	(high:HI (match_dup 1)))   (set (match_dup 0)	(lo_sum:HI (match_dup 0)		(match_dup 1)))]  "")(define_insn "movhi_high"  [(set (match_operand:HI 0 "integer_register_operand" "=d")	(high:HI (match_operand:HI 1 "int_2word_operand" "i")))]  ""  "sethi #hi(%1), %0"  [(set_attr "type" "sethi")   (set_attr "length" "4")])(define_insn "movhi_lo_sum"  [(set (match_operand:HI 0 "integer_register_operand" "+d")	(lo_sum:HI (match_dup 0)		   (match_operand:HI 1 "int_2word_operand" "i")))]  ""  "setlo #lo(%1), %0"  [(set_attr "type" "setlo")   (set_attr "length" "4")])(define_expand "movsi"  [(set (match_operand:SI 0 "move_destination_operand" "")	(match_operand:SI 1 "move_source_operand" ""))]  ""  "{ frv_emit_move (SImode, operands[0], operands[1]); DONE; }");; Note - it is best to only have one movsi pattern and to handle;; all the various contingencies by the use of alternatives.  This;; allows reload the greatest amount of flexibility (since reload will;; only choose amoungst alternatives for a selected insn, it will not;; replace the insn with another one).;; Unfortunately, we do have to separate out load-type moves from the rest,;; and only allow memory source operands in the former.  If we do memory and;; constant loads in a single pattern, reload will be tempted to force;; constants into memory when the destination is a floating-point register.;; That may make a function use a PIC pointer when it didn't before, and we;; cannot change PIC usage (and hence stack layout) so late in the game.;; The resulting sequences for loading constants into FPRs are preferable;; even when we're not generating PIC code.;; However, if we don't accept input from memory at all in the generic;; movsi pattern, reloads for asm instructions that reference pseudos;; that end up assigned to memory will fail to match, because we;; recognize them right after they're emitted, and we don't;; re-recognize them again after the substitution for memory.  So keep;; a memory constraint available, just make sure reload won't be;; tempted to use it.;;		   		   (define_insn "*movsi_load"  [(set (match_operand:SI 0 "register_operand" "=d,f")	(match_operand:SI 1 "frv_load_operand" "m,m"))]  ""  "* return output_move_single (operands, insn);"  [(set_attr "length" "4")   (set_attr "type" "gload,fload")])(define_insn "*movsi_got"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(match_operand:SI 1 "got12_operand" ""))]  ""  "addi gr0, %1, %0"  [(set_attr "type" "int")   (set_attr "length" "4")])(define_insn "*movsi_high_got"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(high:SI (match_operand:SI 1 "const_unspec_operand" "")))]  ""  "sethi %1, %0"  [(set_attr "type" "sethi")   (set_attr "length" "4")])(define_insn "*movsi_lo_sum_got"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(lo_sum:SI (match_operand:SI 1 "integer_register_operand" "0")		   (match_operand:SI 2 "const_unspec_operand" "")))]  ""  "setlo %2, %0"  [(set_attr "type" "setlo")   (set_attr "length" "4")])(define_insn "*movsi_internal"  [(set (match_operand:SI 0 "move_destination_operand" "=d,d,d,m,m,z,d,d,f,f,m,?f,?z,d,f")	(match_operand:SI 1 "move_source_operand"      "L,n,d,d,O,d,z,f,d,f,f,GO,GO,!m,!m"))]  "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)"  "* return output_move_single (operands, insn);"  [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4,4,4,4")   (set_attr "type" "int,multi,int,gstore,gstore,spr,spr,movfg,movgf,fsconv,fstore,movgf,spr,gload,fload")]);; Split 2 wor

⌨️ 快捷键说明

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