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

📄 alpha.md

📁 GCC编译器源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; Machine description for DEC Alpha for GNU C compiler;; Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu);; 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.;; Processor type -- this attribute must exactly match the processor_type;; enumeration in alpha.h.(define_attr "cpu" "ev4,ev5,ev6"  (const (symbol_ref "alpha_cpu")));; Define an insn type attribute.  This is used in function unit delay;; computations, among other purposes.  For the most part, we use the names;; defined in the EV4 documentation, but add a few that we have to know about;; separately.(define_attr "type"  "ld,st,ibr,fbr,jsr,iadd,ilog,shift,cmov,icmp,imull,imulq,fadd,fmul,fcpys,fdivs,fdivt,ldsym,isubr"  (const_string "iadd"));; The TRAP_TYPE attribute marks instructions that may generate traps;; (which are imprecise and may need a trapb if software completion;; is desired).(define_attr "trap" "yes,no" (const_string "no"));; For the EV4 we include four function units: ABOX, which computes the address,;; BBOX, used for branches, EBOX, used for integer operations, and FBOX,;; used for FP operations.;;;; We assume that we have been successful in getting double issues and;; hence multiply all costs by two insns per cycle.  The minimum time in;; a function unit is 2 cycle, which will tend to produce the double;; issues.;; Memory delivers its result in three cycles.(define_function_unit "ev4_abox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "ld,st"))  6 2);; Branches have no delay cost, but do tie up the unit for two cycles.(define_function_unit "ev4_bbox" 1 1  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "ibr,fbr,jsr"))  4 4);; Arithmetic insns are normally have their results available after two;; cycles.  There are a number of exceptions.  They are encoded in;; ADJUST_COST.  Some of the other insns have similar exceptions.(define_function_unit "ev4_ebox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "iadd,ilog,ldsym,shift,cmov,icmp"))  4 2);; These really don't take up the integer pipeline, but they do occupy;; IBOX1; we approximate here.(define_function_unit "ev4_ebox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "imull"))  42 2)(define_function_unit "ev4_ebox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "imulq"))  46 2)(define_function_unit "ev4_imult" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "imull"))  42 38)(define_function_unit "ev4_imult" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "imulq"))  46 42)(define_function_unit "ev4_fbox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "fadd,fmul,fcpys"))  12 2)(define_function_unit "ev4_fbox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "fdivs"))  68 0)(define_function_unit "ev4_fbox" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "fdivt"))  126 0)(define_function_unit "ev4_divider" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "fdivs"))  68 60)(define_function_unit "ev4_divider" 1 0  (and (eq_attr "cpu" "ev4")       (eq_attr "type" "fdivt"))  126 118);; EV5 scheduling.  EV5 can issue 4 insns per clock.;; Multiply all costs by 4.  We consider the EV6 and EV5 for now.;; EV5 has two integer units.(define_function_unit "ev5_ebox" 2 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "iadd,ilog,icmp,ldsym"))  4 4);; Memory takes at least 2 clocks.;; Conditional moves always take 2 ticks.(define_function_unit "ev5_ebox" 2 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "ld,cmov"))  8 4);; Loads can dual issue.  Store cannot; nor can loads + stores.;; Model this with a mythical load/store unit.(define_function_unit "ev5_ldst" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "ld"))  8 4 [(eq_attr "type" "st")])(define_function_unit "ev5_ldst" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "st"))  4 4)(define_function_unit "ev5_ebox" 2 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "imull"))  32 4)(define_function_unit "ev5_ebox" 2 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "imulq"))  48 4);; Multiplies also use the integer multiplier.(define_function_unit "ev5_imult" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "imull"))  16 8)(define_function_unit "ev5_imult" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "imulq"))  48 32);; There is only 1 shifter/zapper.(define_function_unit "ev5_shift" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "shift"))  4 4);; We pretend EV5 has symmetrical 2 fpus,;; even though cpys is the only insn that can issue on either unit.(define_function_unit "ev5_fpu" 2 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fadd,fmul,fcpys"))  16 4)  ;; Multiplies (resp. adds) also use the fmul (resp. fadd) units.(define_function_unit "ev5_fpmul" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fmul"))  16 4)(define_function_unit "ev5_fpadd" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fadd"))  16 4)(define_function_unit "ev5_fpadd" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fbr"))  4 4)(define_function_unit "ev5_fpadd" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fdivs"))  60 4)(define_function_unit "ev5_fpadd" 1 0  (and (eq_attr "cpu" "ev5,ev6")       (eq_attr "type" "fdivt"))  88 4);; First define the arithmetic insns.  Note that the 32-bit forms also;; sign-extend.;; Note that we can do sign extensions in both FP and integer registers.;; However, the result must be in the same type of register as the input.;; The register preferencing code can't handle this case very well, so, for;; now, don't let the FP case show up here for preferencing.  Also,;; sign-extends in FP registers take two instructions.(define_insn "extendsidi2"  [(set (match_operand:DI 0 "register_operand" "=r,r,*f")	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))]  ""  "@   addl %1,$31,%0   ldl %0,%1   cvtql %1,%0\;cvtlq %0,%0"  [(set_attr "type" "iadd,ld,fadd")]);; Do addsi3 the way expand_binop would do if we didn't have one.  This;; generates better code.  We have the anonymous addsi3 pattern below in;; case combine wants to make it.(define_expand "addsi3"  [(set (match_operand:SI 0 "register_operand" "")	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")		 (match_operand:SI 2 "add_operand" "")))]  ""  "{ emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),		      gen_rtx (PLUS, DImode,			       gen_lowpart (DImode, operands[1]),			       gen_lowpart (DImode, operands[2]))));  DONE;} ")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")		 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]  ""  "@   addl %r1,%2,%0   subl %r1,%n2,%0   lda %0,%2(%r1)   ldah %0,%h2(%r1)")(define_split  [(set (match_operand:SI 0 "register_operand" "")	(plus:SI (match_operand:SI 1 "register_operand" "")		 (match_operand:SI 2 "const_int_operand" "")))]  "! add_operand (operands[2], SImode)"  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]  "{  HOST_WIDE_INT val = INTVAL (operands[2]);  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);  HOST_WIDE_INT rest = val - low;  operands[3] = GEN_INT (rest);  operands[4] = GEN_INT (low);}")(define_insn ""  [(set (match_operand:DI 0 "register_operand" "=r,r")	(sign_extend:DI	 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")		  (match_operand:SI 2 "sext_add_operand" "rI,O"))))]  ""  "@   addl %r1,%2,%0   subl %r1,%n2,%0")(define_split  [(set (match_operand:DI 0 "register_operand" "")	(sign_extend:DI	 (plus:SI (match_operand:SI 1 "register_operand" "")		  (match_operand:SI 2 "const_int_operand" ""))))   (clobber (match_operand:SI 3 "register_operand" ""))]  "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0   && INTVAL (operands[2]) % 4 == 0"  [(set (match_dup 3) (match_dup 4))   (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)							(match_dup 5))					       (match_dup 1))))]  "{  HOST_WIDE_INT val = INTVAL (operands[2]) / 4;  int mult = 4;  if (val % 2 == 0)    val /= 2, mult = 8;  operands[4] = GEN_INT (val);  operands[5] = GEN_INT (mult);}")(define_split  [(set (match_operand:DI 0 "register_operand" "")	(sign_extend:DI	 (plus:SI (match_operator:SI 1 "comparison_operator"				     [(match_operand 2 "" "")				      (match_operand 3 "" "")])		  (match_operand:SI 4 "add_operand" ""))))   (clobber (match_operand:DI 5 "register_operand" ""))]  ""  [(set (match_dup 5) (match_dup 6))   (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]  "{  operands[6] = gen_rtx (GET_CODE (operands[1]), DImode,			 operands[2], operands[3]);  operands[7] = gen_lowpart (SImode, operands[5]);}")(define_insn "adddi3"  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")		 (match_operand:DI 2 "add_operand" "rI,O,K,L")))]  ""  "@   addq %r1,%2,%0   subq %r1,%n2,%0   lda %0,%2(%r1)   ldah %0,%h2(%r1)");; Don't do this if we are adjusting SP since we don't want to do;; it in two steps. (define_split  [(set (match_operand:DI 0 "register_operand" "")	(plus:DI (match_operand:DI 1 "register_operand" "")		 (match_operand:DI 2 "const_int_operand" "")))]  "! add_operand (operands[2], DImode)   && REGNO (operands[0]) != STACK_POINTER_REGNUM"  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]  "{  HOST_WIDE_INT val = INTVAL (operands[2]);  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);  HOST_WIDE_INT rest = val - low;  operands[3] = GEN_INT (rest);  operands[4] = GEN_INT (low);}")(define_insn ""  [(set (match_operand:SI 0 "register_operand" "=r,r")	(plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")			  (match_operand:SI 2 "const48_operand" "I,I"))		 (match_operand:SI 3 "sext_add_operand" "rI,O")))]  ""  "@   s%2addl %r1,%3,%0   s%2subl %r1,%n3,%0")(define_insn ""  [(set (match_operand:DI 0 "register_operand" "=r,r")	(sign_extend:DI	 (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")			   (match_operand:SI 2 "const48_operand" "I,I"))		  (match_operand:SI 3 "sext_add_operand" "rI,O"))))]  ""  "@   s%2addl %r1,%3,%0   s%2subl %r1,%n3,%0")(define_split  [(set (match_operand:DI 0 "register_operand" "")	(sign_extend:DI	 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"					      [(match_operand 2 "" "")					       (match_operand 3 "" "")])			   (match_operand:SI 4 "const48_operand" ""))		  (match_operand:SI 5 "add_operand" ""))))   (clobber (match_operand:DI 6 "register_operand" ""))]  ""  [(set (match_dup 6) (match_dup 7))   (set (match_dup 0)	(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))				 (match_dup 5))))]  "{  operands[7] = gen_rtx (GET_CODE (operands[1]), DImode,			 operands[2], operands[3]);  operands[8] = gen_lowpart (SImode, operands[6]);}")(define_insn ""  [(set (match_operand:DI 0 "register_operand" "=r,r")	(plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")			  (match_operand:DI 2 "const48_operand" "I,I"))		 (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]  ""  "@   s%2addq %r1,%3,%0   s%2subq %1,%n3,%0");; These variants of the above insns can occur if the third operand;; is the frame pointer.  This is a kludge, but there doesn't;; seem to be a way around it.  Only recognize them while reloading.(define_insn ""  [(set (match_operand:DI 0 "some_operand" "=&r")	(plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")			  (match_operand:DI 2 "some_operand" "r"))		 (match_operand:DI 3 "some_operand" "rIOKL")))]  "reload_in_progress"  "#")(define_split  [(set (match_operand:DI 0 "register_operand" "")	(plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")			  (match_operand:DI 2 "register_operand" ""))		 (match_operand:DI 3 "add_operand" "")))]  "reload_completed"  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]  "")					   (define_insn ""

⌨️ 快捷键说明

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