📄 mips.md
字号:
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 && mips_cpu != PROCESSOR_R4300" "mul.s\\t%0,%1,%2" [(set_attr "type" "fmul") (set_attr "mode" "SF") (set_attr "length" "1")])(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 && mips_cpu == PROCESSOR_R4300" "*{ 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" "2")]) ;; 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 (HAVE_mulsi3_mult3) emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2])); else if (mips_cpu != PROCESSOR_R4000 || 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 || TARGET_MAD" "*{ if (which_alternative == 1) return \"mult\\t%1,%2\"; if (TARGET_MAD) return \"mul\\t%0,%1,%2\"; return \"mult\\t%0,%1,%2\";}" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "1")])(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"))] "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16" "mult\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "1")])(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"))] "mips_cpu == PROCESSOR_R4000 && !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" "3")]) ;; 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_MIPS16" "*{ static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" }; if (which_alternative == 2) return \"#\"; return madd[which_alternative];}" [(set_attr "type" "imul,imul,multi") (set_attr "mode" "SI") (set_attr "length" "1,1,2")]);; 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 && 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)))] "")(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 && 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)))] "")(define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "=l") (mult:DI (match_operand:DI 1 "se_register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT" "{ if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16) emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2])); else emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2])); DONE;}");; Don't accept both operands using se_register_operand, because if;; both operands are sign extended we would prefer to use mult in the;; mulsidi3 pattern. Commutativity should permit either operand to be;; sign extended.(define_insn "muldi3_internal" [(set (match_operand:DI 0 "register_operand" "=l") (mult:DI (match_operand:DI 1 "se_register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16" "dmult\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "DI") (set_attr "length" "1")])(define_insn "muldi3_internal2" [(set (match_operand:DI 0 "register_operand" "=d") (mult:DI (match_operand:DI 1 "se_register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=l")) (clobber (match_scratch:DI 5 "=a"))] "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)" "*{ if (GENERATE_MULT3) output_asm_insn (\"dmult\\t%0,%1,%2\", operands); else { rtx xoperands[10]; xoperands[0] = operands[0]; xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM); output_asm_insn (\"dmult\\t%1,%2\", operands); output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); } return \"\";}" [(set_attr "type" "imul") (set_attr "mode" "DI") (set (attr "length") (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0)) (const_int 1) (const_int 3)))]) ;; mult + mflo + delay;; ??? We could define a mulditi3 pattern when TARGET_64BIT.(define_expand "mulsidi3" [(set (match_operand:DI 0 "register_operand" "=x") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))] "" "{ rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx); if (TARGET_64BIT) emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2], dummy, dummy)); else emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2], dummy, dummy)); DONE;}")(define_expand "umulsidi3" [(set (match_operand:DI 0 "register_operand" "=x") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))] "" "{ rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx); if (TARGET_64BIT) emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2], dummy, dummy)); else emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2], dummy, dummy)); DONE;}")(define_insn "mulsidi3_internal" [(set (match_operand:DI 0 "register_operand" "=x") (mult:DI (match_operator:DI 3 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 4 "extend_operator" [(match_operand:SI 2 "register_operand" "d")]))) (clobber (match_scratch:SI 5 "=a"))] "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])" "*{ if (GET_CODE (operands[3]) == SIGN_EXTEND) return \"mult\\t%1,%2\"; return \"multu\\t%1,%2\";}" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "1")])(define_insn "mulsidi3_64bit" [(set (match_operand:DI 0 "register_operand" "=a") (mult:DI (match_operator:DI 3 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 4 "extend_operator" [(match_operand:SI 2 "register_operand" "d")]))) (clobber (match_scratch:DI 5 "=l")) (clobber (match_scratch:DI 6 "=h"))] "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])" "*{ if (GET_CODE (operands[3]) == SIGN_EXTEND) return \"mult\\t%1,%2\"; return \"multu\\t%1,%2\";}" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "1")]);; _highpart patterns(define_expand "smulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) (const_int 32))))] "" "{ rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx); rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);#ifndef NO_MD_PROTOTYPES rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));#else rtx (*genfn) ();#endif genfn = gen_xmulsi3_highpart_internal; emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy, dummy, dummy2)); DONE;}")(define_expand "umulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) (const_int 32))))] "" "{ rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx); rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);#ifndef NO_MD_PROTOTYPES rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));#else rtx (*genfn) ();#endif genfn = gen_xmulsi3_highpart_internal; emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy, dummy, dummy2)); DONE;}")(define_insn "xmulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI (match_operator:DI 5 "highpart_shift_operator" [(mult:DI (match_operator:DI 3 "extend_operator" [(match_operand:SI 1 "register_operand" "d")]) (match_operator:DI 4 "extend_operator" [(match_operand:SI 2 "register_operand" "d")])) (const_int 32)]))) (clobber (match_scratch:SI 6 "=l")) (clobber (match_scratch:SI 7 "=a"))] "GET_CODE (operands[3]) == GET_CODE (operands[4])" "*{ if (GET_CODE (operands[3]) == SIGN_EXTEND) return \"mult\\t%1,%2\"; else return \"multu\\t%1,%2\";}" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "1")])(define_insn "smuldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=h") (truncate:DI (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d")) (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d"))) (const_int 64)))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT" "dmult\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "DI") (set_attr "length"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -