📄 mips.md
字号:
{ operands[1] = GEN_INT (0xf); operands[2] = GEN_INT (val - 0xf); } else { operands[1] = GEN_INT (- 0x10); operands[2] = GEN_INT (val + 0x10); }}")(define_split [(set (match_operand:DI 0 "register_operand" "") (minus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "const_int_operand" "")))] "TARGET_MIPS16 && TARGET_64BIT && 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]) > 0x8 && INTVAL (operands[2]) <= 0x8 + 0x10) || (INTVAL (operands[2]) < - 0x7 && INTVAL (operands[2]) >= - 0x7 - 0xf))" [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))] "{ HOST_WIDE_INT val = INTVAL (operands[2]); if (val >= 0) { operands[2] = GEN_INT (0x8); operands[3] = GEN_INT (val - 0x8); } else { operands[2] = GEN_INT (- 0x7); operands[3] = GEN_INT (val + 0x7); }}")(define_insn "subsi3_internal_2" [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") (match_operand:SI 2 "arith_operand" "dI"))))] "TARGET_64BIT && !TARGET_MIPS16 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" "*{ return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ? \"addu\\t%0,%z1,%n2\" : \"subu\\t%0,%z1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "DI")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d,d") (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d") (match_operand:SI 2 "arith_operand" "I,O,d"))))] "TARGET_64BIT && TARGET_MIPS16 && (GET_CODE (operands[2]) != CONST_INT || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" "*{ if (REGNO (operands[0]) == REGNO (operands[1])) return \"subu\\t%0,%2\"; return \"subu\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI") (set_attr_alternative "length" [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "") (const_int 4) (const_int 8)) (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") (const_int 4) (const_int 8)) (const_int 4)])]);;;; ....................;;;; MULTIPLICATION;;;; ....................;;;; Early Vr4300 silicon has a CPU bug where multiplies with certain;; operands may corrupt immediately following multiplies. This is a;; simple fix to insert NOPs.(define_expand "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "{ if (!TARGET_MIPS4300) emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2])); else emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2])); DONE;}")(define_insn "muldf3_internal" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300" "mul.d\\t%0,%1,%2" [(set_attr "type" "fmul") (set_attr "mode" "DF")])(define_insn "muldf3_r4300" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300" "*{ output_asm_insn (\"mul.d\\t%0,%1,%2\", operands); if (TARGET_4300_MUL_FIX) output_asm_insn (\"nop\", operands); return \"\";}" [(set_attr "type" "fmul") (set_attr "mode" "DF") (set_attr "length" "8")]) ;; mul.d + nop(define_expand "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT" "{ if (!TARGET_MIPS4300) emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2])); else emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2])); DONE;}")(define_insn "mulsf3_internal" [(set (match_operand:SF 0 "register_operand" "=f") (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT && !TARGET_MIPS4300" "mul.s\\t%0,%1,%2" [(set_attr "type" "fmul") (set_attr "mode" "SF")])(define_insn "mulsf3_r4300" [(set (match_operand:SF 0 "register_operand" "=f") (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_MIPS4300" "*{ output_asm_insn (\"mul.s\\t%0,%1,%2\", operands); if (TARGET_4300_MUL_FIX) output_asm_insn (\"nop\", operands); return \"\";}" [(set_attr "type" "fmul") (set_attr "mode" "SF") (set_attr "length" "8")]) ;; mul.s + nop;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while;; a multiply is in progress, it may give an incorrect result. Avoid;; this by keeping the mflo with the mult on the R4000.(define_expand "mulsi3" [(set (match_operand:SI 0 "register_operand" "=l") (mult:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_scratch:SI 3 "=h")) (clobber (match_scratch:SI 4 "=a"))] "" "{ if (GENERATE_MULT3_SI || TARGET_MAD) emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2])); else if (!TARGET_MIPS4000 || TARGET_MIPS16) emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2])); else emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2])); DONE;}")(define_insn "mulsi3_mult3" [(set (match_operand:SI 0 "register_operand" "=d,l") (mult:SI (match_operand:SI 1 "register_operand" "d,d") (match_operand:SI 2 "register_operand" "d,d"))) (clobber (match_scratch:SI 3 "=h,h")) (clobber (match_scratch:SI 4 "=l,X")) (clobber (match_scratch:SI 5 "=a,a"))] "GENERATE_MULT3_SI || TARGET_MAD" "*{ if (which_alternative == 1) return \"mult\\t%1,%2\"; if (TARGET_MAD || TARGET_MIPS5400 || TARGET_MIPS5500 || ISA_MIPS32 || ISA_MIPS64) return \"mul\\t%0,%1,%2\"; return \"mult\\t%0,%1,%2\";}" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "mulsi3_internal" [(set (match_operand:SI 0 "register_operand" "=l") (mult:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_scratch:SI 3 "=h")) (clobber (match_scratch:SI 4 "=a"))] "!TARGET_MIPS4000 || TARGET_MIPS16" "mult\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "mulsi3_r4000" [(set (match_operand:SI 0 "register_operand" "=d") (mult:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (clobber (match_scratch:SI 3 "=h")) (clobber (match_scratch:SI 4 "=l")) (clobber (match_scratch:SI 5 "=a"))] "TARGET_MIPS4000 && !TARGET_MIPS16" "*{ rtx xoperands[10]; xoperands[0] = operands[0]; xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM); output_asm_insn (\"mult\\t%1,%2\", operands); output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); return \"\";}" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "12")]) ;; mult + mflo + delay;; Multiply-accumulate patterns;; For processors that can copy the output to a general register:;;;; The all-d alternative is needed because the combiner will find this;; pattern and then register alloc/reload will move registers around to;; make them fit, and we don't want to trigger unnecessary loads to LO.;;;; The last alternative should be made slightly less desirable, but adding;; "?" to the constraint is too strong, and causes values to be loaded into;; LO even when that's more costly. For now, using "*d" mostly does the;; trick.(define_insn "*mul_acc_si" [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") (match_operand:SI 2 "register_operand" "d,d,d")) (match_operand:SI 3 "register_operand" "0,l,*d"))) (clobber (match_scratch:SI 4 "=h,h,h")) (clobber (match_scratch:SI 5 "=X,3,l")) (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "(TARGET_MIPS3900 || TARGET_MIPS5400 || TARGET_MIPS5500 || ISA_HAS_MADD_MSUB) && !TARGET_MIPS16" "*{ static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" }; static const char *const macc[] = { \"macc\\t$0,%1,%2\", \"macc\\t%0,%1,%2\" }; if (which_alternative == 2) return \"#\"; if (ISA_HAS_MADD_MSUB && which_alternative != 0) return \"#\"; if (TARGET_MIPS5400) return macc[which_alternative]; if (TARGET_MIPS5500) { if (which_alternative == 0) return madd[0]; else return macc[which_alternative]; } return madd[which_alternative];}" [(set_attr "type" "imadd,imadd,multi") (set_attr "mode" "SI") (set_attr "length" "4,4,8")]);; Split the above insn if we failed to get LO allocated.(define_split [(set (match_operand:SI 0 "register_operand" "") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" "")) (match_operand:SI 3 "register_operand" ""))) (clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 "")) (clobber (match_scratch:SI 6 "")) (clobber (match_scratch:SI 7 ""))] "reload_completed && !TARGET_DEBUG_D_MODE && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[3]))" [(parallel [(set (match_dup 7) (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))]) (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))] "");; Splitter to copy result of MADD to a general register(define_split [(set (match_operand:SI 0 "register_operand" "") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" "")) (match_operand:SI 3 "register_operand" ""))) (clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 "")) (clobber (match_scratch:SI 6 "")) (clobber (match_scratch:SI 7 ""))] "reload_completed && !TARGET_DEBUG_D_MODE && GP_REG_P (true_regnum (operands[0])) && true_regnum (operands[3]) == LO_REGNUM" [(parallel [(set (match_dup 3) (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6)) (clobber (match_dup 7))]) (set (match_dup 0) (match_dup 3))] "")(define_insn "*mul_sub_si" [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") (match_operand:SI 3 "register_operand" "d,d,d")))) (clobber (match_scratch:SI 4 "=h,h,h")) (clobber (match_scratch:SI 5 "=X,3,l")) (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "ISA_HAS_MADD_MSUB" "*{ if (which_alternative != 0) return \"#\"; return \"msub\\t%2,%3\";}" [(set_attr "type" "imadd,multi,multi") (set_attr "mode" "SI") (set_attr "length" "4,8,8")]);; Split the above insn if we failed to get LO allocated.(define_split [(set (match_operand:SI 0 "register_operand" "") (minus:SI (match_operand:SI 1 "register_operand" "") (mult:SI (match_operand:SI 2 "register_operand" "") (match_operand:SI 3 "register_operand" "")))) (clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 "")) (clobber (match_scratch:SI 6 "")) (clobber (match_scratch:SI 7 ""))] "reload_completed && !TARGET_DEBUG_D_MODE && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))" [(parallel [(set (match_dup 7) (mult:SI (match_dup 2) (match_dup 3))) (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))]) (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))] "");; Splitter to copy result of MSUB to a general register(define_split [(set (match_operand:SI 0 "register_operand" "") (minus:SI (match_operand:SI 1 "register_operand" "") (mult:SI (match_operand:SI 2 "register_operand" "")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -