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

📄 sparc.md

📁 gcc库的原代码,对编程有很大帮助.
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description for SPARC chip for GNU C compiler;;  Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.;;  Contributed by Michael Tiemann (tiemann@cygnus.com);;  64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,;;  at Cygnus Support.;; 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.;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of;; 'f' for all DF/TFmode values, including those that are specific to the v8.;; Architecture type.  Arch32bit includes v7, sparclite, v8.(define_attr "arch" "arch32bit,arch64bit"  (const (symbol_ref "sparc_arch_type")));; CPU type. This is only used for instruction scheduling(define_attr "cpu" "cypress,supersparc" (const  (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")]	(const_string "cypress"))));; Insn type.  Used to default other attribute values.;; type "unary" insns have one input operand (1) and one output operand (0);; type "binary" insns have two input operands (1,2) and one output (0);; type "compare" insns have one or two input operands (0,1) and no output;; type "call_no_delay_slot" is a call followed by an unimp instruction.(define_attr "type"  "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"  (const_string "binary"));; Set true if insn uses call-clobbered intermediate register.(define_attr "use_clobbered" "false,true"  (if_then_else (and (eq_attr "type" "address")		     (match_operand 0 "clobbered_register" ""))	 	(const_string "true")		(const_string "false")));; Length (in # of insns).(define_attr "length" ""  (cond [(eq_attr "type" "load,fpload")	 (if_then_else (match_operand 1 "symbolic_memory_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "store,fpstore")	 (if_then_else (match_operand 0 "symbolic_memory_operand" "")		       (const_int 2) (const_int 1))	 (eq_attr "type" "address") (const_int 2)	 (eq_attr "type" "binary")	 (if_then_else (ior (match_operand 2 "arith_operand" "")			    (match_operand 2 "arith_double_operand" ""))		       (const_int 1) (const_int 3))	 (eq_attr "type" "multi") (const_int 2)	 (eq_attr "type" "move,unary")	 (if_then_else (ior (match_operand 1 "arith_operand" "")			    (match_operand 1 "arith_double_operand" ""))		       (const_int 1) (const_int 2))]	(const_int 1)))(define_asm_attributes  [(set_attr "length" "1")   (set_attr "type" "multi")]);; Attributes for instruction and branch scheduling(define_attr "in_call_delay" "false,true"  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")	 	(const_string "false")	 (eq_attr "type" "load,fpload,store,fpstore")	 	(if_then_else (eq_attr "length" "1")			      (const_string "true")			      (const_string "false"))	 (eq_attr "type" "address")	 	(if_then_else (eq_attr "use_clobbered" "false")			      (const_string "true")			      (const_string "false"))]	(if_then_else (eq_attr "length" "1")		      (const_string "true")		      (const_string "false"))))(define_delay (eq_attr "type" "call")  [(eq_attr "in_call_delay" "true") (nil) (nil)]);; ??? Should implement the notion of predelay slots for floating point;; branches.  This would allow us to remove the nop always inserted before;; a floating point branch.;; ??? It is OK for fill_simple_delay_slots to put load/store instructions;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.;; This is because doing so will add several pipeline stalls to the path;; that the load/store did not come from.  Unfortunately, there is no way;; to prevent fill_eager_delay_slots from using load/store without completely;; disabling them.  For the SPEC benchmark set, this is a serious lose,;; because it prevents us from moving back the final store of inner loops.(define_attr "in_branch_delay" "false,true"  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")		     (eq_attr "length" "1"))		(const_string "true")		(const_string "false")))(define_attr "in_uncond_branch_delay" "false,true"  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")		     (eq_attr "length" "1"))		(const_string "true")		(const_string "false")))(define_attr "in_annul_branch_delay" "false,true"  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")		     (eq_attr "length" "1"))		(const_string "true")		(const_string "false")))(define_delay (eq_attr "type" "branch")  [(eq_attr "in_branch_delay" "true")   (nil) (eq_attr "in_annul_branch_delay" "true")])(define_delay (eq_attr "type" "uncond_branch")  [(eq_attr "in_uncond_branch_delay" "true")   (nil) (nil)])   ;; Function units of the SPARC;; (define_function_unit {name} {num-units} {n-users} {test};;                       {ready-delay} {issue-delay} [{conflict-list}]);; The integer ALU.;; (Noted only for documentation; units that take one cycle do not need to;; be specified.);; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on;; the inputs.;; (define_function_unit "alu" 1 0;;  (eq_attr "type" "unary,binary,move,address") 1 0);; ---- cypress CY7C602 scheduling:;; Memory with load-delay of 1 (i.e., 2 cycle load).(define_function_unit "memory" 1 0   (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2);; SPARC has two floating-point units: the FP ALU,;; and the FP MUL/DIV/SQRT unit.;; Instruction timings on the CY7C602 are as follows;; FABSs	4;; FADDs/d	5/5;; FCMPs/d	4/4;; FDIVs/d	23/37;; FMOVs	4;; FMULs/d	5/7;; FNEGs	4;; FSQRTs/d	34/63;; FSUBs/d	5/5;; FdTOi/s	5/5;; FsTOi/d	5/5;; FiTOs/d	9/5;; The CY7C602 can only support 2 fp isnsn simultaneously.;; More insns cause the chip to stall.(define_function_unit "fp_alu" 1 0  (and (eq_attr "type" "fp")            (eq_attr "cpu" "cypress")) 5 5)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpmul")         (eq_attr "cpu" "cypress")) 7 7)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpsqrt")        (eq_attr "cpu" "cypress")) 63 63);; ----- The TMS390Z55 scheduling;; The Supersparc can issue 1 - 3 insns per cycle; here we assume;; three insns/cycle, and hence multiply all costs by three.;; Combinations up to two integer, one ld/st, one fp.;; Memory delivers its result in one cycle to IU, zero cycles to FP(define_function_unit "memory" 1 0  (and (eq_attr "type" "load")          (eq_attr "cpu" "supersparc")) 3 3)(define_function_unit "memory" 1 0  (and (eq_attr "type" "fpload")        (eq_attr "cpu" "supersparc")) 1 3);; at least one in three instructions can be a mem opt.(define_function_unit "memory" 1 0  (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3);; at least one in three instructions can be a shift op.(define_function_unit "shift" 1 0  (and (eq_attr "type" "shift")         (eq_attr "cpu" "supersparc")) 1 3);; There are only two write ports to the integer register file;; A store also uses a write port(define_function_unit "iwport" 2 0  (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3);; Timings; throughput/latency;; FADD     1/3    add/sub, format conv, compar, abs, neg;; FMUL     1/3;; FDIVs    4/6;; FDIVd    7/9;; FSQRTs   6/8;; FSQRTd  10/12;; IMUL     4/4(define_function_unit "fp_alu" 1 0  (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpmul")    (eq_attr "cpu" "supersparc")) 9 3)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpdivs")   (eq_attr "cpu" "supersparc")) 18 12)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpdivd")   (eq_attr "cpu" "supersparc")) 27 21)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "fpsqrt")   (eq_attr "cpu" "supersparc")) 36 30)(define_function_unit "fp_mds" 1 0  (and (eq_attr "type" "imul")     (eq_attr "cpu" "supersparc")) 12 12);; Compare instructions.;; This controls RTL generation and register allocation.;; We generate RTL for comparisons and branches by having the cmpxx ;; patterns store away the operands.  Then, the scc and bcc patterns;; emit RTL for both the compare and the branch.;;;; We do this because we want to generate different code for an sne and;; seq insn.  In those cases, if the second operand of the compare is not;; const0_rtx, we want to compute the xor of the two operands and test;; it against zero.;;;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc;; insns that actually require more than one machine instruction.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.(define_expand "cmpsi"  [(set (reg:CC 0)	(compare:CC (match_operand:SI 0 "register_operand" "")		    (match_operand:SI 1 "arith_operand" "")))]  ""  "{  sparc_compare_op0 = operands[0];  sparc_compare_op1 = operands[1];  DONE;}")(define_expand "cmpdi"  [(set (reg:CCX 0)	(compare:CCX (match_operand:DI 0 "register_operand" "")		     (match_operand:DI 1 "arith_double_operand" "")))]  "TARGET_V9"  "{  sparc_compare_op0 = operands[0];  sparc_compare_op1 = operands[1];  DONE;}")(define_expand "cmpsf"  [(set (reg:CCFP 0)	(compare:CCFP (match_operand:SF 0 "register_operand" "")		      (match_operand:SF 1 "register_operand" "")))]  "TARGET_FPU"  "{  sparc_compare_op0 = operands[0];  sparc_compare_op1 = operands[1];  DONE;}")(define_expand "cmpdf"  [(set (reg:CCFP 0)	(compare:CCFP (match_operand:DF 0 "register_operand" "")		      (match_operand:DF 1 "register_operand" "")))]  "TARGET_FPU"  "{  sparc_compare_op0 = operands[0];  sparc_compare_op1 = operands[1];  DONE;}")(define_expand "cmptf"  [(set (reg:CCFP 0)	(compare:CCFP (match_operand:TF 0 "register_operand" "")		      (match_operand:TF 1 "register_operand" "")))]  "TARGET_FPU"  "{  sparc_compare_op0 = operands[0];  sparc_compare_op1 = operands[1];  DONE;}");; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use;; the same code as v8 (the addx/subx method has more applications).  The;; exception to this is "reg != 0" which can be done in one instruction on v9;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do;; branches.;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they;; generate addcc/subcc instructions.(define_expand "seqsi_special"  [(set (match_dup 3)	(xor:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "register_operand" "")))   (parallel [(set (match_operand:SI 0 "register_operand" "")		   (eq:SI (match_dup 3) (const_int 0)))	      (clobber (reg:CC 0))])]  ""  "{ operands[3] = gen_reg_rtx (SImode); }")(define_expand "seqdi_special"  [(set (match_dup 3)	(xor:DI (match_operand:DI 1 "register_operand" "")		(match_operand:DI 2 "register_operand" "")))   (parallel [(set (match_operand:DI 0 "register_operand" "")		   (eq:DI (match_dup 3) (const_int 0)))	      (clobber (reg:CCX 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }")(define_expand "snesi_special"  [(set (match_dup 3)	(xor:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "register_operand" "")))   (parallel [(set (match_operand:SI 0 "register_operand" "")		   (ne:SI (match_dup 3) (const_int 0)))	      (clobber (reg:CC 0))])]  ""  "{ operands[3] = gen_reg_rtx (SImode); }")(define_expand "snedi_special"  [(set (match_dup 3)	(xor:DI (match_operand:DI 1 "register_operand" "")		(match_operand:DI 2 "register_operand" "")))   (parallel [(set (match_operand:DI 0 "register_operand" "")		   (ne:DI (match_dup 3) (const_int 0)))	      (clobber (reg:CCX 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }")(define_expand "seqdi_special_trunc"  [(set (match_dup 3)	(xor:DI (match_operand:DI 1 "register_operand" "")		(match_operand:DI 2 "register_operand" "")))   (parallel [(set (match_operand:SI 0 "register_operand" "")		   (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0)))	      (clobber (reg:CC 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }")(define_expand "snedi_special_trunc"  [(set (match_dup 3)	(xor:DI (match_operand:DI 1 "register_operand" "")		(match_operand:DI 2 "register_operand" "")))   (parallel [(set (match_operand:SI 0 "register_operand" "")		   (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0)))	      (clobber (reg:CC 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }")(define_expand "seqsi_special_extend"  [(set (subreg:SI (match_dup 3) 0)	(xor:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "register_operand" "")))   (parallel [(set (match_operand:DI 0 "register_operand" "")		   (eq:DI (match_dup 3) (const_int 0)))	      (clobber (reg:CCX 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }")(define_expand "snesi_special_extend"  [(set (subreg:SI (match_dup 3) 0)	(xor:SI (match_operand:SI 1 "register_operand" "")		(match_operand:SI 2 "register_operand" "")))   (parallel [(set (match_operand:DI 0 "register_operand" "")		   (ne:DI (match_dup 3) (const_int 0)))	      (clobber (reg:CCX 0))])]  ""  "{ operands[3] = gen_reg_rtx (DImode); }");; ??? v9: Operand 0 needs a mode, so SImode was chosen.;; However, the code handles both SImode and DImode.(define_expand "seq"  [(set (match_operand:SI 0 "intreg_operand" "")	(eq:SI (match_dup 1) (const_int 0)))]  ""  "{  if (GET_MODE (sparc_compare_op0) == SImode)    {      rtx pat;

⌨️ 快捷键说明

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