📄 alpha.md
字号:
;; Machine description for DEC Alpha for GNU C compiler;; Copyright (C) 1992, 1993, 1994, 1995 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.;; 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,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym,isubr" (const_string "shiftcm"));; 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 "abox" 1 0 (eq_attr "type" "ld,ldsym,st") 6 2);; Branches have no delay cost, but do tie up the unit for two cycles.(define_function_unit "bbox" 1 1 (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 "ebox" 1 0 (eq_attr "type" "iaddlog,shiftcm,icmp") 4 2);; These really don't take up the integer pipeline, but they do occupy;; IBOX1; we approximate here.(define_function_unit "ebox" 1 0 (eq_attr "type" "imull") 42 2)(define_function_unit "ebox" 1 0 (eq_attr "type" "imulq") 46 2)(define_function_unit "imult" 1 0 (eq_attr "type" "imull") 42 38)(define_function_unit "imult" 1 0 (eq_attr "type" "imulq") 46 42)(define_function_unit "fbox" 1 0 (eq_attr "type" "fpop") 12 2)(define_function_unit "fbox" 1 0 (eq_attr "type" "fdivs") 68 0)(define_function_unit "fbox" 1 0 (eq_attr "type" "fdivt") 126 0)(define_function_unit "divider" 1 0 (eq_attr "type" "fdivs") 68 60)(define_function_unit "divider" 1 0 (eq_attr "type" "fdivt") 126 118);; 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" "iaddlog,ld,fpop")]);; 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)" [(set_attr "type" "iaddlog")])(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" [(set_attr "type" "iaddlog")])(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)" [(set_attr "type" "iaddlog")]);; 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" [(set_attr "type" "iaddlog")])(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" [(set_attr "type" "iaddlog")])(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" [(set_attr "type" "iaddlog")]);; 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" "#" [(set_attr "type" "iaddlog")])(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 "" [(set (match_operand:SI 0 "some_operand" "=&r") (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "some_operand" "r")) (match_operand:SI 4 "some_operand" "rIOKL")))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")])(define_split [(set (match_operand:SI 0 "register_operand" "r") (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") (match_operand:SI 2 "const48_operand" "")) (match_operand:SI 3 "register_operand" "")) (match_operand:SI 4 "add_operand" "rIOKL")))] "reload_completed" [(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] "")(define_insn "" [(set (match_operand:DI 0 "some_operand" "=&r") (sign_extend:DI (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "some_operand" "r")) (match_operand:SI 4 "some_operand" "rIOKL"))))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")])(define_split [(set (match_operand:DI 0 "register_operand" "") (sign_extend:DI (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") (match_operand:SI 2 "const48_operand" "")) (match_operand:SI 3 "register_operand" "")) (match_operand:SI 4 "add_operand" ""))))] "reload_completed" [(set (match_dup 5) (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))] "{ operands[5] = gen_lowpart (SImode, operands[0]);}")(define_insn "" [(set (match_operand:DI 0 "some_operand" "=&r") (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ") (match_operand:DI 2 "const48_operand" "I")) (match_operand:DI 3 "some_operand" "r")) (match_operand:DI 4 "some_operand" "rIOKL")))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")])(define_split [(set (match_operand:DI 0 "register_operand" "=") (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "") (match_operand:DI 2 "const48_operand" "")) (match_operand:DI 3 "register_operand" "")) (match_operand:DI 4 "add_operand" "")))] "reload_completed" [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] "")(define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] "" "subl $31,%1,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))] "" "subl $31,%1,%0" [(set_attr "type" "iaddlog")])(define_insn "negdi2" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] "" "subq $31,%1,%0" [(set_attr "type" "iaddlog")])(define_expand "subsi3" [(set (match_operand:SI 0 "register_operand" "") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") (match_operand:SI 2 "reg_or_8bit_operand" "")))] "" "{ emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]), gen_rtx (MINUS, DImode, gen_lowpart (DImode, operands[1]), gen_lowpart (DImode, operands[2])))); DONE;} ")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] "" "subl %r1,%2,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] "" "subl %r1,%2,%0" [(set_attr "type" "iaddlog")])(define_insn "subdi3" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" "subq %r1,%2,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] "" "s%2subl %r1,%3,%0" [(set_attr "type" "iaddlog")])(define_insn ""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -