📄 ia64.md
字号:
;; IA-64 Machine description template;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.;; Contributed by James E. Wilson <wilson@cygnus.com> and;; David Mosberger <davidm@hpl.hp.com>.;; 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.;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later;; reload. This will be fixed once scheduling support is turned on.;; ??? Optimize for post-increment addressing modes.;; ??? fselect is not supported, because there is no integer register;; equivalent.;; ??? fp abs/min/max instructions may also work for integer values.;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,;; it assumes the operand is a register and takes REGNO of it without checking.;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,;; it assumes the operand is a register and takes REGNO of it without checking.;; ??? Go through list of documented named patterns and look for more to;; implement.;; ??? Go through instruction manual and look for more instructions that;; can be emitted.;; ??? Add function unit scheduling info for Itanium (TM) processor.;; ??? Need a better way to describe alternate fp status registers.(define_constants [; Relocations (UNSPEC_LTOFF_DTPMOD 0) (UNSPEC_LTOFF_DTPREL 1) (UNSPEC_DTPREL 2) (UNSPEC_LTOFF_TPREL 3) (UNSPEC_TPREL 4) (UNSPEC_LD_BASE 9) (UNSPEC_GR_SPILL 10) (UNSPEC_GR_RESTORE 11) (UNSPEC_FR_SPILL 12) (UNSPEC_FR_RESTORE 13) (UNSPEC_FR_RECIP_APPROX 14) (UNSPEC_PRED_REL_MUTEX 15) (UNSPEC_POPCNT 16) (UNSPEC_PIC_CALL 17) (UNSPEC_MF 18) (UNSPEC_CMPXCHG_ACQ 19) (UNSPEC_FETCHADD_ACQ 20) (UNSPEC_BSP_VALUE 21) (UNSPEC_FLUSHRS 22) (UNSPEC_BUNDLE_SELECTOR 23) (UNSPEC_ADDP4 24) (UNSPEC_PROLOGUE_USE 25) (UNSPEC_RET_ADDR 26) ])(define_constants [(UNSPECV_ALLOC 0) (UNSPECV_BLOCKAGE 1) (UNSPECV_INSN_GROUP_BARRIER 2) (UNSPECV_BREAK 3) (UNSPECV_SET_BSP 4) (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls (UNSPECV_PSAC_NORMAL 6) (UNSPECV_SETJMP_RECEIVER 7) ]);; ::::::::::::::::::::;; ::;; :: Attributes;; ::;; ::::::::::::::::::::;; Instruction type. This primarily determines how instructions can be;; packed in bundles, and secondarily affects scheduling to function units.;; A alu, can go in I or M syllable of a bundle;; I integer;; M memory;; F floating-point;; B branch;; L long immediate, takes two syllables;; S stop bit;; ??? Should not have any pattern with type unknown. Perhaps add code to;; check this in md_reorg? Currently use unknown for patterns which emit;; multiple instructions, patterns which emit 0 instructions, and patterns;; which emit instruction that can go in any slot (e.g. nop).(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld, chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f, nop_i,nop_m,nop_x,lfetch" (const_string "unknown"));; chk_s has an I and an M form; use type A for convenience.(define_attr "type" "unknown,A,I,M,F,B,L,X,S" (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M") (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M") (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M") (eq_attr "itanium_class" "lfetch") (const_string "M") (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A") (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F") (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F") (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I") (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I") (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I") (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B") (eq_attr "itanium_class" "stop_bit") (const_string "S") (eq_attr "itanium_class" "nop_x") (const_string "X") (eq_attr "itanium_class" "long_i") (const_string "L")] (const_string "unknown")))(define_attr "itanium_requires_unit0" "no,yes" (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes") (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes") (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes") (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes") (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes") (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")] (const_string "no")));; Predication. True iff this instruction can be predicated.(define_attr "predicable" "no,yes" (const_string "yes"));; Empty. True iff this insn does not generate any code.(define_attr "empty" "no,yes" (const_string "no"));; ::::::::::::::::::::;; ::;; :: Function Units;; ::;; ::::::::::::::::::::;; We define 6 "dummy" functional units. All the real work to decide which;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only;; have to ensure here that there are enough copies of the dummy unit so;; that the scheduler doesn't get confused by MD_SCHED_REORDER.;; Other than the 6 dummies for normal insns, we also add a single dummy unit;; for stop bits.(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0);; There is only one insn `mov = ar.bsp' for frar_i:(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0);; There is only ony insn `mov = ar.unat' for frar_m:(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0);; Now we have only one insn (flushrs) of such class. We assume that flushrs;; is the 1st syllable of the bundle after stop bit.(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0);; Now we use only one insn `mf'. Therfore latency time is set up to 0.(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0);; There is only one insn `mov ar.pfs =' for toar_i therefore we use;; latency time equal to 0:(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0);; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0)(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0);; ::::::::::::::::::::;; ::;; :: Moves;; ::;; ::::::::::::::::::::;; Set of a single predicate register. This is only used to implement;; pr-to-pr move and complement.(define_insn "*movcci" [(set (match_operand:CCI 0 "register_operand" "=c,c,c") (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))] "" "@ cmp.ne %0, p0 = r0, r0 cmp.eq %0, p0 = r0, r0 (%1) cmp.eq.unc %0, p0 = r0, r0" [(set_attr "itanium_class" "icmp") (set_attr "predicable" "no")])(define_insn "movbi" [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r") (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))] "" "@ cmp.ne %0, %I0 = r0, r0 cmp.eq %0, %I0 = r0, r0 # # tbit.nz %0, %I0 = %1, 0 adds %0 = %1, r0 ld1%O1 %0 = %1%P1 st1%Q0 %0 = %1%P0 mov %0 = %1" [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])(define_split [(set (match_operand:BI 0 "register_operand" "") (match_operand:BI 1 "register_operand" ""))] "reload_completed && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0])) && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" [(cond_exec (ne (match_dup 1) (const_int 0)) (set (match_dup 0) (const_int 1))) (cond_exec (eq (match_dup 1) (const_int 0)) (set (match_dup 0) (const_int 0)))] "")(define_split [(set (match_operand:BI 0 "register_operand" "") (match_operand:BI 1 "register_operand" ""))] "reload_completed && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5)) (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0])); operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1); operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1])); operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] ""{ rtx op1 = ia64_expand_move (operands[0], operands[1]); if (!op1) DONE; operands[1] = op1;})(define_insn "*movqi_internal" [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f") (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %r1 addl %0 = %1, r0 ld1%O1 %0 = %1%P1 st1%Q0 %0 = %r1%P0 getf.sig %0 = %1 setf.sig %0 = %r1 mov %0 = %1" [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])(define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "general_operand" ""))] ""{ rtx op1 = ia64_expand_move (operands[0], operands[1]); if (!op1) DONE; operands[1] = op1;})(define_insn "*movhi_internal" [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f") (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %r1 addl %0 = %1, r0 ld2%O1 %0 = %1%P1 st2%Q0 %0 = %r1%P0 getf.sig %0 = %1 setf.sig %0 = %r1 mov %0 = %1" [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])(define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] ""{ rtx op1 = ia64_expand_move (operands[0], operands[1]); if (!op1) DONE; operands[1] = op1;});; This is used during early compilation to delay the decision on;; how to refer to a variable as long as possible. This is especially;; important between initial rtl generation and optimization for;; deferred functions, since we may acquire additional information;; on the variables used in the meantime.(define_insn_and_split "movsi_symbolic" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "symbolic_operand" "s")) (clobber (match_scratch:DI 2 "=r")) (use (reg:DI 1))] "" "* abort ();" "!no_new_pseudos || reload_completed" [(const_int 0)]{ rtx scratch = operands[2]; if (!reload_completed) scratch = gen_reg_rtx (Pmode); ia64_expand_load_address (operands[0], operands[1], scratch); DONE;})(define_insn "*movsi_internal" [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d") (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %r1 addl %0 = %1, r0 movl %0 = %1 ld4%O1 %0 = %1%P1 st4%Q0 %0 = %r1%P0 getf.sig %0 = %1 setf.sig %0 = %r1 mov %0 = %1 mov %0 = %1 mov %0 = %r1" ;; frar_m, toar_m ??? why not frar_i and toar_i [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -