📄 mips.md
字号:
(and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000"))) 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,r3900,r6000,r4600,r4650,r4300,r5000"))) 23 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900"))) 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" "SF") (eq_attr "cpu" "r4600,r4650"))) 32 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000"))) 21 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300"))) 36 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900"))) 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" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650"))) 61 0);;; ??? Is this number right?(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000"))) 54 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650"))) 31 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000"))) 21 0);;; ??? Is this number right?(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000"))) 112 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650"))) 60 0)(define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt,frsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000"))) 36 0);; R4300 FP instruction classes treated as part of the "imuldiv";; functional unit:(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300")) 3 3)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300")) 1 1)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300"))) 5 5)(define_function_unit "imuldiv" 1 0 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300"))) 8 8)(define_function_unit "imuldiv" 1 0 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt")) (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300"))) 29 29)(define_function_unit "imuldiv" 1 0 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt")) (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300"))) 58 58);; 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);; Include scheduling descriptions.(include "5400.md")(include "5500.md")(include "sr71k.md");;;; ....................;;;; CONDITIONAL TRAPS;;;; ....................;;(define_insn "trap" [(trap_if (const_int 1) (const_int 0))] "" "*{ if (ISA_HAS_COND_TRAP) return \"teq\\t$0,$0\"; /* The IRIX 6 O32 assembler requires the first break operand. */ else if (TARGET_MIPS16 || ! TARGET_GAS) return \"break 0\"; else return \"break\";}")(define_expand "conditional_trap" [(trap_if (match_operator 0 "cmp_op" [(match_dup 2) (match_dup 3)]) (match_operand 1 "const_int_operand" ""))] "ISA_HAS_COND_TRAP" "{ mips_gen_conditional_trap (operands); DONE;}");; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a;; 2nd arg of any CONST_INT, so this insn must appear first.;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.(define_insn "" [(trap_if (match_operator 0 "trap_cmp_op" [(match_operand:SI 1 "reg_or_0_operand" "d") (match_operand:SI 2 "nonmemory_operand" "dI")]) (const_int 0))] "ISA_HAS_COND_TRAP" "t%C0\\t%z1,%z2");;;; ....................;;;; 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 && TARGET_DOUBLE_FLOAT" "add.d\\t%0,%1,%2" [(set_attr "type" "fadd") (set_attr "mode" "DF")])(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")])(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")))] "" "{ /* The mips16 assembler handles -32768 correctly, and so does gas, but some other MIPS assemblers think that -32768 needs to be loaded into a register before it can be added in. */ if (! TARGET_MIPS16 && ! TARGET_GAS && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) operands[2] = force_reg (SImode, operands[2]); /* If a large stack adjustment was forced into a register, we may be asked to generate rtx such as: (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo))) but no such instruction is available in mips16. Handle it by using a temporary. */ if (TARGET_MIPS16 && REGNO (operands[0]) == STACK_POINTER_REGNUM && ((GET_CODE (operands[1]) == REG && REGNO (operands[1]) != STACK_POINTER_REGNUM) || GET_CODE (operands[2]) != CONST_INT)) { rtx tmp = gen_reg_rtx (SImode); emit_move_insn (tmp, operands[1]); emit_insn (gen_addsi3 (tmp, tmp, operands[2])); emit_move_insn (operands[0], tmp); DONE; }}")(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")))] "! TARGET_MIPS16 && (TARGET_GAS || GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" "addu\\t%0,%z1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI")]);; For the mips16, we need to recognize stack pointer additions;; explicitly, since we don't have a constraint for $sp. These insns;; will be generated by the save_restore_insns functions.(define_insn "" [(set (reg:SI 29) (plus:SI (reg:SI 29) (match_operand:SI 0 "small_int" "I")))] "TARGET_MIPS16" "addu\\t%$,%$,%0" [(set_attr "type" "arith") (set_attr "mode" "SI") (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "") (const_int 4) (const_int 8)))])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") (plus:SI (reg:SI 29) (match_operand:SI 1 "small_int" "I")))] "TARGET_MIPS16" "addu\\t%0,%$,%1" [(set_attr "type" "arith") (set_attr "mode" "SI") (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "") (const_int 4) (const_int 8)))])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d,d,d") (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") (match_operand:SI 2 "arith_operand" "IQ,O,d")))] "TARGET_MIPS16 && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER || M16_REG_P (REGNO (operands[1])) || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (GET_CODE (operands[2]) != REG || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER || M16_REG_P (REGNO (operands[2])) || REGNO (operands[2]) == ARG_POINTER_REGNUM || REGNO (operands[2]) == FRAME_POINTER_REGNUM || REGNO (operands[2]) == STACK_POINTER_REGNUM)" "*{ if (REGNO (operands[0]) == REGNO (operands[1])) return \"addu\\t%0,%2\"; return \"addu\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr_alternative "length" [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "") (const_int 4) (const_int 8)) (if_then_else (match_operand:VOID 2 "m16_simm4_1" "") (const_int 4) (const_int 8)) (const_int 4)])]);; On the mips16, we can sometimes split an add of a constant which is;; a 4 byte instruction into two adds which are both 2 byte;; instructions. There are two cases: one where we are adding a;; constant plus a register to another register, and one where we are;; simply adding a constant to a register.(define_split [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_dup 0) (match_operand:SI 1 "const_int_operand" "")))] "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE && GET_CODE (operands[0]) == REG && M16_REG_P (REGNO (operands[0])) && GET_CODE (operands[1]) == CONST_INT && ((INTVAL (operands[1]) > 0x7f && INTVAL (operands[1]) <= 0x7f + 0x7f) || (INTVAL (operands[1]) < - 0x80 && INTVAL (operands[1]) >= - 0x80 - 0x80))" [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] "{ HOST_WIDE_INT val = INTVAL (operands[1]); if (val >= 0) { operands[1] = GEN_INT (0x7f); operands[2] = GEN_INT (val - 0x7f); } else { operands[1] = GEN_INT (- 0x80); operands[2] = GEN_INT (val + 0x80); }}")(define_split [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "const_int_operand" "")))] "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE && GET_CODE (operands[0]) == REG && M16_REG_P (REGNO (operands[0])) && GET_CODE (operands[1]) == REG && M16_REG_P (REGNO (operands[1])) && REGNO (operands[0]) != REGNO (operands[1]) && GET_CODE (operands[2]) == CONST_INT && ((INTVAL (operands[2]) > 0x7 && INTVAL (operands[2]) <= 0x7 + 0x7f) || (INTVAL (operands[2]) < - 0x8 && INTVAL (operands[2]) >= - 0x8 - 0x80))" [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] "{ HOST_WIDE_INT val = INTVAL (operands[2]); if (val >= 0) { operands[2] = GEN_INT (0x7); operands[3] = GEN_INT (val - 0x7); } else { operands[2] = GEN_INT (- 0x8); operands[3] = GEN_INT (val + 0x8); }}")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -