sparc.md
来自「GCC编译器源代码」· Markdown 代码 · 共 2,069 行 · 第 1/5 页
MD
2,069 行
;;- Machine description for SPARC chip for GNU C compiler;; Copyright (C) 1987, 88, 89, 92-96, 1997 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.;;;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.;; Attribute for cpu type.;; These must match the values for enum processor_type in sparc.h.(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v8plus,v9,ultrasparc" (const (symbol_ref "sparc_cpu_attr")));; Attribute for the instruction set.;; At present we only need to distinguish v9/!v9, but for clarity we;; test TARGET_V8 too.(define_attr "isa" "v6,v8,v9,sparclet" (const (cond [(symbol_ref "TARGET_V9") (const_string "v9") (symbol_ref "TARGET_V8") (const_string "v8") (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")] (const_string "v6"))));; Architecture size.(define_attr "arch" "arch32bit,arch64bit" (const (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")] (const_string "arch32bit"))));; Whether -mlive-g0 is in effect.(define_attr "live_g0" "no,yes" (const (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")] (const_string "no"))));; 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);; ----- sparclet tsc701 scheduling;; The tsc701 issues 1 insn per cycle.;; Results may be written back out of order.;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.(define_function_unit "tsc701_load" 4 1 (and (eq_attr "type" "load") (eq_attr "cpu" "tsc701")) 3 1);; Stores take 2(?) extra cycles to complete.;; It is desirable to not have any memory operation in the following 2 cycles.;; (??? or 2 memory ops in the case of std).(define_function_unit "tsc701_store" 1 0 (and (eq_attr "type" "store") (eq_attr "cpu" "tsc701")) 3 3 [(eq_attr "type" "load,store")]);; The multiply unit has a latency of 5.(define_function_unit "tsc701_mul" 1 0 (and (eq_attr "type" "imul") (eq_attr "cpu" "tsc701")) 5 5);; ----- The UltraSPARC-1 scheduling;; The Ultrasparc can issue 1 - 4 insns per cycle; here we assume;; four insns/cycle, and hence multiply all costs by four.;; Memory delivers its result in three cycles to IU, three cycles to FP(define_function_unit "memory" 1 0 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "ultrasparc")) 12 4)(define_function_unit "memory" 1 0 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "ultrasparc")) 4 4)(define_function_unit "ieu" 1 0 (and (eq_attr "type" "ialu") (eq_attr "cpu" "ultrasparc")) 1 2)(define_function_unit "ieu" 1 0 (and (eq_attr "type" "shift") (eq_attr "cpu" "ultrasparc")) 1 4)(define_function_unit "ieu" 1 0 (and (eq_attr "type" "cmove") (eq_attr "cpu" "ultrasparc")) 8 4);; Timings; throughput/latency;; ?? FADD 1/3 add/sub, format conv, compar, abs, neg;; ?? FMUL 1/3;; ?? FDIVs 1/12;; ?? FDIVd 1/22;; ?? FSQRTs 1/12;; ?? FSQRTd 1/22(define_function_unit "fp" 1 0 (and (eq_attr "type" "fp") (eq_attr "cpu" "ultrasparc")) 12 2)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpcmp") (eq_attr "cpu" "ultrasparc")) 8 2)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "ultrasparc")) 12 2)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "ultrasparc")) 48 2)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "ultrasparc")) 88 2)(define_function_unit "fp" 1 0 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "ultrasparc")) 48 2);; 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 100) (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 100) (compare:CCX (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] "TARGET_ARCH64" "{ sparc_compare_op0 = operands[0]; sparc_compare_op1 = operands[1]; DONE;}")(define_expand "cmpsf" ;; The 96 here isn't ever used by anyone. [(set (reg:CCFP 96) (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" ;; The 96 here isn't ever used by anyone. [(set (reg:CCFP 96) (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" ;; The 96 here isn't ever used by anyone. [(set (reg:CCFP 96) (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;}");; Now the compare DEFINE_INSNs.(define_insn "*cmpsi_insn" [(set (reg:CC 100) (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")))] "" "cmp %0,%1" [(set_attr "type" "compare")])(define_insn "*cmpdi_sp64" [(set (reg:CCX 100) (compare:CCX (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_double_operand" "rHI")))] "TARGET_ARCH64" "cmp %0,%1" [(set_attr "type" "compare")])(define_insn "*cmpsf_fpe" [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?