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

📄 frv.md

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; 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 insrtuction, 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, eg:;;;; (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" ""))]  ""  "{  if (!reload_in_progress      && !reload_completed      && !register_operand (operands[0], QImode)      && !reg_or_0_operand (operands[1], QImode))    operands[1] = copy_to_mode_reg (QImode, operands[1]);}")(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")	(match_operand:QI 1 "move_source_operand"       "L,d,d,O, d, f, f, f,GO"))]  "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")])(define_expand "movhi"  [(set (match_operand:HI 0 "general_operand" "")	(match_operand:HI 1 "general_operand" ""))]  ""  "{  if (!reload_in_progress      && !reload_completed      && !register_operand (operands[0], HImode)      && !reg_or_0_operand (operands[1], HImode))    operands[1] = copy_to_mode_reg (HImode, operands[1]);}")(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")	(match_operand:HI 1 "move_source_operand"       "L,i,d,d,O, d, f, f, f,GO"))]  "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")   (set_attr "type" "int,multi,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf")]);; 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" ""))]  ""  "{  if (frv_emit_movsi (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 flexability (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 cosntants into FPRs are preferable;; even when we're not generating PIC code.(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_internal"  [(set (match_operand:SI 0 "move_destination_operand" "=d,d,d,m,m,z,d,d,f,f,m,?f,?z")	(match_operand:SI 1 "move_source_operand"      "LQ,i,d,d,O,d,z,f,d,f,f,GO,GO"))]  "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")   (set_attr "type" "int,multi,int,gstore,gstore,spr,spr,movfg,movgf,fsconv,fstore,movgf,spr")])(define_insn "*movsi_lda_sdata"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(plus:SI (match_operand:SI 1 "small_data_register_operand" "d")		 (match_operand:SI 2 "small_data_symbolic_operand" "Q")))]  ""  "addi %1, #gprel12(%2), %0"  [(set_attr "type" "int")   (set_attr "length" "4")]);; Split 2 word load of constants into sethi/setlo instructions(define_split  [(set (match_operand:SI 0 "integer_register_operand" "")	(match_operand:SI 1 "int_2word_operand" ""))]  "reload_completed"  [(set (match_dup 0)	(high:SI (match_dup 1)))   (set (match_dup 0)	(lo_sum:SI (match_dup 0)		(match_dup 1)))]  "")(define_insn "movsi_high"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(high:SI (match_operand:SI 1 "int_2word_operand" "i")))]  ""  "sethi #hi(%1), %0"  [(set_attr "type" "sethi")   (set_attr "length" "4")])(define_insn "movsi_lo_sum"  [(set (match_operand:SI 0 "integer_register_operand" "+d")	(lo_sum:SI (match_dup 0)		   (match_operand:SI 1 "int_2word_operand" "i")))]  ""  "setlo #lo(%1), %0"  [(set_attr "type" "setlo")   (set_attr "length" "4")]);; Split loads of addresses with PIC specified into 3 separate instructions(define_insn_and_split "*movsi_pic"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(plus:SI (match_operand:SI 1 "pic_register_operand" "d")		 (match_operand:SI 2 "pic_symbolic_operand" "")))]  ""  "#"  "reload_completed"  [(set (match_dup 0)	(high:SI (match_dup 2)))   (set (match_dup 0)	(lo_sum:SI (match_dup 0)		   (match_dup 2)))   (set (match_dup 0)	(plus:SI (match_dup 0) (match_dup 1)))]  ""  [(set_attr "type" "multi")   (set_attr "length" "12")])(define_insn "movsi_high_pic"  [(set (match_operand:SI 0 "integer_register_operand" "=d")	(high:SI (match_operand:SI 1 "pic_symbolic_operand" "")))]

⌨️ 快捷键说明

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