📄 alpha.md
字号:
;;- Machine description for DEC Alpha for GNU C compiler;; Copyright (C) 1992 Free Software Foundation, Inc.;; Contributed by Richard Kenner (kenner@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, 675 Mass Ave, Cambridge, MA 02139, 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" (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.(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 cvtlq %1,%0" [(set_attr "type" "iaddlog,ld,fpop")])(define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ") (match_operand:SI 2 "add_operand" "rI,K,L")))] "" "@ addl %r1,%2,%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_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r") (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ") (match_operand:DI 2 "add_operand" "rI,K,L")))] "" "@ addq %r1,%2,%0 lda %0,%2(%r1) ldah %0,%h2(%r1)" [(set_attr "type" "iaddlog")])(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)" [(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") (plus: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%2addl %r1,%3,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (plus: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%2addl %r1,%3,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "const48_operand" "I")) (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] "" "s%2addq %r1,%3,%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:SI 0 "register_operand" "=&r") (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "register_operand" "r")) (match_operand:SI 4 "const_int_operand" "rI")))] "reload_in_progress" "s%2addl %r1,%3,%0\;addl %0,%4,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=&r") (sign_extend:DI (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "register_operand" "r")) (match_operand:SI 4 "const_int_operand" "rI"))))] "reload_in_progress" "s%2addl %r1,%3,%0\;addl %0,%4,%0" [(set_attr "type" "iaddlog")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=&r") (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "const48_operand" "I")) (match_operand:DI 3 "register_operand" "r")) (match_operand:DI 4 "const_int_operand" "rI")))] "reload_in_progress" "s%2addq %r1,%3,%0\;addq %0,%4,%0" [(set_attr "type" "iaddlog")])(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_insn "subsi3" [(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 "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (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 "" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "const48_operand" "I")) (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] "" "s%2subq %r1,%3,%0" [(set_attr "type" "iaddlog")])(define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] "" "mull %r1,%2,%0" [(set_attr "type" "imull")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] "" "mull %r1,%2,%0" [(set_attr "type" "imull")])(define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" "mulq %r1,%2,%0" [(set_attr "type" "imulq")]);; The divide and remainder operations always take their inputs from;; r24 and r25, put their output in r27, and clobber r23.(define_expand "divsi3" [(parallel [(set (reg:SI 27) (div:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" "{ rtx in0 = gen_rtx (REG, SImode, 24); rtx in1 = gen_rtx (REG, SImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "udivsi3" [(parallel [(set (reg:SI 27) (udiv:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" "{ rtx in0 = gen_rtx (REG, SImode, 24); rtx in1 = gen_rtx (REG, SImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "modsi3" [(parallel [(set (reg:SI 27) (mod:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" "{ rtx in0 = gen_rtx (REG, SImode, 24); rtx in1 = gen_rtx (REG, SImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "umodsi3" [(parallel [(set (reg:SI 27) (umod:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" "{ rtx in0 = gen_rtx (REG, SImode, 24); rtx in1 = gen_rtx (REG, SImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "divdi3" [(parallel [(set (reg:DI 27) (div:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" "{ rtx in0 = gen_rtx (REG, DImode, 24); rtx in1 = gen_rtx (REG, DImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "udivdi3" [(parallel [(set (reg:DI 27) (udiv:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" "{ rtx in0 = gen_rtx (REG, DImode, 24); rtx in1 = gen_rtx (REG, DImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")(define_expand "moddi3" [(parallel [(set (reg:DI 27) (mod:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" ""))) (clobber (reg:DI 23))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" "{ rtx in0 = gen_rtx (REG, DImode, 24); rtx in1 = gen_rtx (REG, DImode, 25); emit_move_insn (in0, operands[1]); emit_move_insn (in1, operands[2]); operands[1] = in0, operands[2] = in1;}")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -