📄 mips.md
字号:
;; Mips.md Machine Description for MIPS based processors;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,;; 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.;; Contributed by A. Lichnewsky, lich@inria.inria.fr;; Changes by Michael Meissner, meissner@osf.org;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and;; Brendan Eich, brendan@microunity.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.;; ??? Currently does not have define_function_unit support for the R8000.;; Must include new entries for fmadd in addition to existing entries.(define_constants [(UNSPEC_ULW 0) (UNSPEC_USW 1) (UNSPEC_ULD 2) (UNSPEC_USD 3) (UNSPEC_GET_FNADDR 4) (UNSPEC_HILO_DELAY 5) (UNSPEC_BLOCKAGE 6) (UNSPEC_LOADGP 7) (UNSPEC_SETJMP 8) (UNSPEC_LONGJMP 9) (UNSPEC_EH_RECEIVER 10) (UNSPEC_EH_RETURN 11) (UNSPEC_CONSTTABLE_QI 12) (UNSPEC_CONSTTABLE_HI 13) (UNSPEC_CONSTTABLE_SI 14) (UNSPEC_CONSTTABLE_DI 15) (UNSPEC_CONSTTABLE_SF 16) (UNSPEC_CONSTTABLE_DF 17) (UNSPEC_ALIGN_2 18) (UNSPEC_ALIGN_4 19) (UNSPEC_ALIGN_8 20)]);; ....................;;;; Attributes;;;; ....................;; Classification of each insn.;; branch conditional branch;; jump unconditional jump;; call unconditional call;; load load instruction(s);; store store instruction(s);; move data movement within same register set;; xfer transfer to/from coprocessor;; hilo transfer of hi/lo registers;; arith integer arithmetic instruction;; darith double precision integer arithmetic instructions;; imul integer multiply;; imadd integer multiply-add;; idiv integer divide;; icmp integer compare;; fadd floating point add/subtract;; fmul floating point multiply;; fmadd floating point multiply-add;; fdiv floating point divide;; fabs floating point absolute value;; fneg floating point negation;; fcmp floating point compare;; fcvt floating point convert;; fsqrt floating point square root;; frsqrt floating point reciprocal square root;; multi multiword sequence (or user asm statements);; nop no operation(define_attr "type" "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop" (const_string "unknown"));; Main data type used by the insn(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"));; Length (in # of bytes). A conditional branch is allowed only to a;; location within a signed 18-bit offset of the delay slot. If that;; provides too smal a range, we use the `j' instruction. This;; instruction takes a 28-bit value, but that value is not an offset.;; Instead, it's bitwise-ored with the high-order four bits of the;; instruction in the delay slot, which means it cannot be used to;; cross a 256MB boundary. We could fall back back on the jr,;; instruction which allows full access to the entire address space,;; but we do not do so at present.(define_attr "length" "" (cond [(eq_attr "type" "branch") (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4)))) (const_int 65536)) (const_int 4) (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC") (const_int 0)) (const_int 24) ] (const_int 12)) ] (const_int 4)));; Attribute describing the processor. This attribute must match exactly;; with the processor_type enumeration in mips.h.;; Attribute describing the processor;; (define_attr "cpu" "default,r3000,r6000,r4000";; (const;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000");; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000");; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")];; (const_string "default"))));; ??? Fix everything that tests this attribute.(define_attr "cpu" "default,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sr71000,r4kc,r5kc,r20kc" (const (symbol_ref "mips_cpu_attr")));; Does the instruction have a mandatory delay slot?;; The 3900, is (mostly) mips1, but does not have a mandatory load delay;; slot.(define_attr "dslot" "no,yes" (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp") (and (eq_attr "type" "load") (and (eq (symbol_ref "mips_isa") (const_int 1)) (and (eq (symbol_ref "mips16") (const_int 0)) (eq_attr "cpu" "!r3900"))))) (const_string "yes") (const_string "no")));; Can the instruction be put into a delay slot?(define_attr "can_delay" "no,yes" (if_then_else (and (eq_attr "dslot" "no") ; ADJUST_INSN_LENGTH divides length by 2 on mips16, ; so cope with it here. (ior (and (eq (symbol_ref "mips16") (const_int 0)) (eq_attr "length" "4")) (and (ne (symbol_ref "mips16") (const_int 0)) (eq_attr "length" "2")))) (const_string "yes") (const_string "no")));; Attribute defining whether or not we can use the branch-likely instructions(define_attr "branch_likely" "no,yes" (const (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0)) (const_string "yes") (const_string "no"))));; Describe a user's asm statement.(define_asm_attributes [(set_attr "type" "multi") (set_attr "can_delay" "no")]);; whether or not generating calls to position independent functions(define_attr "abicalls" "no,yes" (const (symbol_ref "mips_abicalls_attr")));; .........................;;;; Delay slots, can't describe load/fcmp/xfer delay slots here;;;; .........................(define_delay (and (eq_attr "type" "branch") (eq (symbol_ref "mips16") (const_int 0))) [(eq_attr "can_delay" "yes") (nil) (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])(define_delay (eq_attr "type" "jump") [(eq_attr "can_delay" "yes") (nil) (nil)])(define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no")) [(eq_attr "can_delay" "yes") (nil) (nil)]);; .........................;;;; Functional units;;;; .........................; (define_function_unit NAME MULTIPLICITY SIMULTANEITY; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]);; Make the default case (PROCESSOR_DEFAULT) handle the worst case(define_function_unit "memory" 1 0 (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000")) 3 0)(define_function_unit "memory" 1 0 (and (eq_attr "type" "load") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000")) 2 0)(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)(define_function_unit "imuldiv" 1 0 (eq_attr "type" "hilo") 1 3)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000")) 17 17);; On them mips16, we want to stronly discourage a mult from appearing;; after an mflo, since that requires explicit nop instructions. We;; do this by pretending that mflo ties up the function unit for long;; enough that the scheduler will ignore load stalls and the like when;; selecting instructions to between the two instructions.(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0))) 1 5)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900")) 12 12)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600")) 10 10)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650")) 4 4)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120"))) 1 1)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120"))) 4 4)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000"))) 5 5)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300"))) 8 8)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "imul,imadd") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000"))) 9 9)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000")) 38 38)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900")) 35 35)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600")) 42 42)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650")) 36 36)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000")) 69 69)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120"))) 35 35)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120"))) 67 67)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300"))) 37 37)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300"))) 69 69)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000"))) 36 36)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "idiv") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000"))) 68 68);; The R4300 does *NOT* have a separate Floating Point Unit, instead;; the FP hardware is part of the normal ALU circuitry. This means FP;; instructions affect the pipe-line, and no functional unit;; parallelism can occur on R4300 processors. To force GCC into coding;; for only a single functional unit, we force the R4300 FP;; instructions to be processed in the "imuldiv" unit.(define_function_unit "adder" 1 1 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")) 3 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000")) 2 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000")) 1 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300")) 4 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900")) 2 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000")) 3 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000")) 2 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000")) 1 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000"))) 7 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000"))) 4 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) 5 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650"))) 8 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))) 8 0)(define_function_unit "mult" 1 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -