📄 mips.md
字号:
;; Mips.md Machine Description for MIPS based processors;; Contributed by A. Lichnewsky, lich@inria.inria.fr;; Changes by Michael Meissner, meissner@osf.org;; Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.;; 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.;; ....................;;;; 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;; idiv integer divide;; icmp integer compare;; fadd floating point add/subtract;; fmul floating point multiply;; 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;; 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,idiv,icmp,fadd,fmul,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,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"));; # instructions (4 bytes each)(define_attr "length" "" (const_int 1));; whether or not an instruction has a mandatory delay slot(define_attr "dslot" "no,yes" (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp") (const_string "yes") (const_string "no")));; 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"))))(define_attr "cpu" "default,r3000,r6000,r4000" (const (symbol_ref "mips_cpu_attr")));; Attribute defining whether or not we can use the branch-likely instructions;; (MIPS ISA level 2)(define_attr "branch_likely" "no,yes" (const (if_then_else (ge (symbol_ref "mips_isa") (const_int 2)) (const_string "yes") (const_string "no"))));; Describe a user's asm statement.(define_asm_attributes [(set_attr "type" "multi")]);; .........................;;;; Delay slots, can't describe load/fcmp/xfer delay slots here;;;; .........................(define_delay (eq_attr "type" "branch") [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) (nil) (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])(define_delay (eq_attr "type" "call,jump") [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) (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")) 3 0)(define_function_unit "memory" 1 0 (and (eq_attr "type" "load") (eq_attr "cpu" "r3000")) 2 0)(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)(define_function_unit "addr" 1 0 (eq_attr "type" "fcmp") 2 0)(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)(define_function_unit "memory" 1 0 (eq_attr "type" "hilo") 3 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000")) 17 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000")) 12 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000")) 10 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000")) 38 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000")) 35 0)(define_function_unit "imuldiv" 1 1 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000")) 69 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000")) 4 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000")) 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")) 2 0)(define_function_unit "adder" 1 1 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000")) 1 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) 7 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) 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" "DF") (eq_attr "cpu" "!r3000,r6000"))) 8 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) 5 0)(define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) 6 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) 23 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) 12 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) 15 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000"))) 36 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) 19 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) 16 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0);; The following functional units do not use the cpu type, and use;; much less memory in genattrtab.c.;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0);; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0);; ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0);; ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0);; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0);; ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0);; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0);; ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0);; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0);; ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0);; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0);; ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0);; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0);; ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0);; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0);;;; ....................;;;; ADDITION;;;; ....................;;(define_insn "adddf3" [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT" "add.d\\t%0,%1,%2" [(set_attr "type" "fadd") (set_attr "mode" "DF") (set_attr "length" "1")])(define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=f") (plus:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT" "add.s\\t%0,%1,%2" [(set_attr "type" "fadd") (set_attr "mode" "SF") (set_attr "length" "1")])(define_expand "addsi3" [(set (match_operand:SI 0 "register_operand" "=d") (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") (match_operand:SI 2 "arith_operand" "dI")))] "" "{ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) operands[2] = force_reg (SImode, operands[2]);}")(define_insn "addsi3_internal" [(set (match_operand:SI 0 "register_operand" "=d") (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") (match_operand:SI 2 "arith_operand" "dI")))] "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768" "*{ return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ? \"subu\\t%0,%z1,%n2\" : \"addu\\t%0,%z1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr "length" "1")])(define_expand "adddi3" [(parallel [(set (match_operand:DI 0 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "arith_operand" ""))) (clobber (match_dup 3))])] "!TARGET_DEBUG_G_MODE" "{ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) operands[2] = force_reg (SImode, operands[2]); operands[3] = gen_reg_rtx (SImode);}")(define_insn "adddi3_internal_1" [(set (match_operand:DI 0 "register_operand" "=d,&d") (plus:DI (match_operand:DI 1 "register_operand" "0,d") (match_operand:DI 2 "register_operand" "d,d"))) (clobber (match_operand:SI 3 "register_operand" "=d,d"))] "!TARGET_DEBUG_G_MODE" "*{ return (REGNO (operands[0]) == REGNO (operands[1]) && REGNO (operands[0]) == REGNO (operands[2])) ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\" : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";}" [(set_attr "type" "darith") (set_attr "mode" "DI") (set_attr "length" "4")])(define_split [(set (match_operand:DI 0 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) (clobber (match_operand:SI 3 "register_operand" ""))] "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) && (REGNO (operands[0]) != REGNO (operands[1]) || REGNO (operands[0]) != REGNO (operands[2]))" [(set (subreg:SI (match_dup 0) 0) (plus:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) (set (match_dup 3) (ltu:SI (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 2) 0))) (set (subreg:SI (match_dup 0) 1) (plus:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))) (set (subreg:SI (match_dup 0) 1) (plus:SI (subreg:SI (match_dup 0) 1) (match_dup 3)))] "")(define_split [(set (match_operand:DI 0 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) (clobber (match_operand:SI 3 "register_operand" ""))] "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) && (REGNO (operands[0]) != REGNO (operands[1]) || REGNO (operands[0]) != REGNO (operands[2]))" [(set (subreg:SI (match_dup 0) 1) (plus:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))) (set (match_dup 3) (ltu:SI (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 2) 1))) (set (subreg:SI (match_dup 0) 0) (plus:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) (set (subreg:SI (match_dup 0) 0) (plus:SI (subreg:SI (match_dup 0) 0) (match_dup 3)))] "")(define_insn "adddi3_internal_2" [(set (match_operand:DI 0 "register_operand" "=d,d,d") (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d") (match_operand:DI 2 "small_int" "P,J,N"))) (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768" "@ addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -